From f9527ce8682323d8252f7cf4783258d800f6eb87 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Fri, 25 Sep 2009 22:31:23 +0200 Subject: [PATCH] linux: - update to linux-2.6.32-next-20090925 --- ...a-implements-VGA-arbitration-on-Linux.diff | 1714 - packages/linux/70_drm-next.diff | 81284 ------------- ... => 0001-patch-v2.6.31-next-20090925.diff} | 94645 +++++++++++++++- 3 files changed, 90218 insertions(+), 87425 deletions(-) delete mode 100644 packages/linux/0001-vga-implements-VGA-arbitration-on-Linux.diff delete mode 100644 packages/linux/70_drm-next.diff rename packages/linux/patches/{0001-patch-v2.6.31-next-20090924.diff => 0001-patch-v2.6.31-next-20090925.diff} (95%) diff --git a/packages/linux/0001-vga-implements-VGA-arbitration-on-Linux.diff b/packages/linux/0001-vga-implements-VGA-arbitration-on-Linux.diff deleted file mode 100644 index c8de45711b..0000000000 --- a/packages/linux/0001-vga-implements-VGA-arbitration-on-Linux.diff +++ /dev/null @@ -1,1714 +0,0 @@ -diff -Naur linux-2.6.31-rc9/Documentation/vgaarbiter.txt linux-2.6.31-rc9.patch/Documentation/vgaarbiter.txt ---- linux-2.6.31-rc9/Documentation/vgaarbiter.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31-rc9.patch/Documentation/vgaarbiter.txt 2009-09-06 20:03:01.640044298 +0200 -@@ -0,0 +1,194 @@ -+ -+VGA Arbiter -+=========== -+ -+Graphic devices are accessed through ranges in I/O or memory space. While most -+modern devices allow relocation of such ranges, some "Legacy" VGA devices -+implemented on PCI will typically have the same "hard-decoded" addresses as -+they did on ISA. For more details see "PCI Bus Binding to IEEE Std 1275-1994 -+Standard for Boot (Initialization Configuration) Firmware Revision 2.1" -+Section 7, Legacy Devices. -+ -+The Resource Access Control (RAC) module inside the X server [0] existed for -+the legacy VGA arbitration task (besides other bus management tasks) when more -+than one legacy device co-exists on the same machine. But the problem happens -+when these devices are trying to be accessed by different userspace clients -+(e.g. two server in parallel). Their address assignments conflict. Moreover, -+ideally, being an userspace application, it is not the role of the the X -+server to control bus resources. Therefore an arbitration scheme outside of -+the X server is needed to control the sharing of these resources. This -+document introduces the operation of the VGA arbiter implemented for Linux -+kernel. -+ -+---------------------------------------------------------------------------- -+ -+I. Details and Theory of Operation -+ I.1 vgaarb -+ I.2 libpciaccess -+ I.3 xf86VGAArbiter (X server implementation) -+II. Credits -+III.References -+ -+ -+I. Details and Theory of Operation -+================================== -+ -+I.1 vgaarb -+---------- -+ -+The vgaarb is a module of the Linux Kernel. When it is initially loaded, it -+scans all PCI devices and adds the VGA ones inside the arbitration. The -+arbiter then enables/disables the decoding on different devices of the VGA -+legacy instructions. Device which do not want/need to use the arbiter may -+explicitly tell it by calling vga_set_legacy_decoding(). -+ -+The kernel exports a char device interface (/dev/vga_arbiter) to the clients, -+which has the following semantics: -+ -+ open : open user instance of the arbiter. By default, it's attached to -+ the default VGA device of the system. -+ -+ close : close user instance. Release locks made by the user -+ -+ read : return a string indicating the status of the target like: -+ -+ ",decodes=,owns=,locks= (ic,mc)" -+ -+ An IO state string is of the form {io,mem,io+mem,none}, mc and -+ ic are respectively mem and io lock counts (for debugging/ -+ diagnostic only). "decodes" indicate what the card currently -+ decodes, "owns" indicates what is currently enabled on it, and -+ "locks" indicates what is locked by this card. If the card is -+ unplugged, we get "invalid" then for card_ID and an -ENODEV -+ error is returned for any command until a new card is targeted. -+ -+ -+ write : write a command to the arbiter. List of commands: -+ -+ target : switch target to card (see below) -+ lock : acquires locks on target ("none" is an invalid io_state) -+ trylock : non-blocking acquire locks on target (returns EBUSY if -+ unsuccessful) -+ unlock : release locks on target -+ unlock all : release all locks on target held by this user (not -+ implemented yet) -+ decodes : set the legacy decoding attributes for the card -+ -+ poll : event if something changes on any card (not just the -+ target) -+ -+ card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default" -+ to go back to the system default card (TODO: not implemented yet). Currently, -+ only PCI is supported as a prefix, but the userland API may support other bus -+ types in the future, even if the current kernel implementation doesn't. -+ -+Note about locks: -+ -+The driver keeps track of which user has which locks on which card. It -+supports stacking, like the kernel one. This complexifies the implementation -+a bit, but makes the arbiter more tolerant to user space problems and able -+to properly cleanup in all cases when a process dies. -+Currently, a max of 16 cards can have locks simultaneously issued from -+user space for a given user (file descriptor instance) of the arbiter. -+ -+In the case of devices hot-{un,}plugged, there is a hook - pci_notify() - to -+notify them being added/removed in the system and automatically added/removed -+in the arbiter. -+ -+There's also a in-kernel API of the arbiter in the case of DRM, vgacon and -+others which may use the arbiter. -+ -+ -+I.2 libpciaccess -+---------------- -+ -+To use the vga arbiter char device it was implemented an API inside the -+libpciaccess library. One fieldd was added to struct pci_device (each device -+on the system): -+ -+ /* the type of resource decoded by the device */ -+ int vgaarb_rsrc; -+ -+Besides it, in pci_system were added: -+ -+ int vgaarb_fd; -+ int vga_count; -+ struct pci_device *vga_target; -+ struct pci_device *vga_default_dev; -+ -+ -+The vga_count is usually need to keep informed how many cards are being -+arbitrated, so for instance if there's only one then it can totally escape the -+scheme. -+ -+ -+These functions below acquire VGA resources for the given card and mark those -+resources as locked. If the resources requested are "normal" (and not legacy) -+resources, the arbiter will first check whether the card is doing legacy -+decoding for that type of resource. If yes, the lock is "converted" into a -+legacy resource lock. The arbiter will first look for all VGA cards that -+might conflict and disable their IOs and/or Memory access, including VGA -+forwarding on P2P bridges if necessary, so that the requested resources can -+be used. Then, the card is marked as locking these resources and the IO and/or -+Memory access is enabled on the card (including VGA forwarding on parent -+P2P bridges if any). In the case of vga_arb_lock(), the function will block -+if some conflicting card is already locking one of the required resources (or -+any resource on a different bus segment, since P2P bridges don't differentiate -+VGA memory and IO afaik). If the card already owns the resources, the function -+succeeds. vga_arb_trylock() will return (-EBUSY) instead of blocking. Nested -+calls are supported (a per-resource counter is maintained). -+ -+ -+Set the target device of this client. -+ int pci_device_vgaarb_set_target (struct pci_device *dev); -+ -+ -+For instance, in x86 if two devices on the same bus want to lock different -+resources, both will succeed (lock). If devices are in different buses and -+trying to lock different resources, only the first who tried succeeds. -+ int pci_device_vgaarb_lock (void); -+ int pci_device_vgaarb_trylock (void); -+ -+Unlock resources of device. -+ int pci_device_vgaarb_unlock (void); -+ -+Indicates to the arbiter if the card decodes legacy VGA IOs, legacy VGA -+Memory, both, or none. All cards default to both, the card driver (fbdev for -+example) should tell the arbiter if it has disabled legacy decoding, so the -+card can be left out of the arbitration process (and can be safe to take -+interrupts at any time. -+ int pci_device_vgaarb_decodes (int new_vgaarb_rsrc); -+ -+Connects to the arbiter device, allocates the struct -+ int pci_device_vgaarb_init (void); -+ -+Close the connection -+ void pci_device_vgaarb_fini (void); -+ -+ -+I.3 xf86VGAArbiter (X server implementation) -+-------------------------------------------- -+ -+(TODO) -+ -+X server basically wraps all the functions that touch VGA registers somehow. -+ -+ -+II. Credits -+=========== -+ -+Benjamin Herrenschmidt (IBM?) started this work when he discussed such design -+with the Xorg community in 2005 [1, 2]. In the end of 2007, Paulo Zanoni and -+Tiago Vignatti (both of C3SL/Federal University of ParanĂ¡) proceeded his work -+enhancing the kernel code to adapt as a kernel module and also did the -+implementation of the user space side [3]. Now (2009) Tiago Vignatti and Dave -+Airlie finally put this work in shape and queued to Jesse Barnes' PCI tree. -+ -+ -+III. References -+============== -+ -+[0] http://cgit.freedesktop.org/xorg/xserver/commit/?id=4b42448a2388d40f257774fbffdccaea87bd0347 -+[1] http://lists.freedesktop.org/archives/xorg/2005-March/006663.html -+[2] http://lists.freedesktop.org/archives/xorg/2005-March/006745.html -+[3] http://lists.freedesktop.org/archives/xorg/2007-October/029507.html -diff -Naur linux-2.6.31-rc9/drivers/gpu/Makefile linux-2.6.31-rc9.patch/drivers/gpu/Makefile ---- linux-2.6.31-rc9/drivers/gpu/Makefile 2009-09-06 01:38:12.000000000 +0200 -+++ linux-2.6.31-rc9.patch/drivers/gpu/Makefile 2009-09-06 20:02:15.047044096 +0200 -@@ -1 +1 @@ --obj-y += drm/ -+obj-y += drm/ vga/ -diff -Naur linux-2.6.31-rc9/drivers/gpu/vga/Kconfig linux-2.6.31-rc9.patch/drivers/gpu/vga/Kconfig ---- linux-2.6.31-rc9/drivers/gpu/vga/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31-rc9.patch/drivers/gpu/vga/Kconfig 2009-09-06 20:02:15.047044096 +0200 -@@ -0,0 +1,10 @@ -+config VGA_ARB -+ bool "VGA Arbitration" if EMBEDDED -+ default y -+ depends on PCI -+ help -+ Some "legacy" VGA devices implemented on PCI typically have the same -+ hard-decoded addresses as they did on ISA. When multiple PCI devices -+ are accessed at same time they need some kind of coordination. Please -+ see Documentation/vgaarbiter.txt for more details. Select this to -+ enable VGA arbiter. -diff -Naur linux-2.6.31-rc9/drivers/gpu/vga/Makefile linux-2.6.31-rc9.patch/drivers/gpu/vga/Makefile ---- linux-2.6.31-rc9/drivers/gpu/vga/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31-rc9.patch/drivers/gpu/vga/Makefile 2009-09-06 20:02:15.049044023 +0200 -@@ -0,0 +1 @@ -+obj-$(CONFIG_VGA_ARB) += vgaarb.o -diff -Naur linux-2.6.31-rc9/drivers/gpu/vga/vgaarb.c linux-2.6.31-rc9.patch/drivers/gpu/vga/vgaarb.c ---- linux-2.6.31-rc9/drivers/gpu/vga/vgaarb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31-rc9.patch/drivers/gpu/vga/vgaarb.c 2009-09-06 20:02:48.730046930 +0200 -@@ -0,0 +1,1205 @@ -+/* -+ * vgaarb.c -+ * -+ * (C) Copyright 2005 Benjamin Herrenschmidt -+ * (C) Copyright 2007 Paulo R. Zanoni -+ * (C) Copyright 2007, 2009 Tiago Vignatti -+ * -+ * Implements the VGA arbitration. For details refer to -+ * Documentation/vgaarbiter.txt -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+static void vga_arbiter_notify_clients(void); -+/* -+ * We keep a list of all vga devices in the system to speed -+ * up the various operations of the arbiter -+ */ -+struct vga_device { -+ struct list_head list; -+ struct pci_dev *pdev; -+ unsigned int decodes; /* what does it decodes */ -+ unsigned int owns; /* what does it owns */ -+ unsigned int locks; /* what does it locks */ -+ unsigned int io_lock_cnt; /* legacy IO lock count */ -+ unsigned int mem_lock_cnt; /* legacy MEM lock count */ -+ unsigned int io_norm_cnt; /* normal IO count */ -+ unsigned int mem_norm_cnt; /* normal MEM count */ -+ -+ /* allow IRQ enable/disable hook */ -+ void *cookie; -+ void (*irq_set_state)(void *cookie, bool enable); -+ unsigned int (*set_vga_decode)(void *cookie, bool decode); -+}; -+ -+static LIST_HEAD(vga_list); -+static int vga_count, vga_decode_count; -+static bool vga_arbiter_used; -+static DEFINE_SPINLOCK(vga_lock); -+static DECLARE_WAIT_QUEUE_HEAD(vga_wait_queue); -+ -+ -+static const char *vga_iostate_to_str(unsigned int iostate) -+{ -+ /* Ignore VGA_RSRC_IO and VGA_RSRC_MEM */ -+ iostate &= VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; -+ switch (iostate) { -+ case VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM: -+ return "io+mem"; -+ case VGA_RSRC_LEGACY_IO: -+ return "io"; -+ case VGA_RSRC_LEGACY_MEM: -+ return "mem"; -+ } -+ return "none"; -+} -+ -+static int vga_str_to_iostate(char *buf, int str_size, int *io_state) -+{ -+ /* we could in theory hand out locks on IO and mem -+ * separately to userspace but it can cause deadlocks */ -+ if (strncmp(buf, "none", 4) == 0) { -+ *io_state = VGA_RSRC_NONE; -+ return 1; -+ } -+ -+ /* XXX We're not chekcing the str_size! */ -+ if (strncmp(buf, "io+mem", 6) == 0) -+ goto both; -+ else if (strncmp(buf, "io", 2) == 0) -+ goto both; -+ else if (strncmp(buf, "mem", 3) == 0) -+ goto both; -+ return 0; -+both: -+ *io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; -+ return 1; -+} -+ -+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE -+/* this is only used a cookie - it should not be dereferenced */ -+static struct pci_dev *vga_default; -+#endif -+ -+static void vga_arb_device_card_gone(struct pci_dev *pdev); -+ -+/* Find somebody in our list */ -+static struct vga_device *vgadev_find(struct pci_dev *pdev) -+{ -+ struct vga_device *vgadev; -+ -+ list_for_each_entry(vgadev, &vga_list, list) -+ if (pdev == vgadev->pdev) -+ return vgadev; -+ return NULL; -+} -+ -+/* Returns the default VGA device (vgacon's babe) */ -+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE -+struct pci_dev *vga_default_device(void) -+{ -+ return vga_default; -+} -+#endif -+ -+static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) -+{ -+ if (vgadev->irq_set_state) -+ vgadev->irq_set_state(vgadev->cookie, state); -+} -+ -+ -+/* If we don't ever use VGA arb we should avoid -+ turning off anything anywhere due to old X servers getting -+ confused about the boot device not being VGA */ -+static void vga_check_first_use(void) -+{ -+ /* we should inform all GPUs in the system that -+ * VGA arb has occured and to try and disable resources -+ * if they can */ -+ if (!vga_arbiter_used) { -+ vga_arbiter_used = true; -+ vga_arbiter_notify_clients(); -+ } -+} -+ -+static struct vga_device *__vga_tryget(struct vga_device *vgadev, -+ unsigned int rsrc) -+{ -+ unsigned int wants, legacy_wants, match; -+ struct vga_device *conflict; -+ unsigned int pci_bits; -+ /* Account for "normal" resources to lock. If we decode the legacy, -+ * counterpart, we need to request it as well -+ */ -+ if ((rsrc & VGA_RSRC_NORMAL_IO) && -+ (vgadev->decodes & VGA_RSRC_LEGACY_IO)) -+ rsrc |= VGA_RSRC_LEGACY_IO; -+ if ((rsrc & VGA_RSRC_NORMAL_MEM) && -+ (vgadev->decodes & VGA_RSRC_LEGACY_MEM)) -+ rsrc |= VGA_RSRC_LEGACY_MEM; -+ -+ pr_devel("%s: %d\n", __func__, rsrc); -+ pr_devel("%s: owns: %d\n", __func__, vgadev->owns); -+ -+ /* Check what resources we need to acquire */ -+ wants = rsrc & ~vgadev->owns; -+ -+ /* We already own everything, just mark locked & bye bye */ -+ if (wants == 0) -+ goto lock_them; -+ -+ /* We don't need to request a legacy resource, we just enable -+ * appropriate decoding and go -+ */ -+ legacy_wants = wants & VGA_RSRC_LEGACY_MASK; -+ if (legacy_wants == 0) -+ goto enable_them; -+ -+ /* Ok, we don't, let's find out how we need to kick off */ -+ list_for_each_entry(conflict, &vga_list, list) { -+ unsigned int lwants = legacy_wants; -+ unsigned int change_bridge = 0; -+ -+ /* Don't conflict with myself */ -+ if (vgadev == conflict) -+ continue; -+ -+ /* Check if the architecture allows a conflict between those -+ * 2 devices or if they are on separate domains -+ */ -+ if (!vga_conflicts(vgadev->pdev, conflict->pdev)) -+ continue; -+ -+ /* We have a possible conflict. before we go further, we must -+ * check if we sit on the same bus as the conflicting device. -+ * if we don't, then we must tie both IO and MEM resources -+ * together since there is only a single bit controlling -+ * VGA forwarding on P2P bridges -+ */ -+ if (vgadev->pdev->bus != conflict->pdev->bus) { -+ change_bridge = 1; -+ lwants = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; -+ } -+ -+ /* Check if the guy has a lock on the resource. If he does, -+ * return the conflicting entry -+ */ -+ if (conflict->locks & lwants) -+ return conflict; -+ -+ /* Ok, now check if he owns the resource we want. We don't need -+ * to check "decodes" since it should be impossible to own -+ * own legacy resources you don't decode unless I have a bug -+ * in this code... -+ */ -+ WARN_ON(conflict->owns & ~conflict->decodes); -+ match = lwants & conflict->owns; -+ if (!match) -+ continue; -+ -+ /* looks like he doesn't have a lock, we can steal -+ * them from him -+ */ -+ vga_irq_set_state(conflict, false); -+ -+ pci_bits = 0; -+ if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) -+ pci_bits |= PCI_COMMAND_MEMORY; -+ if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) -+ pci_bits |= PCI_COMMAND_IO; -+ -+ pci_set_vga_state(conflict->pdev, false, pci_bits, -+ change_bridge); -+ conflict->owns &= ~lwants; -+ /* If he also owned non-legacy, that is no longer the case */ -+ if (lwants & VGA_RSRC_LEGACY_MEM) -+ conflict->owns &= ~VGA_RSRC_NORMAL_MEM; -+ if (lwants & VGA_RSRC_LEGACY_IO) -+ conflict->owns &= ~VGA_RSRC_NORMAL_IO; -+ } -+ -+enable_them: -+ /* ok dude, we got it, everybody conflicting has been disabled, let's -+ * enable us. Make sure we don't mark a bit in "owns" that we don't -+ * also have in "decodes". We can lock resources we don't decode but -+ * not own them. -+ */ -+ pci_bits = 0; -+ if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM)) -+ pci_bits |= PCI_COMMAND_MEMORY; -+ if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO)) -+ pci_bits |= PCI_COMMAND_IO; -+ pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK)); -+ -+ vga_irq_set_state(vgadev, true); -+ vgadev->owns |= (wants & vgadev->decodes); -+lock_them: -+ vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK); -+ if (rsrc & VGA_RSRC_LEGACY_IO) -+ vgadev->io_lock_cnt++; -+ if (rsrc & VGA_RSRC_LEGACY_MEM) -+ vgadev->mem_lock_cnt++; -+ if (rsrc & VGA_RSRC_NORMAL_IO) -+ vgadev->io_norm_cnt++; -+ if (rsrc & VGA_RSRC_NORMAL_MEM) -+ vgadev->mem_norm_cnt++; -+ -+ return NULL; -+} -+ -+static void __vga_put(struct vga_device *vgadev, unsigned int rsrc) -+{ -+ unsigned int old_locks = vgadev->locks; -+ -+ pr_devel("%s\n", __func__); -+ -+ /* Update our counters, and account for equivalent legacy resources -+ * if we decode them -+ */ -+ if ((rsrc & VGA_RSRC_NORMAL_IO) && vgadev->io_norm_cnt > 0) { -+ vgadev->io_norm_cnt--; -+ if (vgadev->decodes & VGA_RSRC_LEGACY_IO) -+ rsrc |= VGA_RSRC_LEGACY_IO; -+ } -+ if ((rsrc & VGA_RSRC_NORMAL_MEM) && vgadev->mem_norm_cnt > 0) { -+ vgadev->mem_norm_cnt--; -+ if (vgadev->decodes & VGA_RSRC_LEGACY_MEM) -+ rsrc |= VGA_RSRC_LEGACY_MEM; -+ } -+ if ((rsrc & VGA_RSRC_LEGACY_IO) && vgadev->io_lock_cnt > 0) -+ vgadev->io_lock_cnt--; -+ if ((rsrc & VGA_RSRC_LEGACY_MEM) && vgadev->mem_lock_cnt > 0) -+ vgadev->mem_lock_cnt--; -+ -+ /* Just clear lock bits, we do lazy operations so we don't really -+ * have to bother about anything else at this point -+ */ -+ if (vgadev->io_lock_cnt == 0) -+ vgadev->locks &= ~VGA_RSRC_LEGACY_IO; -+ if (vgadev->mem_lock_cnt == 0) -+ vgadev->locks &= ~VGA_RSRC_LEGACY_MEM; -+ -+ /* Kick the wait queue in case somebody was waiting if we actually -+ * released something -+ */ -+ if (old_locks != vgadev->locks) -+ wake_up_all(&vga_wait_queue); -+} -+ -+int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) -+{ -+ struct vga_device *vgadev, *conflict; -+ unsigned long flags; -+ wait_queue_t wait; -+ int rc = 0; -+ -+ vga_check_first_use(); -+ /* The one who calls us should check for this, but lets be sure... */ -+ if (pdev == NULL) -+ pdev = vga_default_device(); -+ if (pdev == NULL) -+ return 0; -+ -+ for (;;) { -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) { -+ spin_unlock_irqrestore(&vga_lock, flags); -+ rc = -ENODEV; -+ break; -+ } -+ conflict = __vga_tryget(vgadev, rsrc); -+ spin_unlock_irqrestore(&vga_lock, flags); -+ if (conflict == NULL) -+ break; -+ -+ -+ /* We have a conflict, we wait until somebody kicks the -+ * work queue. Currently we have one work queue that we -+ * kick each time some resources are released, but it would -+ * be fairly easy to have a per device one so that we only -+ * need to attach to the conflicting device -+ */ -+ init_waitqueue_entry(&wait, current); -+ add_wait_queue(&vga_wait_queue, &wait); -+ set_current_state(interruptible ? -+ TASK_INTERRUPTIBLE : -+ TASK_UNINTERRUPTIBLE); -+ if (signal_pending(current)) { -+ rc = -EINTR; -+ break; -+ } -+ schedule(); -+ remove_wait_queue(&vga_wait_queue, &wait); -+ set_current_state(TASK_RUNNING); -+ } -+ return rc; -+} -+EXPORT_SYMBOL(vga_get); -+ -+int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ int rc = 0; -+ -+ vga_check_first_use(); -+ -+ /* The one who calls us should check for this, but lets be sure... */ -+ if (pdev == NULL) -+ pdev = vga_default_device(); -+ if (pdev == NULL) -+ return 0; -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) { -+ rc = -ENODEV; -+ goto bail; -+ } -+ if (__vga_tryget(vgadev, rsrc)) -+ rc = -EBUSY; -+bail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+ return rc; -+} -+EXPORT_SYMBOL(vga_tryget); -+ -+void vga_put(struct pci_dev *pdev, unsigned int rsrc) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ -+ /* The one who calls us should check for this, but lets be sure... */ -+ if (pdev == NULL) -+ pdev = vga_default_device(); -+ if (pdev == NULL) -+ return; -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) -+ goto bail; -+ __vga_put(vgadev, rsrc); -+bail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+} -+EXPORT_SYMBOL(vga_put); -+ -+/* -+ * Currently, we assume that the "initial" setup of the system is -+ * not sane, that is we come up with conflicting devices and let -+ * the arbiter's client decides if devices decodes or not legacy -+ * things. -+ */ -+static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ struct pci_bus *bus; -+ struct pci_dev *bridge; -+ u16 cmd; -+ -+ /* Only deal with VGA class devices */ -+ if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) -+ return false; -+ -+ /* Allocate structure */ -+ vgadev = kmalloc(sizeof(struct vga_device), GFP_KERNEL); -+ if (vgadev == NULL) { -+ pr_err("vgaarb: failed to allocate pci device\n"); -+ /* What to do on allocation failure ? For now, let's -+ * just do nothing, I'm not sure there is anything saner -+ * to be done -+ */ -+ return false; -+ } -+ -+ memset(vgadev, 0, sizeof(*vgadev)); -+ -+ /* Take lock & check for duplicates */ -+ spin_lock_irqsave(&vga_lock, flags); -+ if (vgadev_find(pdev) != NULL) { -+ BUG_ON(1); -+ goto fail; -+ } -+ vgadev->pdev = pdev; -+ -+ /* By default, assume we decode everything */ -+ vgadev->decodes = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | -+ VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; -+ -+ /* by default mark it as decoding */ -+ vga_decode_count++; -+ /* Mark that we "own" resources based on our enables, we will -+ * clear that below if the bridge isn't forwarding -+ */ -+ pci_read_config_word(pdev, PCI_COMMAND, &cmd); -+ if (cmd & PCI_COMMAND_IO) -+ vgadev->owns |= VGA_RSRC_LEGACY_IO; -+ if (cmd & PCI_COMMAND_MEMORY) -+ vgadev->owns |= VGA_RSRC_LEGACY_MEM; -+ -+ /* Check if VGA cycles can get down to us */ -+ bus = pdev->bus; -+ while (bus) { -+ bridge = bus->self; -+ if (bridge) { -+ u16 l; -+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, -+ &l); -+ if (!(l & PCI_BRIDGE_CTL_VGA)) { -+ vgadev->owns = 0; -+ break; -+ } -+ } -+ bus = bus->parent; -+ } -+ -+ /* Deal with VGA default device. Use first enabled one -+ * by default if arch doesn't have it's own hook -+ */ -+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE -+ if (vga_default == NULL && -+ ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) -+ vga_default = pci_dev_get(pdev); -+#endif -+ -+ /* Add to the list */ -+ list_add(&vgadev->list, &vga_list); -+ vga_count++; -+ pr_info("vgaarb: device added: PCI:%s,decodes=%s,owns=%s,locks=%s\n", -+ pci_name(pdev), -+ vga_iostate_to_str(vgadev->decodes), -+ vga_iostate_to_str(vgadev->owns), -+ vga_iostate_to_str(vgadev->locks)); -+ -+ spin_unlock_irqrestore(&vga_lock, flags); -+ return true; -+fail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+ kfree(vgadev); -+ return false; -+} -+ -+static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ bool ret = true; -+ -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) { -+ ret = false; -+ goto bail; -+ } -+ -+ if (vga_default == pdev) { -+ pci_dev_put(vga_default); -+ vga_default = NULL; -+ } -+ -+ if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) -+ vga_decode_count--; -+ -+ /* Remove entry from list */ -+ list_del(&vgadev->list); -+ vga_count--; -+ /* Notify userland driver that the device is gone so it discards -+ * it's copies of the pci_dev pointer -+ */ -+ vga_arb_device_card_gone(pdev); -+ -+ /* Wake up all possible waiters */ -+ wake_up_all(&vga_wait_queue); -+bail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+ kfree(vgadev); -+ return ret; -+} -+ -+/* this is called with the lock */ -+static inline void vga_update_device_decodes(struct vga_device *vgadev, -+ int new_decodes) -+{ -+ int old_decodes; -+ struct vga_device *new_vgadev, *conflict; -+ -+ old_decodes = vgadev->decodes; -+ vgadev->decodes = new_decodes; -+ -+ pr_info("vgaarb: device changed decodes: PCI:%s,olddecodes=%s,decodes=%s:owns=%s\n", -+ pci_name(vgadev->pdev), -+ vga_iostate_to_str(old_decodes), -+ vga_iostate_to_str(vgadev->decodes), -+ vga_iostate_to_str(vgadev->owns)); -+ -+ -+ /* if we own the decodes we should move them along to -+ another card */ -+ if ((vgadev->owns & old_decodes) && (vga_count > 1)) { -+ /* set us to own nothing */ -+ vgadev->owns &= ~old_decodes; -+ list_for_each_entry(new_vgadev, &vga_list, list) { -+ if ((new_vgadev != vgadev) && -+ (new_vgadev->decodes & VGA_RSRC_LEGACY_MASK)) { -+ pr_info("vgaarb: transferring owner from PCI:%s to PCI:%s\n", pci_name(vgadev->pdev), pci_name(new_vgadev->pdev)); -+ conflict = __vga_tryget(new_vgadev, VGA_RSRC_LEGACY_MASK); -+ if (!conflict) -+ __vga_put(new_vgadev, VGA_RSRC_LEGACY_MASK); -+ break; -+ } -+ } -+ } -+ -+ /* change decodes counter */ -+ if (old_decodes != new_decodes) { -+ if (new_decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) -+ vga_decode_count++; -+ else -+ vga_decode_count--; -+ } -+} -+ -+void __vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes, bool userspace) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ -+ decodes &= VGA_RSRC_LEGACY_MASK; -+ -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) -+ goto bail; -+ -+ /* don't let userspace futz with kernel driver decodes */ -+ if (userspace && vgadev->set_vga_decode) -+ goto bail; -+ -+ /* update the device decodes + counter */ -+ vga_update_device_decodes(vgadev, decodes); -+ -+ /* XXX if somebody is going from "doesn't decode" to "decodes" state -+ * here, additional care must be taken as we may have pending owner -+ * ship of non-legacy region ... -+ */ -+bail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+} -+ -+void vga_set_legacy_decoding(struct pci_dev *pdev, unsigned int decodes) -+{ -+ __vga_set_legacy_decoding(pdev, decodes, false); -+} -+EXPORT_SYMBOL(vga_set_legacy_decoding); -+ -+/* call with NULL to unregister */ -+int vga_client_register(struct pci_dev *pdev, void *cookie, -+ void (*irq_set_state)(void *cookie, bool state), -+ unsigned int (*set_vga_decode)(void *cookie, bool decode)) -+{ -+ int ret = -1; -+ struct vga_device *vgadev; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&vga_lock, flags); -+ vgadev = vgadev_find(pdev); -+ if (!vgadev) -+ goto bail; -+ -+ vgadev->irq_set_state = irq_set_state; -+ vgadev->set_vga_decode = set_vga_decode; -+ vgadev->cookie = cookie; -+ ret = 0; -+ -+bail: -+ spin_unlock_irqrestore(&vga_lock, flags); -+ return ret; -+ -+} -+EXPORT_SYMBOL(vga_client_register); -+ -+/* -+ * Char driver implementation -+ * -+ * Semantics is: -+ * -+ * open : open user instance of the arbitrer. by default, it's -+ * attached to the default VGA device of the system. -+ * -+ * close : close user instance, release locks -+ * -+ * read : return a string indicating the status of the target. -+ * an IO state string is of the form {io,mem,io+mem,none}, -+ * mc and ic are respectively mem and io lock counts (for -+ * debugging/diagnostic only). "decodes" indicate what the -+ * card currently decodes, "owns" indicates what is currently -+ * enabled on it, and "locks" indicates what is locked by this -+ * card. If the card is unplugged, we get "invalid" then for -+ * card_ID and an -ENODEV error is returned for any command -+ * until a new card is targeted -+ * -+ * ",decodes=,owns=,locks= (ic,mc)" -+ * -+ * write : write a command to the arbiter. List of commands is: -+ * -+ * target : switch target to card (see below) -+ * lock : acquires locks on target ("none" is invalid io_state) -+ * trylock : non-blocking acquire locks on target -+ * unlock : release locks on target -+ * unlock all : release all locks on target held by this user -+ * decodes : set the legacy decoding attributes for the card -+ * -+ * poll : event if something change on any card (not just the target) -+ * -+ * card_ID is of the form "PCI:domain:bus:dev.fn". It can be set to "default" -+ * to go back to the system default card (TODO: not implemented yet). -+ * Currently, only PCI is supported as a prefix, but the userland API may -+ * support other bus types in the future, even if the current kernel -+ * implementation doesn't. -+ * -+ * Note about locks: -+ * -+ * The driver keeps track of which user has what locks on which card. It -+ * supports stacking, like the kernel one. This complexifies the implementation -+ * a bit, but makes the arbiter more tolerant to userspace problems and able -+ * to properly cleanup in all cases when a process dies. -+ * Currently, a max of 16 cards simultaneously can have locks issued from -+ * userspace for a given user (file descriptor instance) of the arbiter. -+ * -+ * If the device is hot-unplugged, there is a hook inside the module to notify -+ * they being added/removed in the system and automatically added/removed in -+ * the arbiter. -+ */ -+ -+#define MAX_USER_CARDS 16 -+#define PCI_INVALID_CARD ((struct pci_dev *)-1UL) -+ -+/* -+ * Each user has an array of these, tracking which cards have locks -+ */ -+struct vga_arb_user_card { -+ struct pci_dev *pdev; -+ unsigned int mem_cnt; -+ unsigned int io_cnt; -+}; -+ -+struct vga_arb_private { -+ struct list_head list; -+ struct pci_dev *target; -+ struct vga_arb_user_card cards[MAX_USER_CARDS]; -+ spinlock_t lock; -+}; -+ -+static LIST_HEAD(vga_user_list); -+static DEFINE_SPINLOCK(vga_user_lock); -+ -+ -+/* -+ * This function gets a string in the format: "PCI:domain:bus:dev.fn" and -+ * returns the respective values. If the string is not in this format, -+ * it returns 0. -+ */ -+static int vga_pci_str_to_vars(char *buf, int count, unsigned int *domain, -+ unsigned int *bus, unsigned int *devfn) -+{ -+ int n; -+ unsigned int slot, func; -+ -+ -+ n = sscanf(buf, "PCI:%x:%x:%x.%x", domain, bus, &slot, &func); -+ if (n != 4) -+ return 0; -+ -+ *devfn = PCI_DEVFN(slot, func); -+ -+ return 1; -+} -+ -+static ssize_t vga_arb_read(struct file *file, char __user * buf, -+ size_t count, loff_t *ppos) -+{ -+ struct vga_arb_private *priv = file->private_data; -+ struct vga_device *vgadev; -+ struct pci_dev *pdev; -+ unsigned long flags; -+ size_t len; -+ int rc; -+ char *lbuf; -+ -+ lbuf = kmalloc(1024, GFP_KERNEL); -+ if (lbuf == NULL) -+ return -ENOMEM; -+ -+ /* Shields against vga_arb_device_card_gone (pci_dev going -+ * away), and allows access to vga list -+ */ -+ spin_lock_irqsave(&vga_lock, flags); -+ -+ /* If we are targetting the default, use it */ -+ pdev = priv->target; -+ if (pdev == NULL || pdev == PCI_INVALID_CARD) { -+ spin_unlock_irqrestore(&vga_lock, flags); -+ len = sprintf(lbuf, "invalid"); -+ goto done; -+ } -+ -+ /* Find card vgadev structure */ -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) { -+ /* Wow, it's not in the list, that shouldn't happen, -+ * let's fix us up and return invalid card -+ */ -+ if (pdev == priv->target) -+ vga_arb_device_card_gone(pdev); -+ spin_unlock_irqrestore(&vga_lock, flags); -+ len = sprintf(lbuf, "invalid"); -+ goto done; -+ } -+ -+ /* Fill the buffer with infos */ -+ len = snprintf(lbuf, 1024, -+ "count:%d,PCI:%s,decodes=%s,owns=%s,locks=%s(%d:%d)\n", -+ vga_decode_count, pci_name(pdev), -+ vga_iostate_to_str(vgadev->decodes), -+ vga_iostate_to_str(vgadev->owns), -+ vga_iostate_to_str(vgadev->locks), -+ vgadev->io_lock_cnt, vgadev->mem_lock_cnt); -+ -+ spin_unlock_irqrestore(&vga_lock, flags); -+done: -+ -+ /* Copy that to user */ -+ if (len > count) -+ len = count; -+ rc = copy_to_user(buf, lbuf, len); -+ kfree(lbuf); -+ if (rc) -+ return -EFAULT; -+ return len; -+} -+ -+/* -+ * TODO: To avoid parsing inside kernel and to improve the speed we may -+ * consider use ioctl here -+ */ -+static ssize_t vga_arb_write(struct file *file, const char __user * buf, -+ size_t count, loff_t *ppos) -+{ -+ struct vga_arb_private *priv = file->private_data; -+ struct vga_arb_user_card *uc = NULL; -+ struct pci_dev *pdev; -+ -+ unsigned int io_state; -+ -+ char *kbuf, *curr_pos; -+ size_t remaining = count; -+ -+ int ret_val; -+ int i; -+ -+ -+ kbuf = kmalloc(count + 1, GFP_KERNEL); -+ if (!kbuf) -+ return -ENOMEM; -+ -+ if (copy_from_user(kbuf, buf, count)) { -+ kfree(kbuf); -+ return -EFAULT; -+ } -+ curr_pos = kbuf; -+ kbuf[count] = '\0'; /* Just to make sure... */ -+ -+ if (strncmp(curr_pos, "lock ", 5) == 0) { -+ curr_pos += 5; -+ remaining -= 5; -+ -+ pr_devel("client 0x%p called 'lock'\n", priv); -+ -+ if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ if (io_state == VGA_RSRC_NONE) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ -+ pdev = priv->target; -+ if (priv->target == NULL) { -+ ret_val = -ENODEV; -+ goto done; -+ } -+ -+ vga_get_uninterruptible(pdev, io_state); -+ -+ /* Update the client's locks lists... */ -+ for (i = 0; i < MAX_USER_CARDS; i++) { -+ if (priv->cards[i].pdev == pdev) { -+ if (io_state & VGA_RSRC_LEGACY_IO) -+ priv->cards[i].io_cnt++; -+ if (io_state & VGA_RSRC_LEGACY_MEM) -+ priv->cards[i].mem_cnt++; -+ break; -+ } -+ } -+ -+ ret_val = count; -+ goto done; -+ } else if (strncmp(curr_pos, "unlock ", 7) == 0) { -+ curr_pos += 7; -+ remaining -= 7; -+ -+ pr_devel("client 0x%p called 'unlock'\n", priv); -+ -+ if (strncmp(curr_pos, "all", 3) == 0) -+ io_state = VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM; -+ else { -+ if (!vga_str_to_iostate -+ (curr_pos, remaining, &io_state)) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ /* TODO: Add this? -+ if (io_state == VGA_RSRC_NONE) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ */ -+ } -+ -+ pdev = priv->target; -+ if (priv->target == NULL) { -+ ret_val = -ENODEV; -+ goto done; -+ } -+ for (i = 0; i < MAX_USER_CARDS; i++) { -+ if (priv->cards[i].pdev == pdev) -+ uc = &priv->cards[i]; -+ } -+ -+ if (!uc) -+ return -EINVAL; -+ -+ if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) -+ return -EINVAL; -+ -+ if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) -+ return -EINVAL; -+ -+ vga_put(pdev, io_state); -+ -+ if (io_state & VGA_RSRC_LEGACY_IO) -+ uc->io_cnt--; -+ if (io_state & VGA_RSRC_LEGACY_MEM) -+ uc->mem_cnt--; -+ -+ ret_val = count; -+ goto done; -+ } else if (strncmp(curr_pos, "trylock ", 8) == 0) { -+ curr_pos += 8; -+ remaining -= 8; -+ -+ pr_devel("client 0x%p called 'trylock'\n", priv); -+ -+ if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ /* TODO: Add this? -+ if (io_state == VGA_RSRC_NONE) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ */ -+ -+ pdev = priv->target; -+ if (priv->target == NULL) { -+ ret_val = -ENODEV; -+ goto done; -+ } -+ -+ if (vga_tryget(pdev, io_state)) { -+ /* Update the client's locks lists... */ -+ for (i = 0; i < MAX_USER_CARDS; i++) { -+ if (priv->cards[i].pdev == pdev) { -+ if (io_state & VGA_RSRC_LEGACY_IO) -+ priv->cards[i].io_cnt++; -+ if (io_state & VGA_RSRC_LEGACY_MEM) -+ priv->cards[i].mem_cnt++; -+ break; -+ } -+ } -+ ret_val = count; -+ goto done; -+ } else { -+ ret_val = -EBUSY; -+ goto done; -+ } -+ -+ } else if (strncmp(curr_pos, "target ", 7) == 0) { -+ unsigned int domain, bus, devfn; -+ struct vga_device *vgadev; -+ -+ curr_pos += 7; -+ remaining -= 7; -+ pr_devel("client 0x%p called 'target'\n", priv); -+ /* if target is default */ -+ if (!strncmp(buf, "default", 7)) -+ pdev = pci_dev_get(vga_default_device()); -+ else { -+ if (!vga_pci_str_to_vars(curr_pos, remaining, -+ &domain, &bus, &devfn)) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ -+ pdev = pci_get_bus_and_slot(bus, devfn); -+ if (!pdev) { -+ pr_info("vgaarb: invalid PCI address!\n"); -+ ret_val = -ENODEV; -+ goto done; -+ } -+ } -+ -+ vgadev = vgadev_find(pdev); -+ if (vgadev == NULL) { -+ pr_info("vgaarb: this pci device is not a vga device\n"); -+ pci_dev_put(pdev); -+ ret_val = -ENODEV; -+ goto done; -+ } -+ -+ priv->target = pdev; -+ for (i = 0; i < MAX_USER_CARDS; i++) { -+ if (priv->cards[i].pdev == pdev) -+ break; -+ if (priv->cards[i].pdev == NULL) { -+ priv->cards[i].pdev = pdev; -+ priv->cards[i].io_cnt = 0; -+ priv->cards[i].mem_cnt = 0; -+ break; -+ } -+ } -+ if (i == MAX_USER_CARDS) { -+ pr_err("vgaarb: maximum user cards number reached!\n"); -+ pci_dev_put(pdev); -+ /* XXX: which value to return? */ -+ ret_val = -ENOMEM; -+ goto done; -+ } -+ -+ ret_val = count; -+ pci_dev_put(pdev); -+ goto done; -+ -+ -+ } else if (strncmp(curr_pos, "decodes ", 8) == 0) { -+ curr_pos += 8; -+ remaining -= 8; -+ pr_devel("vgaarb: client 0x%p called 'decodes'\n", priv); -+ -+ if (!vga_str_to_iostate(curr_pos, remaining, &io_state)) { -+ ret_val = -EPROTO; -+ goto done; -+ } -+ pdev = priv->target; -+ if (priv->target == NULL) { -+ ret_val = -ENODEV; -+ goto done; -+ } -+ -+ __vga_set_legacy_decoding(pdev, io_state, true); -+ ret_val = count; -+ goto done; -+ } -+ /* If we got here, the message written is not part of the protocol! */ -+ kfree(kbuf); -+ return -EPROTO; -+ -+done: -+ kfree(kbuf); -+ return ret_val; -+} -+ -+static unsigned int vga_arb_fpoll(struct file *file, poll_table * wait) -+{ -+ struct vga_arb_private *priv = file->private_data; -+ -+ pr_devel("%s\n", __func__); -+ -+ if (priv == NULL) -+ return -ENODEV; -+ poll_wait(file, &vga_wait_queue, wait); -+ return POLLIN; -+} -+ -+static int vga_arb_open(struct inode *inode, struct file *file) -+{ -+ struct vga_arb_private *priv; -+ unsigned long flags; -+ -+ pr_devel("%s\n", __func__); -+ -+ priv = kmalloc(sizeof(struct vga_arb_private), GFP_KERNEL); -+ if (priv == NULL) -+ return -ENOMEM; -+ memset(priv, 0, sizeof(*priv)); -+ spin_lock_init(&priv->lock); -+ file->private_data = priv; -+ -+ spin_lock_irqsave(&vga_user_lock, flags); -+ list_add(&priv->list, &vga_user_list); -+ spin_unlock_irqrestore(&vga_user_lock, flags); -+ -+ /* Set the client' lists of locks */ -+ priv->target = vga_default_device(); /* Maybe this is still null! */ -+ priv->cards[0].pdev = priv->target; -+ priv->cards[0].io_cnt = 0; -+ priv->cards[0].mem_cnt = 0; -+ -+ -+ return 0; -+} -+ -+static int vga_arb_release(struct inode *inode, struct file *file) -+{ -+ struct vga_arb_private *priv = file->private_data; -+ struct vga_arb_user_card *uc; -+ unsigned long flags; -+ int i; -+ -+ pr_devel("%s\n", __func__); -+ -+ if (priv == NULL) -+ return -ENODEV; -+ -+ spin_lock_irqsave(&vga_user_lock, flags); -+ list_del(&priv->list); -+ for (i = 0; i < MAX_USER_CARDS; i++) { -+ uc = &priv->cards[i]; -+ if (uc->pdev == NULL) -+ continue; -+ pr_devel("uc->io_cnt == %d, uc->mem_cnt == %d\n", -+ uc->io_cnt, uc->mem_cnt); -+ while (uc->io_cnt--) -+ vga_put(uc->pdev, VGA_RSRC_LEGACY_IO); -+ while (uc->mem_cnt--) -+ vga_put(uc->pdev, VGA_RSRC_LEGACY_MEM); -+ } -+ spin_unlock_irqrestore(&vga_user_lock, flags); -+ -+ kfree(priv); -+ -+ return 0; -+} -+ -+static void vga_arb_device_card_gone(struct pci_dev *pdev) -+{ -+} -+ -+/* -+ * callback any registered clients to let them know we have a -+ * change in VGA cards -+ */ -+static void vga_arbiter_notify_clients(void) -+{ -+ struct vga_device *vgadev; -+ unsigned long flags; -+ uint32_t new_decodes; -+ bool new_state; -+ -+ if (!vga_arbiter_used) -+ return; -+ -+ spin_lock_irqsave(&vga_lock, flags); -+ list_for_each_entry(vgadev, &vga_list, list) { -+ if (vga_count > 1) -+ new_state = false; -+ else -+ new_state = true; -+ if (vgadev->set_vga_decode) { -+ new_decodes = vgadev->set_vga_decode(vgadev->cookie, new_state); -+ vga_update_device_decodes(vgadev, new_decodes); -+ } -+ } -+ spin_unlock_irqrestore(&vga_lock, flags); -+} -+ -+static int pci_notify(struct notifier_block *nb, unsigned long action, -+ void *data) -+{ -+ struct device *dev = data; -+ struct pci_dev *pdev = to_pci_dev(dev); -+ bool notify = false; -+ -+ pr_devel("%s\n", __func__); -+ -+ /* For now we're only intereted in devices added and removed. I didn't -+ * test this thing here, so someone needs to double check for the -+ * cases of hotplugable vga cards. */ -+ if (action == BUS_NOTIFY_ADD_DEVICE) -+ notify = vga_arbiter_add_pci_device(pdev); -+ else if (action == BUS_NOTIFY_DEL_DEVICE) -+ notify = vga_arbiter_del_pci_device(pdev); -+ -+ if (notify) -+ vga_arbiter_notify_clients(); -+ return 0; -+} -+ -+static struct notifier_block pci_notifier = { -+ .notifier_call = pci_notify, -+}; -+ -+static const struct file_operations vga_arb_device_fops = { -+ .read = vga_arb_read, -+ .write = vga_arb_write, -+ .poll = vga_arb_fpoll, -+ .open = vga_arb_open, -+ .release = vga_arb_release, -+}; -+ -+static struct miscdevice vga_arb_device = { -+ MISC_DYNAMIC_MINOR, "vga_arbiter", &vga_arb_device_fops -+}; -+ -+static int __init vga_arb_device_init(void) -+{ -+ int rc; -+ struct pci_dev *pdev; -+ -+ rc = misc_register(&vga_arb_device); -+ if (rc < 0) -+ pr_err("vgaarb: error %d registering device\n", rc); -+ -+ bus_register_notifier(&pci_bus_type, &pci_notifier); -+ -+ /* We add all pci devices satisfying vga class in the arbiter by -+ * default */ -+ pdev = NULL; -+ while ((pdev = -+ pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, -+ PCI_ANY_ID, pdev)) != NULL) -+ vga_arbiter_add_pci_device(pdev); -+ -+ pr_info("vgaarb: loaded\n"); -+ return rc; -+} -+subsys_initcall(vga_arb_device_init); -diff -Naur linux-2.6.31-rc9/drivers/pci/pci.c linux-2.6.31-rc9.patch/drivers/pci/pci.c ---- linux-2.6.31-rc9/drivers/pci/pci.c 2009-09-06 01:38:12.000000000 +0200 -+++ linux-2.6.31-rc9.patch/drivers/pci/pci.c 2009-09-06 20:02:15.059043870 +0200 -@@ -2504,6 +2504,50 @@ - return 0; - } - -+/** -+ * pci_set_vga_state - set VGA decode state on device and parents if requested -+ * @dev the PCI device -+ * @decode - true = enable decoding, false = disable decoding -+ * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY -+ * @change_bridge - traverse ancestors and change bridges -+ */ -+int pci_set_vga_state(struct pci_dev *dev, bool decode, -+ unsigned int command_bits, bool change_bridge) -+{ -+ struct pci_bus *bus; -+ struct pci_dev *bridge; -+ u16 cmd; -+ -+ WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)); -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ if (decode == true) -+ cmd |= command_bits; -+ else -+ cmd &= ~command_bits; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ if (change_bridge == false) -+ return 0; -+ -+ bus = dev->bus; -+ while (bus) { -+ bridge = bus->self; -+ if (bridge) { -+ pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, -+ &cmd); -+ if (decode == true) -+ cmd |= PCI_BRIDGE_CTL_VGA; -+ else -+ cmd &= ~PCI_BRIDGE_CTL_VGA; -+ pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, -+ cmd); -+ } -+ bus = bus->parent; -+ } -+ return 0; -+} -+ - #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE - static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; - spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; -diff -Naur linux-2.6.31-rc9/drivers/video/Kconfig linux-2.6.31-rc9.patch/drivers/video/Kconfig ---- linux-2.6.31-rc9/drivers/video/Kconfig 2009-09-06 01:38:12.000000000 +0200 -+++ linux-2.6.31-rc9.patch/drivers/video/Kconfig 2009-09-06 20:02:15.085168853 +0200 -@@ -7,6 +7,8 @@ - - source "drivers/char/agp/Kconfig" - -+source "drivers/gpu/vga/Kconfig" -+ - source "drivers/gpu/drm/Kconfig" - - config VGASTATE -diff -Naur linux-2.6.31-rc9/include/linux/pci.h linux-2.6.31-rc9.patch/include/linux/pci.h ---- linux-2.6.31-rc9/include/linux/pci.h 2009-09-06 01:38:12.000000000 +0200 -+++ linux-2.6.31-rc9.patch/include/linux/pci.h 2009-09-06 20:02:15.153041858 +0200 -@@ -805,6 +805,8 @@ - int pci_cfg_space_size(struct pci_dev *dev); - unsigned char pci_bus_max_busnr(struct pci_bus *bus); - -+int pci_set_vga_state(struct pci_dev *pdev, bool decode, -+ unsigned int command_bits, bool change_bridge); - /* kmem_cache style wrapper around pci_alloc_consistent() */ - - #include -diff -Naur linux-2.6.31-rc9/include/linux/vgaarb.h linux-2.6.31-rc9.patch/include/linux/vgaarb.h ---- linux-2.6.31-rc9/include/linux/vgaarb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.31-rc9.patch/include/linux/vgaarb.h 2009-09-06 20:02:48.731044484 +0200 -@@ -0,0 +1,200 @@ -+/* -+ * vgaarb.c -+ * -+ * (C) Copyright 2005 Benjamin Herrenschmidt -+ * (C) Copyright 2007 Paulo R. Zanoni -+ * (C) Copyright 2007, 2009 Tiago Vignatti -+ */ -+ -+#ifndef LINUX_VGA_H -+ -+#include -+ -+/* Legacy VGA regions */ -+#define VGA_RSRC_NONE 0x00 -+#define VGA_RSRC_LEGACY_IO 0x01 -+#define VGA_RSRC_LEGACY_MEM 0x02 -+#define VGA_RSRC_LEGACY_MASK (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM) -+/* Non-legacy access */ -+#define VGA_RSRC_NORMAL_IO 0x04 -+#define VGA_RSRC_NORMAL_MEM 0x08 -+ -+/* Passing that instead of a pci_dev to use the system "default" -+ * device, that is the one used by vgacon. Archs will probably -+ * have to provide their own vga_default_device(); -+ */ -+#define VGA_DEFAULT_DEVICE (NULL) -+ -+/* For use by clients */ -+ -+/** -+ * vga_set_legacy_decoding -+ * -+ * @pdev: pci device of the VGA card -+ * @decodes: bit mask of what legacy regions the card decodes -+ * -+ * Indicates to the arbiter if the card decodes legacy VGA IOs, -+ * legacy VGA Memory, both, or none. All cards default to both, -+ * the card driver (fbdev for example) should tell the arbiter -+ * if it has disabled legacy decoding, so the card can be left -+ * out of the arbitration process (and can be safe to take -+ * interrupts at any time. -+ */ -+extern void vga_set_legacy_decoding(struct pci_dev *pdev, -+ unsigned int decodes); -+ -+/** -+ * vga_get - acquire & locks VGA resources -+ * -+ * @pdev: pci device of the VGA card or NULL for the system default -+ * @rsrc: bit mask of resources to acquire and lock -+ * @interruptible: blocking should be interruptible by signals ? -+ * -+ * This function acquires VGA resources for the given -+ * card and mark those resources locked. If the resource requested -+ * are "normal" (and not legacy) resources, the arbiter will first check -+ * wether the card is doing legacy decoding for that type of resource. If -+ * yes, the lock is "converted" into a legacy resource lock. -+ * The arbiter will first look for all VGA cards that might conflict -+ * and disable their IOs and/or Memory access, inlcuding VGA forwarding -+ * on P2P bridges if necessary, so that the requested resources can -+ * be used. Then, the card is marked as locking these resources and -+ * the IO and/or Memory accesse are enabled on the card (including -+ * VGA forwarding on parent P2P bridges if any). -+ * This function will block if some conflicting card is already locking -+ * one of the required resources (or any resource on a different bus -+ * segment, since P2P bridges don't differenciate VGA memory and IO -+ * afaik). You can indicate wether this blocking should be interruptible -+ * by a signal (for userland interface) or not. -+ * Must not be called at interrupt time or in atomic context. -+ * If the card already owns the resources, the function succeeds. -+ * Nested calls are supported (a per-resource counter is maintained) -+ */ -+ -+extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, -+ int interruptible); -+ -+/** -+ * vga_get_interruptible -+ * -+ * Shortcut to vga_get -+ */ -+ -+static inline int vga_get_interruptible(struct pci_dev *pdev, -+ unsigned int rsrc) -+{ -+ return vga_get(pdev, rsrc, 1); -+} -+ -+/** -+ * vga_get_uninterruptible -+ * -+ * Shortcut to vga_get -+ */ -+ -+static inline int vga_get_uninterruptible(struct pci_dev *pdev, -+ unsigned int rsrc) -+{ -+ return vga_get(pdev, rsrc, 0); -+} -+ -+/** -+ * vga_tryget - try to acquire & lock legacy VGA resources -+ * -+ * @pdev: pci devivce of VGA card or NULL for system default -+ * @rsrc: bit mask of resources to acquire and lock -+ * -+ * This function performs the same operation as vga_get(), but -+ * will return an error (-EBUSY) instead of blocking if the resources -+ * are already locked by another card. It can be called in any context -+ */ -+ -+extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc); -+ -+/** -+ * vga_put - release lock on legacy VGA resources -+ * -+ * @pdev: pci device of VGA card or NULL for system default -+ * @rsrc: but mask of resource to release -+ * -+ * This function releases resources previously locked by vga_get() -+ * or vga_tryget(). The resources aren't disabled right away, so -+ * that a subsequence vga_get() on the same card will succeed -+ * immediately. Resources have a counter, so locks are only -+ * released if the counter reaches 0. -+ */ -+ -+extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); -+ -+ -+/** -+ * vga_default_device -+ * -+ * This can be defined by the platform. The default implementation -+ * is rather dumb and will probably only work properly on single -+ * vga card setups and/or x86 platforms. -+ * -+ * If your VGA default device is not PCI, you'll have to return -+ * NULL here. In this case, I assume it will not conflict with -+ * any PCI card. If this is not true, I'll have to define two archs -+ * hooks for enabling/disabling the VGA default device if that is -+ * possible. This may be a problem with real _ISA_ VGA cards, in -+ * addition to a PCI one. I don't know at this point how to deal -+ * with that card. Can theirs IOs be disabled at all ? If not, then -+ * I suppose it's a matter of having the proper arch hook telling -+ * us about it, so we basically never allow anybody to succeed a -+ * vga_get()... -+ */ -+ -+#ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE -+extern struct pci_dev *vga_default_device(void); -+#endif -+ -+/** -+ * vga_conflicts -+ * -+ * Architectures should define this if they have several -+ * independant PCI domains that can afford concurrent VGA -+ * decoding -+ */ -+ -+#ifndef __ARCH_HAS_VGA_CONFLICT -+static inline int vga_conflicts(struct pci_dev *p1, struct pci_dev *p2) -+{ -+ return 1; -+} -+#endif -+ -+/** -+ * vga_client_register -+ * -+ * @pdev: pci device of the VGA client -+ * @cookie: client cookie to be used in callbacks -+ * @irq_set_state: irq state change callback -+ * @set_vga_decode: vga decode change callback -+ * -+ * return value: 0 on success, -1 on failure -+ * Register a client with the VGA arbitration logic -+ * -+ * Clients have two callback mechanisms they can use. -+ * irq enable/disable callback - -+ * If a client can't disable its GPUs VGA resources, then we -+ * need to be able to ask it to turn off its irqs when we -+ * turn off its mem and io decoding. -+ * set_vga_decode -+ * If a client can disable its GPU VGA resource, it will -+ * get a callback from this to set the encode/decode state -+ * -+ * Rationale: we cannot disable VGA decode resources unconditionally -+ * some single GPU laptops seem to require ACPI or BIOS access to the -+ * VGA registers to control things like backlights etc. -+ * Hopefully newer multi-GPU laptops do something saner, and desktops -+ * won't have any special ACPI for this. -+ * They driver will get a callback when VGA arbitration is first used -+ * by userspace since we some older X servers have issues. -+ */ -+int vga_client_register(struct pci_dev *pdev, void *cookie, -+ void (*irq_set_state)(void *cookie, bool state), -+ unsigned int (*set_vga_decode)(void *cookie, bool state)); -+ -+#endif /* LINUX_VGA_H */ diff --git a/packages/linux/70_drm-next.diff b/packages/linux/70_drm-next.diff deleted file mode 100644 index a3b2f70213..0000000000 --- a/packages/linux/70_drm-next.diff +++ /dev/null @@ -1,81284 +0,0 @@ -diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig -index 39b393d..e4d971c 100644 ---- a/drivers/gpu/drm/Kconfig -+++ b/drivers/gpu/drm/Kconfig -@@ -18,6 +18,14 @@ menuconfig DRM - details. You should also select and configure AGP - (/dev/agpgart) support. - -+config DRM_KMS_HELPER -+ tristate -+ depends on DRM -+ select FB -+ select FRAMEBUFFER_CONSOLE if !EMBEDDED -+ help -+ FB and CRTC helpers for KMS drivers. -+ - config DRM_TTM - tristate - depends on DRM -@@ -36,6 +44,7 @@ config DRM_TDFX - config DRM_R128 - tristate "ATI Rage 128" - depends on DRM && PCI -+ select FW_LOADER - help - Choose this option if you have an ATI Rage 128 graphics card. If M - is selected, the module will be called r128. AGP support for -@@ -47,8 +56,9 @@ config DRM_RADEON - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT -- select FB -- select FRAMEBUFFER_CONSOLE if !EMBEDDED -+ select FW_LOADER -+ select DRM_KMS_HELPER -+ select DRM_TTM - help - Choose this option if you have an ATI Radeon graphics card. There - are both PCI and AGP versions. You don't need to choose this to -@@ -82,11 +92,10 @@ config DRM_I830 - config DRM_I915 - tristate "i915 driver" - depends on AGP_INTEL -+ select DRM_KMS_HELPER - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT -- select FB -- select FRAMEBUFFER_CONSOLE if !EMBEDDED - # i915 depends on ACPI_VIDEO when ACPI is enabled - # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI -@@ -116,6 +125,7 @@ endchoice - config DRM_MGA - tristate "Matrox g200/g400" - depends on DRM -+ select FW_LOADER - help - Choose this option if you have a Matrox G200, G400 or G450 graphics - card. If M is selected, the module will be called mga. AGP -diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile -index fe23f29..3c8827a 100644 ---- a/drivers/gpu/drm/Makefile -+++ b/drivers/gpu/drm/Makefile -@@ -10,11 +10,15 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ - drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ -- drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \ -- drm_info.o drm_debugfs.o -+ drm_crtc.o drm_modes.o drm_edid.o \ -+ drm_info.o drm_debugfs.o drm_encoder_slave.o - - drm-$(CONFIG_COMPAT) += drm_ioc32.o - -+drm_kms_helper-y := drm_fb_helper.o drm_crtc_helper.o -+ -+obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o -+ - obj-$(CONFIG_DRM) += drm.o - obj-$(CONFIG_DRM_TTM) += ttm/ - obj-$(CONFIG_DRM_TDFX) += tdfx/ -diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c -index 0e994a0..0e3bd5b 100644 ---- a/drivers/gpu/drm/drm_cache.c -+++ b/drivers/gpu/drm/drm_cache.c -@@ -45,6 +45,23 @@ drm_clflush_page(struct page *page) - clflush(page_virtual + i); - kunmap_atomic(page_virtual, KM_USER0); - } -+ -+static void drm_cache_flush_clflush(struct page *pages[], -+ unsigned long num_pages) -+{ -+ unsigned long i; -+ -+ mb(); -+ for (i = 0; i < num_pages; i++) -+ drm_clflush_page(*pages++); -+ mb(); -+} -+ -+static void -+drm_clflush_ipi_handler(void *null) -+{ -+ wbinvd(); -+} - #endif - - void -@@ -53,17 +70,30 @@ drm_clflush_pages(struct page *pages[], unsigned long num_pages) - - #if defined(CONFIG_X86) - if (cpu_has_clflush) { -- unsigned long i; -- -- mb(); -- for (i = 0; i < num_pages; ++i) -- drm_clflush_page(*pages++); -- mb(); -- -+ drm_cache_flush_clflush(pages, num_pages); - return; - } - -- wbinvd(); -+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0) -+ printk(KERN_ERR "Timed out waiting for cache flush.\n"); -+ -+#elif defined(__powerpc__) -+ unsigned long i; -+ for (i = 0; i < num_pages; i++) { -+ struct page *page = pages[i]; -+ void *page_virtual; -+ -+ if (unlikely(page == NULL)) -+ continue; -+ -+ page_virtual = kmap_atomic(page, KM_USER0); -+ flush_dcache_range((unsigned long)page_virtual, -+ (unsigned long)page_virtual + PAGE_SIZE); -+ kunmap_atomic(page_virtual, KM_USER0); -+ } -+#else -+ printk(KERN_ERR "Architecture has no drm_cache.c support\n"); -+ WARN_ON_ONCE(1); - #endif - } - EXPORT_SYMBOL(drm_clflush_pages); -diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c -index 2f631c7..ba728ad 100644 ---- a/drivers/gpu/drm/drm_crtc.c -+++ b/drivers/gpu/drm/drm_crtc.c -@@ -68,10 +68,10 @@ DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list) - */ - static struct drm_prop_enum_list drm_scaling_mode_enum_list[] = - { -- { DRM_MODE_SCALE_NON_GPU, "Non-GPU" }, -- { DRM_MODE_SCALE_FULLSCREEN, "Fullscreen" }, -- { DRM_MODE_SCALE_NO_SCALE, "No scale" }, -- { DRM_MODE_SCALE_ASPECT, "Aspect" }, -+ { DRM_MODE_SCALE_NONE, "None" }, -+ { DRM_MODE_SCALE_FULLSCREEN, "Full" }, -+ { DRM_MODE_SCALE_CENTER, "Center" }, -+ { DRM_MODE_SCALE_ASPECT, "Full aspect" }, - }; - - static struct drm_prop_enum_list drm_dithering_mode_enum_list[] = -@@ -108,6 +108,7 @@ static struct drm_prop_enum_list drm_tv_select_enum_list[] = - { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ -+ { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ - }; - - DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list) -@@ -118,6 +119,7 @@ static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = - { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */ - { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */ -+ { DRM_MODE_SUBCONNECTOR_SCART, "SCART" }, /* TV-out */ - }; - - DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name, -@@ -146,6 +148,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = - { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, - { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, - { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, -+ { DRM_MODE_CONNECTOR_TV, "TV", 0 }, - }; - - static struct drm_prop_enum_list drm_encoder_enum_list[] = -@@ -165,6 +168,7 @@ char *drm_get_encoder_name(struct drm_encoder *encoder) - encoder->base.id); - return buf; - } -+EXPORT_SYMBOL(drm_get_encoder_name); - - char *drm_get_connector_name(struct drm_connector *connector) - { -@@ -699,6 +703,42 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, - drm_property_add_enum(dev->mode_config.tv_mode_property, i, - i, modes[i]); - -+ dev->mode_config.tv_brightness_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "brightness", 2); -+ dev->mode_config.tv_brightness_property->values[0] = 0; -+ dev->mode_config.tv_brightness_property->values[1] = 100; -+ -+ dev->mode_config.tv_contrast_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "contrast", 2); -+ dev->mode_config.tv_contrast_property->values[0] = 0; -+ dev->mode_config.tv_contrast_property->values[1] = 100; -+ -+ dev->mode_config.tv_flicker_reduction_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "flicker reduction", 2); -+ dev->mode_config.tv_flicker_reduction_property->values[0] = 0; -+ dev->mode_config.tv_flicker_reduction_property->values[1] = 100; -+ -+ dev->mode_config.tv_overscan_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "overscan", 2); -+ dev->mode_config.tv_overscan_property->values[0] = 0; -+ dev->mode_config.tv_overscan_property->values[1] = 100; -+ -+ dev->mode_config.tv_saturation_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "saturation", 2); -+ dev->mode_config.tv_saturation_property->values[0] = 0; -+ dev->mode_config.tv_saturation_property->values[1] = 100; -+ -+ dev->mode_config.tv_hue_property = -+ drm_property_create(dev, DRM_MODE_PROP_RANGE, -+ "hue", 2); -+ dev->mode_config.tv_hue_property->values[0] = 0; -+ dev->mode_config.tv_hue_property->values[1] = 100; -+ - return 0; - } - EXPORT_SYMBOL(drm_mode_create_tv_properties); -@@ -1044,7 +1084,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, - if (file_priv->master->minor->type == DRM_MINOR_CONTROL) { - list_for_each_entry(crtc, &dev->mode_config.crtc_list, - head) { -- DRM_DEBUG("CRTC ID is %d\n", crtc->base.id); -+ DRM_DEBUG_KMS("CRTC ID is %d\n", crtc->base.id); - if (put_user(crtc->base.id, crtc_id + copied)) { - ret = -EFAULT; - goto out; -@@ -1072,7 +1112,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, - list_for_each_entry(encoder, - &dev->mode_config.encoder_list, - head) { -- DRM_DEBUG("ENCODER ID is %d\n", -+ DRM_DEBUG_KMS("ENCODER ID is %d\n", - encoder->base.id); - if (put_user(encoder->base.id, encoder_id + - copied)) { -@@ -1103,7 +1143,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, - list_for_each_entry(connector, - &dev->mode_config.connector_list, - head) { -- DRM_DEBUG("CONNECTOR ID is %d\n", -+ DRM_DEBUG_KMS("CONNECTOR ID is %d\n", - connector->base.id); - if (put_user(connector->base.id, - connector_id + copied)) { -@@ -1127,7 +1167,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, - } - card_res->count_connectors = connector_count; - -- DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs, -+ DRM_DEBUG_KMS("Counted %d %d %d\n", card_res->count_crtcs, - card_res->count_connectors, card_res->count_encoders); - - out: -@@ -1230,7 +1270,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, - - memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); - -- DRM_DEBUG("connector id %d:\n", out_resp->connector_id); -+ DRM_DEBUG_KMS("connector id %d:\n", out_resp->connector_id); - - mutex_lock(&dev->mode_config.mutex); - -@@ -1406,7 +1446,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - obj = drm_mode_object_find(dev, crtc_req->crtc_id, - DRM_MODE_OBJECT_CRTC); - if (!obj) { -- DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req->crtc_id); -+ DRM_DEBUG_KMS("Unknown CRTC ID %d\n", crtc_req->crtc_id); - ret = -EINVAL; - goto out; - } -@@ -1419,7 +1459,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - list_for_each_entry(crtcfb, - &dev->mode_config.crtc_list, head) { - if (crtcfb == crtc) { -- DRM_DEBUG("Using current fb for setmode\n"); -+ DRM_DEBUG_KMS("Using current fb for " -+ "setmode\n"); - fb = crtc->fb; - } - } -@@ -1427,7 +1468,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - obj = drm_mode_object_find(dev, crtc_req->fb_id, - DRM_MODE_OBJECT_FB); - if (!obj) { -- DRM_DEBUG("Unknown FB ID%d\n", crtc_req->fb_id); -+ DRM_DEBUG_KMS("Unknown FB ID%d\n", -+ crtc_req->fb_id); - ret = -EINVAL; - goto out; - } -@@ -1440,13 +1482,13 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - } - - if (crtc_req->count_connectors == 0 && mode) { -- DRM_DEBUG("Count connectors is 0 but mode set\n"); -+ DRM_DEBUG_KMS("Count connectors is 0 but mode set\n"); - ret = -EINVAL; - goto out; - } - - if (crtc_req->count_connectors > 0 && (!mode || !fb)) { -- DRM_DEBUG("Count connectors is %d but no mode or fb set\n", -+ DRM_DEBUG_KMS("Count connectors is %d but no mode or fb set\n", - crtc_req->count_connectors); - ret = -EINVAL; - goto out; -@@ -1479,7 +1521,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, - obj = drm_mode_object_find(dev, out_id, - DRM_MODE_OBJECT_CONNECTOR); - if (!obj) { -- DRM_DEBUG("Connector id %d unknown\n", out_id); -+ DRM_DEBUG_KMS("Connector id %d unknown\n", -+ out_id); - ret = -EINVAL; - goto out; - } -@@ -1512,7 +1555,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, - struct drm_crtc *crtc; - int ret = 0; - -- DRM_DEBUG("\n"); -+ DRM_DEBUG_KMS("\n"); - - if (!req->flags) { - DRM_ERROR("no operation set\n"); -@@ -1522,7 +1565,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, - mutex_lock(&dev->mode_config.mutex); - obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!obj) { -- DRM_DEBUG("Unknown CRTC ID %d\n", req->crtc_id); -+ DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id); - ret = -EINVAL; - goto out; - } -diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c -index 6aaa2cb..ff447f1 100644 ---- a/drivers/gpu/drm/drm_crtc_helper.c -+++ b/drivers/gpu/drm/drm_crtc_helper.c -@@ -33,15 +33,6 @@ - #include "drm_crtc.h" - #include "drm_crtc_helper.h" - --/* -- * Detailed mode info for 800x600@60Hz -- */ --static struct drm_display_mode std_modes[] = { -- { DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840, -- 968, 1056, 0, 600, 601, 605, 628, 0, -- DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, --}; -- - static void drm_mode_validate_flag(struct drm_connector *connector, - int flags) - { -@@ -94,7 +85,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - int count = 0; - int mode_flags = 0; - -- DRM_DEBUG("%s\n", drm_get_connector_name(connector)); -+ DRM_DEBUG_KMS("%s\n", drm_get_connector_name(connector)); - /* set all modes to the unverified state */ - list_for_each_entry_safe(mode, t, &connector->modes, head) - mode->status = MODE_UNVERIFIED; -@@ -102,15 +93,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - connector->status = connector->funcs->detect(connector); - - if (connector->status == connector_status_disconnected) { -- DRM_DEBUG("%s is disconnected\n", -+ DRM_DEBUG_KMS("%s is disconnected\n", - drm_get_connector_name(connector)); -- /* TODO set EDID to NULL */ -- return 0; -+ goto prune; - } - - count = (*connector_funcs->get_modes)(connector); -- if (!count) -- return 0; -+ if (!count) { -+ count = drm_add_modes_noedid(connector, 800, 600); -+ if (!count) -+ return 0; -+ } - - drm_mode_connector_list_update(connector); - -@@ -130,7 +123,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - mode); - } - -- -+prune: - drm_mode_prune_invalid(dev, &connector->modes, true); - - if (list_empty(&connector->modes)) -@@ -138,7 +131,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - - drm_mode_sort(&connector->modes); - -- DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector)); -+ DRM_DEBUG_KMS("Probed modes for %s\n", -+ drm_get_connector_name(connector)); - list_for_each_entry_safe(mode, t, &connector->modes, head) { - mode->vrefresh = drm_mode_vrefresh(mode); - -@@ -165,39 +159,6 @@ int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, - } - EXPORT_SYMBOL(drm_helper_probe_connector_modes); - --static void drm_helper_add_std_modes(struct drm_device *dev, -- struct drm_connector *connector) --{ -- struct drm_display_mode *mode, *t; -- int i; -- -- for (i = 0; i < ARRAY_SIZE(std_modes); i++) { -- struct drm_display_mode *stdmode; -- -- /* -- * When no valid EDID modes are available we end up -- * here and bailed in the past, now we add some standard -- * modes and move on. -- */ -- stdmode = drm_mode_duplicate(dev, &std_modes[i]); -- drm_mode_probed_add(connector, stdmode); -- drm_mode_list_concat(&connector->probed_modes, -- &connector->modes); -- -- DRM_DEBUG("Adding mode %s to %s\n", stdmode->name, -- drm_get_connector_name(connector)); -- } -- drm_mode_sort(&connector->modes); -- -- DRM_DEBUG("Added std modes on %s\n", drm_get_connector_name(connector)); -- list_for_each_entry_safe(mode, t, &connector->modes, head) { -- mode->vrefresh = drm_mode_vrefresh(mode); -- -- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); -- drm_mode_debug_printmodeline(mode); -- } --} -- - /** - * drm_helper_encoder_in_use - check if a given encoder is in use - * @encoder: encoder to check -@@ -258,13 +219,27 @@ EXPORT_SYMBOL(drm_helper_crtc_in_use); - void drm_helper_disable_unused_functions(struct drm_device *dev) - { - struct drm_encoder *encoder; -+ struct drm_connector *connector; - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_crtc *crtc; - -+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -+ if (!connector->encoder) -+ continue; -+ if (connector->status == connector_status_disconnected) -+ connector->encoder = NULL; -+ } -+ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - encoder_funcs = encoder->helper_private; -- if (!drm_helper_encoder_in_use(encoder)) -- (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); -+ if (!drm_helper_encoder_in_use(encoder)) { -+ if (encoder_funcs->disable) -+ (*encoder_funcs->disable)(encoder); -+ else -+ (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); -+ /* disconnector encoder from any connector */ -+ encoder->crtc = NULL; -+ } - } - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -@@ -312,7 +287,7 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled) - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - enabled[i] = drm_connector_enabled(connector, true); -- DRM_DEBUG("connector %d enabled? %s\n", connector->base.id, -+ DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id, - enabled[i] ? "yes" : "no"); - any_enabled |= enabled[i]; - i++; -@@ -342,7 +317,7 @@ static bool drm_target_preferred(struct drm_device *dev, - continue; - } - -- DRM_DEBUG("looking for preferred mode on connector %d\n", -+ DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", - connector->base.id); - - modes[i] = drm_has_preferred_mode(connector, width, height); -@@ -351,7 +326,7 @@ static bool drm_target_preferred(struct drm_device *dev, - list_for_each_entry(modes[i], &connector->modes, head) - break; - } -- DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name : -+ DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : - "none"); - i++; - } -@@ -409,7 +384,7 @@ static int drm_pick_crtcs(struct drm_device *dev, - c = 0; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - -- if ((connector->encoder->possible_crtcs & (1 << c)) == 0) { -+ if ((encoder->possible_crtcs & (1 << c)) == 0) { - c++; - continue; - } -@@ -452,7 +427,7 @@ static void drm_setup_crtcs(struct drm_device *dev) - int width, height; - int i, ret; - -- DRM_DEBUG("\n"); -+ DRM_DEBUG_KMS("\n"); - - width = dev->mode_config.max_width; - height = dev->mode_config.max_height; -@@ -475,7 +450,7 @@ static void drm_setup_crtcs(struct drm_device *dev) - if (!ret) - DRM_ERROR("Unable to find initial modes\n"); - -- DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height); -+ DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height); - - drm_pick_crtcs(dev, crtcs, modes, 0, width, height); - -@@ -490,12 +465,14 @@ static void drm_setup_crtcs(struct drm_device *dev) - } - - if (mode && crtc) { -- DRM_DEBUG("desired mode %s set on crtc %d\n", -+ DRM_DEBUG_KMS("desired mode %s set on crtc %d\n", - mode->name, crtc->base.id); - crtc->desired_mode = mode; - connector->encoder->crtc = crtc; -- } else -+ } else { - connector->encoder->crtc = NULL; -+ connector->encoder = NULL; -+ } - i++; - } - -@@ -702,18 +679,17 @@ EXPORT_SYMBOL(drm_crtc_helper_set_mode); - int drm_crtc_helper_set_config(struct drm_mode_set *set) - { - struct drm_device *dev; -- struct drm_crtc **save_crtcs, *new_crtc; -- struct drm_encoder **save_encoders, *new_encoder; -+ struct drm_crtc *save_crtcs, *new_crtc, *crtc; -+ struct drm_encoder *save_encoders, *new_encoder, *encoder; - struct drm_framebuffer *old_fb = NULL; -- bool save_enabled; - bool mode_changed = false; /* if true do a full mode set */ - bool fb_changed = false; /* if true and !mode_changed just do a flip */ -- struct drm_connector *connector; -+ struct drm_connector *save_connectors, *connector; - int count = 0, ro, fail = 0; - struct drm_crtc_helper_funcs *crtc_funcs; - int ret = 0; - -- DRM_DEBUG("\n"); -+ DRM_DEBUG_KMS("\n"); - - if (!set) - return -EINVAL; -@@ -726,37 +702,60 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - - crtc_funcs = set->crtc->helper_private; - -- DRM_DEBUG("crtc: %p %d fb: %p connectors: %p num_connectors: %d (x, y) (%i, %i)\n", -+ DRM_DEBUG_KMS("crtc: %p %d fb: %p connectors: %p num_connectors:" -+ " %d (x, y) (%i, %i)\n", - set->crtc, set->crtc->base.id, set->fb, set->connectors, - (int)set->num_connectors, set->x, set->y); - - dev = set->crtc->dev; - -- /* save previous config */ -- save_enabled = set->crtc->enabled; -- -- /* -- * We do mode_config.num_connectors here since we'll look at the -- * CRTC and encoder associated with each connector later. -- */ -- save_crtcs = kzalloc(dev->mode_config.num_connector * -- sizeof(struct drm_crtc *), GFP_KERNEL); -+ /* Allocate space for the backup of all (non-pointer) crtc, encoder and -+ * connector data. */ -+ save_crtcs = kzalloc(dev->mode_config.num_crtc * -+ sizeof(struct drm_crtc), GFP_KERNEL); - if (!save_crtcs) - return -ENOMEM; - -- save_encoders = kzalloc(dev->mode_config.num_connector * -- sizeof(struct drm_encoders *), GFP_KERNEL); -+ save_encoders = kzalloc(dev->mode_config.num_encoder * -+ sizeof(struct drm_encoder), GFP_KERNEL); - if (!save_encoders) { - kfree(save_crtcs); - return -ENOMEM; - } - -+ save_connectors = kzalloc(dev->mode_config.num_connector * -+ sizeof(struct drm_connector), GFP_KERNEL); -+ if (!save_connectors) { -+ kfree(save_crtcs); -+ kfree(save_encoders); -+ return -ENOMEM; -+ } -+ -+ /* Copy data. Note that driver private data is not affected. -+ * Should anything bad happen only the expected state is -+ * restored, not the drivers personal bookkeeping. -+ */ -+ count = 0; -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ save_crtcs[count++] = *crtc; -+ } -+ -+ count = 0; -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ save_encoders[count++] = *encoder; -+ } -+ -+ count = 0; -+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -+ save_connectors[count++] = *connector; -+ } -+ - /* We should be able to check here if the fb has the same properties - * and then just flip_or_move it */ - if (set->crtc->fb != set->fb) { - /* If we have no fb then treat it as a full mode set */ - if (set->crtc->fb == NULL) { -- DRM_DEBUG("crtc has no fb, full mode set\n"); -+ DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); - mode_changed = true; - } else if (set->fb == NULL) { - mode_changed = true; -@@ -772,7 +771,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - fb_changed = true; - - if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { -- DRM_DEBUG("modes are different, full mode set\n"); -+ DRM_DEBUG_KMS("modes are different, full mode set\n"); - drm_mode_debug_printmodeline(&set->crtc->mode); - drm_mode_debug_printmodeline(set->mode); - mode_changed = true; -@@ -783,7 +782,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct drm_connector_helper_funcs *connector_funcs = - connector->helper_private; -- save_encoders[count++] = connector->encoder; - new_encoder = connector->encoder; - for (ro = 0; ro < set->num_connectors; ro++) { - if (set->connectors[ro] == connector) { -@@ -798,15 +796,20 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - } - - if (new_encoder != connector->encoder) { -- DRM_DEBUG("encoder changed, full mode switch\n"); -+ DRM_DEBUG_KMS("encoder changed, full mode switch\n"); - mode_changed = true; -+ /* If the encoder is reused for another connector, then -+ * the appropriate crtc will be set later. -+ */ -+ if (connector->encoder) -+ connector->encoder->crtc = NULL; - connector->encoder = new_encoder; - } - } - - if (fail) { - ret = -EINVAL; -- goto fail_no_encoder; -+ goto fail; - } - - count = 0; -@@ -814,8 +817,6 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - if (!connector->encoder) - continue; - -- save_crtcs[count++] = connector->encoder->crtc; -- - if (connector->encoder->crtc == set->crtc) - new_crtc = NULL; - else -@@ -830,14 +831,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - if (new_crtc && - !drm_encoder_crtc_ok(connector->encoder, new_crtc)) { - ret = -EINVAL; -- goto fail_set_mode; -+ goto fail; - } - if (new_crtc != connector->encoder->crtc) { -- DRM_DEBUG("crtc changed, full mode switch\n"); -+ DRM_DEBUG_KMS("crtc changed, full mode switch\n"); - mode_changed = true; - connector->encoder->crtc = new_crtc; - } -- DRM_DEBUG("setting connector %d crtc to %p\n", -+ DRM_DEBUG_KMS("setting connector %d crtc to %p\n", - connector->base.id, new_crtc); - } - -@@ -850,7 +851,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - set->crtc->fb = set->fb; - set->crtc->enabled = (set->mode != NULL); - if (set->mode != NULL) { -- DRM_DEBUG("attempting to set mode from userspace\n"); -+ DRM_DEBUG_KMS("attempting to set mode from" -+ " userspace\n"); - drm_mode_debug_printmodeline(set->mode); - if (!drm_crtc_helper_set_mode(set->crtc, set->mode, - set->x, set->y, -@@ -858,7 +860,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - DRM_ERROR("failed to set mode on crtc %p\n", - set->crtc); - ret = -EINVAL; -- goto fail_set_mode; -+ goto fail; - } - /* TODO are these needed? */ - set->crtc->desired_x = set->x; -@@ -873,37 +875,41 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) - ret = crtc_funcs->mode_set_base(set->crtc, - set->x, set->y, old_fb); - if (ret != 0) -- goto fail_set_mode; -+ goto fail; - } - -+ kfree(save_connectors); - kfree(save_encoders); - kfree(save_crtcs); - return 0; - --fail_set_mode: -- set->crtc->enabled = save_enabled; -- set->crtc->fb = old_fb; -+fail: -+ /* Restore all previous data. */ - count = 0; -- list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -- if (!connector->encoder) -- continue; -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ *crtc = save_crtcs[count++]; -+ } - -- connector->encoder->crtc = save_crtcs[count++]; -+ count = 0; -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ *encoder = save_encoders[count++]; - } --fail_no_encoder: -- kfree(save_crtcs); -+ - count = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -- connector->encoder = save_encoders[count++]; -+ *connector = save_connectors[count++]; - } -+ -+ kfree(save_connectors); - kfree(save_encoders); -+ kfree(save_crtcs); - return ret; - } - EXPORT_SYMBOL(drm_crtc_helper_set_config); - - bool drm_helper_plugged_event(struct drm_device *dev) - { -- DRM_DEBUG("\n"); -+ DRM_DEBUG_KMS("\n"); - - drm_helper_probe_connector_modes(dev, dev->mode_config.max_width, - dev->mode_config.max_height); -@@ -932,7 +938,6 @@ bool drm_helper_plugged_event(struct drm_device *dev) - */ - bool drm_helper_initial_config(struct drm_device *dev) - { -- struct drm_connector *connector; - int count = 0; - - count = drm_helper_probe_connector_modes(dev, -@@ -940,16 +945,9 @@ bool drm_helper_initial_config(struct drm_device *dev) - dev->mode_config.max_height); - - /* -- * None of the available connectors had any modes, so add some -- * and try to light them up anyway -+ * we shouldn't end up with no modes here. - */ -- if (!count) { -- DRM_ERROR("connectors have no modes, using standard modes\n"); -- list_for_each_entry(connector, -- &dev->mode_config.connector_list, -- head) -- drm_helper_add_std_modes(dev, connector); -- } -+ WARN(!count, "Connected connector with 0 modes\n"); - - drm_setup_crtcs(dev); - -diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c -index b39d7bf..a75ca63 100644 ---- a/drivers/gpu/drm/drm_drv.c -+++ b/drivers/gpu/drm/drm_drv.c -@@ -63,12 +63,12 @@ static struct drm_ioctl_desc drm_ioctls[] = { - DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), - DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), -- DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY), -+ DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), - - DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -- DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), -+ DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER), - - DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), -diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c -index 7f2728b..90d76ba 100644 ---- a/drivers/gpu/drm/drm_edid.c -+++ b/drivers/gpu/drm/drm_edid.c -@@ -60,6 +60,12 @@ - #define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5) - /* use +hsync +vsync for detailed mode */ - #define EDID_QUIRK_DETAILED_SYNC_PP (1 << 6) -+/* define the number of Extension EDID block */ -+#define MAX_EDID_EXT_NUM 4 -+ -+#define LEVEL_DMT 0 -+#define LEVEL_GTF 1 -+#define LEVEL_CVT 2 - - static struct edid_quirk { - char *vendor; -@@ -237,28 +243,291 @@ static void edid_fixup_preferred(struct drm_connector *connector, - preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; - } - -+/* -+ * Add the Autogenerated from the DMT spec. -+ * This table is copied from xfree86/modes/xf86EdidModes.c. -+ * But the mode with Reduced blank feature is deleted. -+ */ -+static struct drm_display_mode drm_dmt_modes[] = { -+ /* 640x350@85Hz */ -+ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, -+ 736, 832, 0, 350, 382, 385, 445, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 640x400@85Hz */ -+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 31500, 640, 672, -+ 736, 832, 0, 400, 401, 404, 445, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 720x400@85Hz */ -+ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 756, -+ 828, 936, 0, 400, 401, 404, 446, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 640x480@60Hz */ -+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, -+ 752, 800, 0, 480, 489, 492, 525, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 640x480@72Hz */ -+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664, -+ 704, 832, 0, 480, 489, 492, 520, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 640x480@75Hz */ -+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 656, -+ 720, 840, 0, 480, 481, 484, 500, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 640x480@85Hz */ -+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 36000, 640, 696, -+ 752, 832, 0, 480, 481, 484, 509, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 800x600@56Hz */ -+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 36000, 800, 824, -+ 896, 1024, 0, 600, 601, 603, 625, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 800x600@60Hz */ -+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, -+ 968, 1056, 0, 600, 601, 605, 628, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 800x600@72Hz */ -+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 50000, 800, 856, -+ 976, 1040, 0, 600, 637, 643, 666, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 800x600@75Hz */ -+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 49500, 800, 816, -+ 896, 1056, 0, 600, 601, 604, 625, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 800x600@85Hz */ -+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832, -+ 896, 1048, 0, 600, 601, 604, 631, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 848x480@60Hz */ -+ { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864, -+ 976, 1088, 0, 480, 486, 494, 517, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1024x768@43Hz, interlace */ -+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032, -+ 1208, 1264, 0, 768, 768, 772, 817, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | -+ DRM_MODE_FLAG_INTERLACE) }, -+ /* 1024x768@60Hz */ -+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, -+ 1184, 1344, 0, 768, 771, 777, 806, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 1024x768@70Hz */ -+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048, -+ 1184, 1328, 0, 768, 771, 777, 806, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 1024x768@75Hz */ -+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040, -+ 1136, 1312, 0, 768, 769, 772, 800, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1024x768@85Hz */ -+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, -+ 1072, 1376, 0, 768, 769, 772, 808, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1152x864@75Hz */ -+ { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, -+ 1344, 1600, 0, 864, 865, 868, 900, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x768@60Hz */ -+ { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, -+ 1472, 1664, 0, 768, 771, 778, 798, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x768@75Hz */ -+ { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 102250, 1280, 1360, -+ 1488, 1696, 0, 768, 771, 778, 805, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 1280x768@85Hz */ -+ { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360, -+ 1496, 1712, 0, 768, 771, 778, 809, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x800@60Hz */ -+ { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, -+ 1480, 1680, 0, 800, 803, 809, 831, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, -+ /* 1280x800@75Hz */ -+ { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 106500, 1280, 1360, -+ 1488, 1696, 0, 800, 803, 809, 838, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x800@85Hz */ -+ { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360, -+ 1496, 1712, 0, 800, 803, 809, 843, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x960@60Hz */ -+ { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, -+ 1488, 1800, 0, 960, 961, 964, 1000, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x960@85Hz */ -+ { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344, -+ 1504, 1728, 0, 960, 961, 964, 1011, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x1024@60Hz */ -+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, -+ 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x1024@75Hz */ -+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296, -+ 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1280x1024@85Hz */ -+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344, -+ 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1360x768@60Hz */ -+ { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, -+ 1536, 1792, 0, 768, 771, 777, 795, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x1050@60Hz */ -+ { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, -+ 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x1050@75Hz */ -+ { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504, -+ 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x1050@85Hz */ -+ { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504, -+ 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x900@60Hz */ -+ { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, -+ 1672, 1904, 0, 900, 903, 909, 934, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x900@75Hz */ -+ { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 136750, 1440, 1536, -+ 1688, 1936, 0, 900, 903, 909, 942, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1440x900@85Hz */ -+ { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544, -+ 1696, 1952, 0, 900, 903, 909, 948, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1600x1200@60Hz */ -+ { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, -+ 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1600x1200@65Hz */ -+ { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 175500, 1600, 1664, -+ 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1600x1200@70Hz */ -+ { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 189000, 1600, 1664, -+ 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1600x1200@75Hz */ -+ { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 2025000, 1600, 1664, -+ 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1600x1200@85Hz */ -+ { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664, -+ 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, -+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1680x1050@60Hz */ -+ { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, -+ 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1680x1050@75Hz */ -+ { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 187000, 1680, 1800, -+ 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1680x1050@85Hz */ -+ { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808, -+ 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1792x1344@60Hz */ -+ { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, -+ 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1729x1344@75Hz */ -+ { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888, -+ 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1853x1392@60Hz */ -+ { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, -+ 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1856x1392@75Hz */ -+ { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984, -+ 2208, 2560, 0, 1392, 1395, 1399, 1500, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1920x1200@60Hz */ -+ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, -+ 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1920x1200@75Hz */ -+ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 245250, 1920, 2056, -+ 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1920x1200@85Hz */ -+ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064, -+ 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1920x1440@60Hz */ -+ { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, -+ 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 1920x1440@75Hz */ -+ { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064, -+ 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 2560x1600@60Hz */ -+ { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, -+ 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 2560x1600@75HZ */ -+ { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 443250, 2560, 2768, -+ 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+ /* 2560x1600@85HZ */ -+ { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768, -+ 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, -+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, -+}; -+ -+static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, -+ int hsize, int vsize, int fresh) -+{ -+ int i, count; -+ struct drm_display_mode *ptr, *mode; -+ -+ count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); -+ mode = NULL; -+ for (i = 0; i < count; i++) { -+ ptr = &drm_dmt_modes[i]; -+ if (hsize == ptr->hdisplay && -+ vsize == ptr->vdisplay && -+ fresh == drm_mode_vrefresh(ptr)) { -+ /* get the expected default mode */ -+ mode = drm_mode_duplicate(dev, ptr); -+ break; -+ } -+ } -+ return mode; -+} - /** - * drm_mode_std - convert standard mode info (width, height, refresh) into mode - * @t: standard timing params -+ * @timing_level: standard timing level - * - * Take the standard timing params (in this case width, aspect, and refresh) -- * and convert them into a real mode using CVT. -+ * and convert them into a real mode using CVT/GTF/DMT. - * - * Punts for now, but should eventually use the FB layer's CVT based mode - * generation code. - */ - struct drm_display_mode *drm_mode_std(struct drm_device *dev, -- struct std_timing *t) -+ struct std_timing *t, -+ int timing_level) - { - struct drm_display_mode *mode; -- int hsize = t->hsize * 8 + 248, vsize; -+ int hsize, vsize; -+ int vrefresh_rate; - unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) - >> EDID_TIMING_ASPECT_SHIFT; -- -- mode = drm_mode_create(dev); -- if (!mode) -- return NULL; -- -+ unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) -+ >> EDID_TIMING_VFREQ_SHIFT; -+ -+ /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ -+ hsize = t->hsize * 8 + 248; -+ /* vrefresh_rate = vfreq + 60 */ -+ vrefresh_rate = vfreq + 60; -+ /* the vdisplay is calculated based on the aspect ratio */ - if (aspect_ratio == 0) - vsize = (hsize * 10) / 16; - else if (aspect_ratio == 1) -@@ -267,9 +536,30 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, - vsize = (hsize * 4) / 5; - else - vsize = (hsize * 9) / 16; -- -- drm_mode_set_name(mode); -- -+ /* HDTV hack */ -+ if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { -+ mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); -+ mode->hdisplay = 1366; -+ mode->vsync_start = mode->vsync_start - 1; -+ mode->vsync_end = mode->vsync_end - 1; -+ return mode; -+ } -+ mode = NULL; -+ /* check whether it can be found in default mode table */ -+ mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); -+ if (mode) -+ return mode; -+ -+ switch (timing_level) { -+ case LEVEL_DMT: -+ break; -+ case LEVEL_GTF: -+ mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); -+ break; -+ case LEVEL_CVT: -+ mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); -+ break; -+ } - return mode; - } - -@@ -451,6 +741,19 @@ static int add_established_modes(struct drm_connector *connector, struct edid *e - - return modes; - } -+/** -+ * stanard_timing_level - get std. timing level(CVT/GTF/DMT) -+ * @edid: EDID block to scan -+ */ -+static int standard_timing_level(struct edid *edid) -+{ -+ if (edid->revision >= 2) { -+ if (edid->revision >= 4 && (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)) -+ return LEVEL_CVT; -+ return LEVEL_GTF; -+ } -+ return LEVEL_DMT; -+} - - /** - * add_standard_modes - get std. modes from EDID and add them -@@ -463,6 +766,9 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid - { - struct drm_device *dev = connector->dev; - int i, modes = 0; -+ int timing_level; -+ -+ timing_level = standard_timing_level(edid); - - for (i = 0; i < EDID_STD_TIMINGS; i++) { - struct std_timing *t = &edid->standard_timings[i]; -@@ -472,7 +778,8 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid - if (t->hsize == 1 && t->vfreq_aspect == 1) - continue; - -- newmode = drm_mode_std(dev, &edid->standard_timings[i]); -+ newmode = drm_mode_std(dev, &edid->standard_timings[i], -+ timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; -@@ -496,6 +803,9 @@ static int add_detailed_info(struct drm_connector *connector, - { - struct drm_device *dev = connector->dev; - int i, j, modes = 0; -+ int timing_level; -+ -+ timing_level = standard_timing_level(edid); - - for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { - struct detailed_timing *timing = &edid->detailed_timings[i]; -@@ -525,7 +835,8 @@ static int add_detailed_info(struct drm_connector *connector, - struct drm_display_mode *newmode; - - std = &data->data.timings[j]; -- newmode = drm_mode_std(dev, std); -+ newmode = drm_mode_std(dev, std, -+ timing_level); - if (newmode) { - drm_mode_probed_add(connector, newmode); - modes++; -@@ -551,6 +862,122 @@ static int add_detailed_info(struct drm_connector *connector, - - return modes; - } -+/** -+ * add_detailed_mode_eedid - get detailed mode info from addtional timing -+ * EDID block -+ * @connector: attached connector -+ * @edid: EDID block to scan(It is only to get addtional timing EDID block) -+ * @quirks: quirks to apply -+ * -+ * Some of the detailed timing sections may contain mode information. Grab -+ * it and add it to the list. -+ */ -+static int add_detailed_info_eedid(struct drm_connector *connector, -+ struct edid *edid, u32 quirks) -+{ -+ struct drm_device *dev = connector->dev; -+ int i, j, modes = 0; -+ char *edid_ext = NULL; -+ struct detailed_timing *timing; -+ struct detailed_non_pixel *data; -+ struct drm_display_mode *newmode; -+ int edid_ext_num; -+ int start_offset, end_offset; -+ int timing_level; -+ -+ if (edid->version == 1 && edid->revision < 3) { -+ /* If the EDID version is less than 1.3, there is no -+ * extension EDID. -+ */ -+ return 0; -+ } -+ if (!edid->extensions) { -+ /* if there is no extension EDID, it is unnecessary to -+ * parse the E-EDID to get detailed info -+ */ -+ return 0; -+ } -+ -+ /* Chose real EDID extension number */ -+ edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ? -+ MAX_EDID_EXT_NUM : edid->extensions; -+ -+ /* Find CEA extension */ -+ for (i = 0; i < edid_ext_num; i++) { -+ edid_ext = (char *)edid + EDID_LENGTH * (i + 1); -+ /* This block is CEA extension */ -+ if (edid_ext[0] == 0x02) -+ break; -+ } -+ -+ if (i == edid_ext_num) { -+ /* if there is no additional timing EDID block, return */ -+ return 0; -+ } -+ -+ /* Get the start offset of detailed timing block */ -+ start_offset = edid_ext[2]; -+ if (start_offset == 0) { -+ /* If the start_offset is zero, it means that neither detailed -+ * info nor data block exist. In such case it is also -+ * unnecessary to parse the detailed timing info. -+ */ -+ return 0; -+ } -+ -+ timing_level = standard_timing_level(edid); -+ end_offset = EDID_LENGTH; -+ end_offset -= sizeof(struct detailed_timing); -+ for (i = start_offset; i < end_offset; -+ i += sizeof(struct detailed_timing)) { -+ timing = (struct detailed_timing *)(edid_ext + i); -+ data = &timing->data.other_data; -+ /* Detailed mode timing */ -+ if (timing->pixel_clock) { -+ newmode = drm_mode_detailed(dev, edid, timing, quirks); -+ if (!newmode) -+ continue; -+ -+ drm_mode_probed_add(connector, newmode); -+ -+ modes++; -+ continue; -+ } -+ -+ /* Other timing or info */ -+ switch (data->type) { -+ case EDID_DETAIL_MONITOR_SERIAL: -+ break; -+ case EDID_DETAIL_MONITOR_STRING: -+ break; -+ case EDID_DETAIL_MONITOR_RANGE: -+ /* Get monitor range data */ -+ break; -+ case EDID_DETAIL_MONITOR_NAME: -+ break; -+ case EDID_DETAIL_MONITOR_CPDATA: -+ break; -+ case EDID_DETAIL_STD_MODES: -+ /* Five modes per detailed section */ -+ for (j = 0; j < 5; i++) { -+ struct std_timing *std; -+ struct drm_display_mode *newmode; -+ -+ std = &data->data.timings[j]; -+ newmode = drm_mode_std(dev, std, timing_level); -+ if (newmode) { -+ drm_mode_probed_add(connector, newmode); -+ modes++; -+ } -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ -+ return modes; -+} - - #define DDC_ADDR 0x50 - /** -@@ -584,7 +1011,6 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, - if (i2c_transfer(adapter, msgs, 2) == 2) - return 0; - -- dev_info(&adapter->dev, "unable to read EDID block.\n"); - return -1; - } - EXPORT_SYMBOL(drm_do_probe_ddc_edid); -@@ -597,8 +1023,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector, - - ret = drm_do_probe_ddc_edid(adapter, buf, len); - if (ret != 0) { -- dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", -- drm_get_connector_name(connector)); - goto end; - } - if (!edid_is_valid((struct edid *)buf)) { -@@ -610,7 +1034,6 @@ end: - return ret; - } - --#define MAX_EDID_EXT_NUM 4 - /** - * drm_get_edid - get EDID data, if available - * @connector: connector we're probing -@@ -763,6 +1186,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) - num_modes += add_established_modes(connector, edid); - num_modes += add_standard_modes(connector, edid); - num_modes += add_detailed_info(connector, edid, quirks); -+ num_modes += add_detailed_info_eedid(connector, edid, quirks); - - if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) - edid_fixup_preferred(connector, quirks); -@@ -788,3 +1212,49 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) - return num_modes; - } - EXPORT_SYMBOL(drm_add_edid_modes); -+ -+/** -+ * drm_add_modes_noedid - add modes for the connectors without EDID -+ * @connector: connector we're probing -+ * @hdisplay: the horizontal display limit -+ * @vdisplay: the vertical display limit -+ * -+ * Add the specified modes to the connector's mode list. Only when the -+ * hdisplay/vdisplay is not beyond the given limit, it will be added. -+ * -+ * Return number of modes added or 0 if we couldn't find any. -+ */ -+int drm_add_modes_noedid(struct drm_connector *connector, -+ int hdisplay, int vdisplay) -+{ -+ int i, count, num_modes = 0; -+ struct drm_display_mode *mode, *ptr; -+ struct drm_device *dev = connector->dev; -+ -+ count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); -+ if (hdisplay < 0) -+ hdisplay = 0; -+ if (vdisplay < 0) -+ vdisplay = 0; -+ -+ for (i = 0; i < count; i++) { -+ ptr = &drm_dmt_modes[i]; -+ if (hdisplay && vdisplay) { -+ /* -+ * Only when two are valid, they will be used to check -+ * whether the mode should be added to the mode list of -+ * the connector. -+ */ -+ if (ptr->hdisplay > hdisplay || -+ ptr->vdisplay > vdisplay) -+ continue; -+ } -+ mode = drm_mode_duplicate(dev, ptr); -+ if (mode) { -+ drm_mode_probed_add(connector, mode); -+ num_modes++; -+ } -+ } -+ return num_modes; -+} -+EXPORT_SYMBOL(drm_add_modes_noedid); -diff --git a/drivers/gpu/drm/drm_encoder_slave.c b/drivers/gpu/drm/drm_encoder_slave.c -new file mode 100644 -index 0000000..f018469 ---- /dev/null -+++ b/drivers/gpu/drm/drm_encoder_slave.c -@@ -0,0 +1,116 @@ -+/* -+ * Copyright (C) 2009 Francisco Jerez. -+ * All Rights Reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial -+ * portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ */ -+ -+#include "drm_encoder_slave.h" -+ -+/** -+ * drm_i2c_encoder_init - Initialize an I2C slave encoder -+ * @dev: DRM device. -+ * @encoder: Encoder to be attached to the I2C device. You aren't -+ * required to have called drm_encoder_init() before. -+ * @adap: I2C adapter that will be used to communicate with -+ * the device. -+ * @info: Information that will be used to create the I2C device. -+ * Required fields are @addr and @type. -+ * -+ * Create an I2C device on the specified bus (the module containing its -+ * driver is transparently loaded) and attach it to the specified -+ * &drm_encoder_slave. The @slave_funcs field will be initialized with -+ * the hooks provided by the slave driver. -+ * -+ * Returns 0 on success or a negative errno on failure, in particular, -+ * -ENODEV is returned when no matching driver is found. -+ */ -+int drm_i2c_encoder_init(struct drm_device *dev, -+ struct drm_encoder_slave *encoder, -+ struct i2c_adapter *adap, -+ const struct i2c_board_info *info) -+{ -+ char modalias[sizeof(I2C_MODULE_PREFIX) -+ + I2C_NAME_SIZE]; -+ struct module *module = NULL; -+ struct i2c_client *client; -+ struct drm_i2c_encoder_driver *encoder_drv; -+ int err = 0; -+ -+ snprintf(modalias, sizeof(modalias), -+ "%s%s", I2C_MODULE_PREFIX, info->type); -+ request_module(modalias); -+ -+ client = i2c_new_device(adap, info); -+ if (!client) { -+ err = -ENOMEM; -+ goto fail; -+ } -+ -+ if (!client->driver) { -+ err = -ENODEV; -+ goto fail_unregister; -+ } -+ -+ module = client->driver->driver.owner; -+ if (!try_module_get(module)) { -+ err = -ENODEV; -+ goto fail_unregister; -+ } -+ -+ encoder->bus_priv = client; -+ -+ encoder_drv = to_drm_i2c_encoder_driver(client->driver); -+ -+ err = encoder_drv->encoder_init(client, dev, encoder); -+ if (err) -+ goto fail_unregister; -+ -+ return 0; -+ -+fail_unregister: -+ i2c_unregister_device(client); -+ module_put(module); -+fail: -+ return err; -+} -+EXPORT_SYMBOL(drm_i2c_encoder_init); -+ -+/** -+ * drm_i2c_encoder_destroy - Unregister the I2C device backing an encoder -+ * @drm_encoder: Encoder to be unregistered. -+ * -+ * This should be called from the @destroy method of an I2C slave -+ * encoder driver once I2C access is no longer needed. -+ */ -+void drm_i2c_encoder_destroy(struct drm_encoder *drm_encoder) -+{ -+ struct drm_encoder_slave *encoder = to_encoder_slave(drm_encoder); -+ struct i2c_client *client = drm_i2c_encoder_get_client(drm_encoder); -+ struct module *module = client->driver->driver.owner; -+ -+ i2c_unregister_device(client); -+ encoder->bus_priv = NULL; -+ -+ module_put(module); -+} -+EXPORT_SYMBOL(drm_i2c_encoder_destroy); -diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c -new file mode 100644 -index 0000000..8eee4a6 ---- /dev/null -+++ b/drivers/gpu/drm/drm_fb_helper.c -@@ -0,0 +1,701 @@ -+/* -+ * Copyright (c) 2006-2009 Red Hat Inc. -+ * Copyright (c) 2006-2008 Intel Corporation -+ * Copyright (c) 2007 Dave Airlie -+ * -+ * DRM framebuffer helper functions -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that copyright -+ * notice and this permission notice appear in supporting documentation, and -+ * that the name of the copyright holders not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. The copyright holders make no representations -+ * about the suitability of this software for any purpose. It is provided "as -+ * is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -+ * OF THIS SOFTWARE. -+ * -+ * Authors: -+ * Dave Airlie -+ * Jesse Barnes -+ */ -+#include -+#include -+#include "drmP.h" -+#include "drm_crtc.h" -+#include "drm_fb_helper.h" -+#include "drm_crtc_helper.h" -+ -+MODULE_AUTHOR("David Airlie, Jesse Barnes"); -+MODULE_DESCRIPTION("DRM KMS helper"); -+MODULE_LICENSE("GPL and additional rights"); -+ -+static LIST_HEAD(kernel_fb_helper_list); -+ -+bool drm_fb_helper_force_kernel_mode(void) -+{ -+ int i = 0; -+ bool ret, error = false; -+ struct drm_fb_helper *helper; -+ -+ if (list_empty(&kernel_fb_helper_list)) -+ return false; -+ -+ list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { -+ for (i = 0; i < helper->crtc_count; i++) { -+ struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; -+ ret = drm_crtc_helper_set_config(mode_set); -+ if (ret) -+ error = true; -+ } -+ } -+ return error; -+} -+ -+int drm_fb_helper_panic(struct notifier_block *n, unsigned long ununsed, -+ void *panic_str) -+{ -+ DRM_ERROR("panic occurred, switching back to text console\n"); -+ return drm_fb_helper_force_kernel_mode(); -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_panic); -+ -+static struct notifier_block paniced = { -+ .notifier_call = drm_fb_helper_panic, -+}; -+ -+/** -+ * drm_fb_helper_restore - restore the framebuffer console (kernel) config -+ * -+ * Restore's the kernel's fbcon mode, used for lastclose & panic paths. -+ */ -+void drm_fb_helper_restore(void) -+{ -+ bool ret; -+ ret = drm_fb_helper_force_kernel_mode(); -+ if (ret == true) -+ DRM_ERROR("Failed to restore crtc configuration\n"); -+} -+EXPORT_SYMBOL(drm_fb_helper_restore); -+ -+static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) -+{ -+ drm_fb_helper_restore(); -+} -+static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); -+ -+static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3) -+{ -+ schedule_work(&drm_fb_helper_restore_work); -+} -+ -+static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { -+ .handler = drm_fb_helper_sysrq, -+ .help_msg = "force-fb(V)", -+ .action_msg = "Restore framebuffer console", -+}; -+ -+static void drm_fb_helper_on(struct fb_info *info) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct drm_crtc *crtc; -+ struct drm_encoder *encoder; -+ int i; -+ -+ /* -+ * For each CRTC in this fb, turn the crtc on then, -+ * find all associated encoders and turn them on. -+ */ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -+ -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) -+ break; -+ } -+ -+ mutex_lock(&dev->mode_config.mutex); -+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -+ mutex_unlock(&dev->mode_config.mutex); -+ -+ /* Found a CRTC on this fb, now find encoders */ -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ if (encoder->crtc == crtc) { -+ struct drm_encoder_helper_funcs *encoder_funcs; -+ -+ encoder_funcs = encoder->helper_private; -+ mutex_lock(&dev->mode_config.mutex); -+ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); -+ mutex_unlock(&dev->mode_config.mutex); -+ } -+ } -+ } -+} -+ -+static void drm_fb_helper_off(struct fb_info *info, int dpms_mode) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct drm_crtc *crtc; -+ struct drm_encoder *encoder; -+ int i; -+ -+ /* -+ * For each CRTC in this fb, find all associated encoders -+ * and turn them off, then turn off the CRTC. -+ */ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -+ -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) -+ break; -+ } -+ -+ /* Found a CRTC on this fb, now find encoders */ -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ if (encoder->crtc == crtc) { -+ struct drm_encoder_helper_funcs *encoder_funcs; -+ -+ encoder_funcs = encoder->helper_private; -+ mutex_lock(&dev->mode_config.mutex); -+ encoder_funcs->dpms(encoder, dpms_mode); -+ mutex_unlock(&dev->mode_config.mutex); -+ } -+ } -+ if (dpms_mode == DRM_MODE_DPMS_OFF) { -+ mutex_lock(&dev->mode_config.mutex); -+ crtc_funcs->dpms(crtc, dpms_mode); -+ mutex_unlock(&dev->mode_config.mutex); -+ } -+ } -+} -+ -+int drm_fb_helper_blank(int blank, struct fb_info *info) -+{ -+ switch (blank) { -+ case FB_BLANK_UNBLANK: -+ drm_fb_helper_on(info); -+ break; -+ case FB_BLANK_NORMAL: -+ drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); -+ break; -+ case FB_BLANK_HSYNC_SUSPEND: -+ drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); -+ break; -+ case FB_BLANK_VSYNC_SUSPEND: -+ drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); -+ break; -+ case FB_BLANK_POWERDOWN: -+ drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); -+ break; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_blank); -+ -+static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) -+{ -+ int i; -+ -+ for (i = 0; i < helper->crtc_count; i++) -+ kfree(helper->crtc_info[i].mode_set.connectors); -+ kfree(helper->crtc_info); -+} -+ -+int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, int max_conn_count) -+{ -+ struct drm_device *dev = helper->dev; -+ struct drm_crtc *crtc; -+ int ret = 0; -+ int i; -+ -+ helper->crtc_info = kcalloc(crtc_count, sizeof(struct drm_fb_helper_crtc), GFP_KERNEL); -+ if (!helper->crtc_info) -+ return -ENOMEM; -+ -+ helper->crtc_count = crtc_count; -+ -+ for (i = 0; i < crtc_count; i++) { -+ helper->crtc_info[i].mode_set.connectors = -+ kcalloc(max_conn_count, -+ sizeof(struct drm_connector *), -+ GFP_KERNEL); -+ -+ if (!helper->crtc_info[i].mode_set.connectors) { -+ ret = -ENOMEM; -+ goto out_free; -+ } -+ helper->crtc_info[i].mode_set.num_connectors = 0; -+ } -+ -+ i = 0; -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ helper->crtc_info[i].crtc_id = crtc->base.id; -+ helper->crtc_info[i].mode_set.crtc = crtc; -+ i++; -+ } -+ helper->conn_limit = max_conn_count; -+ return 0; -+out_free: -+ drm_fb_helper_crtc_free(helper); -+ return -ENOMEM; -+} -+EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); -+ -+int drm_fb_helper_setcolreg(unsigned regno, -+ unsigned red, -+ unsigned green, -+ unsigned blue, -+ unsigned transp, -+ struct fb_info *info) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct drm_crtc *crtc; -+ int i; -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ struct drm_framebuffer *fb = fb_helper->fb; -+ -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) -+ break; -+ } -+ if (i == fb_helper->crtc_count) -+ continue; -+ -+ if (regno > 255) -+ return 1; -+ -+ if (fb->depth == 8) { -+ fb_helper->funcs->gamma_set(crtc, red, green, blue, regno); -+ return 0; -+ } -+ -+ if (regno < 16) { -+ switch (fb->depth) { -+ case 15: -+ fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | -+ ((green & 0xf800) >> 6) | -+ ((blue & 0xf800) >> 11); -+ break; -+ case 16: -+ fb->pseudo_palette[regno] = (red & 0xf800) | -+ ((green & 0xfc00) >> 5) | -+ ((blue & 0xf800) >> 11); -+ break; -+ case 24: -+ case 32: -+ fb->pseudo_palette[regno] = -+ (((red >> 8) & 0xff) << info->var.red.offset) | -+ (((green >> 8) & 0xff) << info->var.green.offset) | -+ (((blue >> 8) & 0xff) << info->var.blue.offset); -+ break; -+ } -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_setcolreg); -+ -+int drm_fb_helper_check_var(struct fb_var_screeninfo *var, -+ struct fb_info *info) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_framebuffer *fb = fb_helper->fb; -+ int depth; -+ -+ if (var->pixclock == -1 || !var->pixclock) -+ return -EINVAL; -+ -+ /* Need to resize the fb object !!! */ -+ if (var->xres > fb->width || var->yres > fb->height) { -+ DRM_ERROR("Requested width/height is greater than current fb " -+ "object %dx%d > %dx%d\n", var->xres, var->yres, -+ fb->width, fb->height); -+ DRM_ERROR("Need resizing code.\n"); -+ return -EINVAL; -+ } -+ -+ switch (var->bits_per_pixel) { -+ case 16: -+ depth = (var->green.length == 6) ? 16 : 15; -+ break; -+ case 32: -+ depth = (var->transp.length > 0) ? 32 : 24; -+ break; -+ default: -+ depth = var->bits_per_pixel; -+ break; -+ } -+ -+ switch (depth) { -+ case 8: -+ var->red.offset = 0; -+ var->green.offset = 0; -+ var->blue.offset = 0; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 0; -+ var->transp.offset = 0; -+ break; -+ case 15: -+ var->red.offset = 10; -+ var->green.offset = 5; -+ var->blue.offset = 0; -+ var->red.length = 5; -+ var->green.length = 5; -+ var->blue.length = 5; -+ var->transp.length = 1; -+ var->transp.offset = 15; -+ break; -+ case 16: -+ var->red.offset = 11; -+ var->green.offset = 5; -+ var->blue.offset = 0; -+ var->red.length = 5; -+ var->green.length = 6; -+ var->blue.length = 5; -+ var->transp.length = 0; -+ var->transp.offset = 0; -+ break; -+ case 24: -+ var->red.offset = 16; -+ var->green.offset = 8; -+ var->blue.offset = 0; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 0; -+ var->transp.offset = 0; -+ break; -+ case 32: -+ var->red.offset = 16; -+ var->green.offset = 8; -+ var->blue.offset = 0; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 8; -+ var->transp.offset = 24; -+ break; -+ default: -+ return -EINVAL; -+ } -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_check_var); -+ -+/* this will let fbcon do the mode init */ -+int drm_fb_helper_set_par(struct fb_info *info) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct fb_var_screeninfo *var = &info->var; -+ struct drm_crtc *crtc; -+ int ret; -+ int i; -+ -+ if (var->pixclock != -1) { -+ DRM_ERROR("PIXEL CLCOK SET\n"); -+ return -EINVAL; -+ } -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) -+ break; -+ } -+ if (i == fb_helper->crtc_count) -+ continue; -+ -+ if (crtc->fb == fb_helper->crtc_info[i].mode_set.fb) { -+ mutex_lock(&dev->mode_config.mutex); -+ ret = crtc->funcs->set_config(&fb_helper->crtc_info->mode_set); -+ mutex_unlock(&dev->mode_config.mutex); -+ if (ret) -+ return ret; -+ } -+ } -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_set_par); -+ -+int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, -+ struct fb_info *info) -+{ -+ struct drm_fb_helper *fb_helper = info->par; -+ struct drm_device *dev = fb_helper->dev; -+ struct drm_mode_set *modeset; -+ struct drm_crtc *crtc; -+ int ret = 0; -+ int i; -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ for (i = 0; i < fb_helper->crtc_count; i++) { -+ if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) -+ break; -+ } -+ -+ if (i == fb_helper->crtc_count) -+ continue; -+ -+ modeset = &fb_helper->crtc_info[i].mode_set; -+ -+ modeset->x = var->xoffset; -+ modeset->y = var->yoffset; -+ -+ if (modeset->num_connectors) { -+ mutex_lock(&dev->mode_config.mutex); -+ ret = crtc->funcs->set_config(modeset); -+ mutex_unlock(&dev->mode_config.mutex); -+ if (!ret) { -+ info->var.xoffset = var->xoffset; -+ info->var.yoffset = var->yoffset; -+ } -+ } -+ } -+ return ret; -+} -+EXPORT_SYMBOL(drm_fb_helper_pan_display); -+ -+int drm_fb_helper_single_fb_probe(struct drm_device *dev, -+ int (*fb_create)(struct drm_device *dev, -+ uint32_t fb_width, -+ uint32_t fb_height, -+ uint32_t surface_width, -+ uint32_t surface_height, -+ struct drm_framebuffer **fb_ptr)) -+{ -+ struct drm_crtc *crtc; -+ struct drm_connector *connector; -+ unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; -+ unsigned int surface_width = 0, surface_height = 0; -+ int new_fb = 0; -+ int crtc_count = 0; -+ int ret, i, conn_count = 0; -+ struct fb_info *info; -+ struct drm_framebuffer *fb; -+ struct drm_mode_set *modeset = NULL; -+ struct drm_fb_helper *fb_helper; -+ -+ /* first up get a count of crtcs now in use and new min/maxes width/heights */ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ if (drm_helper_crtc_in_use(crtc)) { -+ if (crtc->desired_mode) { -+ if (crtc->desired_mode->hdisplay < fb_width) -+ fb_width = crtc->desired_mode->hdisplay; -+ -+ if (crtc->desired_mode->vdisplay < fb_height) -+ fb_height = crtc->desired_mode->vdisplay; -+ -+ if (crtc->desired_mode->hdisplay > surface_width) -+ surface_width = crtc->desired_mode->hdisplay; -+ -+ if (crtc->desired_mode->vdisplay > surface_height) -+ surface_height = crtc->desired_mode->vdisplay; -+ } -+ crtc_count++; -+ } -+ } -+ -+ if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { -+ /* hmm everyone went away - assume VGA cable just fell out -+ and will come back later. */ -+ return 0; -+ } -+ -+ /* do we have an fb already? */ -+ if (list_empty(&dev->mode_config.fb_kernel_list)) { -+ ret = (*fb_create)(dev, fb_width, fb_height, surface_width, -+ surface_height, &fb); -+ if (ret) -+ return -EINVAL; -+ new_fb = 1; -+ } else { -+ fb = list_first_entry(&dev->mode_config.fb_kernel_list, -+ struct drm_framebuffer, filp_head); -+ -+ /* if someone hotplugs something bigger than we have already allocated, we are pwned. -+ As really we can't resize an fbdev that is in the wild currently due to fbdev -+ not really being designed for the lower layers moving stuff around under it. -+ - so in the grand style of things - punt. */ -+ if ((fb->width < surface_width) || -+ (fb->height < surface_height)) { -+ DRM_ERROR("Framebuffer not large enough to scale console onto.\n"); -+ return -EINVAL; -+ } -+ } -+ -+ info = fb->fbdev; -+ fb_helper = info->par; -+ -+ crtc_count = 0; -+ /* okay we need to setup new connector sets in the crtcs */ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ modeset = &fb_helper->crtc_info[crtc_count].mode_set; -+ modeset->fb = fb; -+ conn_count = 0; -+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -+ if (connector->encoder) -+ if (connector->encoder->crtc == modeset->crtc) { -+ modeset->connectors[conn_count] = connector; -+ conn_count++; -+ if (conn_count > fb_helper->conn_limit) -+ BUG(); -+ } -+ } -+ -+ for (i = conn_count; i < fb_helper->conn_limit; i++) -+ modeset->connectors[i] = NULL; -+ -+ modeset->crtc = crtc; -+ crtc_count++; -+ -+ modeset->num_connectors = conn_count; -+ if (modeset->crtc->desired_mode) { -+ if (modeset->mode) -+ drm_mode_destroy(dev, modeset->mode); -+ modeset->mode = drm_mode_duplicate(dev, -+ modeset->crtc->desired_mode); -+ } -+ } -+ fb_helper->crtc_count = crtc_count; -+ fb_helper->fb = fb; -+ -+ if (new_fb) { -+ info->var.pixclock = -1; -+ if (register_framebuffer(info) < 0) -+ return -EINVAL; -+ } else { -+ drm_fb_helper_set_par(info); -+ } -+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -+ info->fix.id); -+ -+ /* Switch back to kernel console on panic */ -+ /* multi card linked list maybe */ -+ if (list_empty(&kernel_fb_helper_list)) { -+ printk(KERN_INFO "registered panic notifier\n"); -+ atomic_notifier_chain_register(&panic_notifier_list, -+ &paniced); -+ register_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); -+ } -+ list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list); -+ return 0; -+} -+EXPORT_SYMBOL(drm_fb_helper_single_fb_probe); -+ -+void drm_fb_helper_free(struct drm_fb_helper *helper) -+{ -+ list_del(&helper->kernel_fb_list); -+ if (list_empty(&kernel_fb_helper_list)) { -+ printk(KERN_INFO "unregistered panic notifier\n"); -+ atomic_notifier_chain_unregister(&panic_notifier_list, -+ &paniced); -+ unregister_sysrq_key('v', &sysrq_drm_fb_helper_restore_op); -+ } -+ drm_fb_helper_crtc_free(helper); -+} -+EXPORT_SYMBOL(drm_fb_helper_free); -+ -+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch) -+{ -+ info->fix.type = FB_TYPE_PACKED_PIXELS; -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ info->fix.type_aux = 0; -+ info->fix.xpanstep = 1; /* doing it in hw */ -+ info->fix.ypanstep = 1; /* doing it in hw */ -+ info->fix.ywrapstep = 0; -+ info->fix.accel = FB_ACCEL_NONE; -+ info->fix.type_aux = 0; -+ -+ info->fix.line_length = pitch; -+ return; -+} -+EXPORT_SYMBOL(drm_fb_helper_fill_fix); -+ -+void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, -+ uint32_t fb_width, uint32_t fb_height) -+{ -+ info->pseudo_palette = fb->pseudo_palette; -+ info->var.xres_virtual = fb->width; -+ info->var.yres_virtual = fb->height; -+ info->var.bits_per_pixel = fb->bits_per_pixel; -+ info->var.xoffset = 0; -+ info->var.yoffset = 0; -+ info->var.activate = FB_ACTIVATE_NOW; -+ info->var.height = -1; -+ info->var.width = -1; -+ -+ switch (fb->depth) { -+ case 8: -+ info->var.red.offset = 0; -+ info->var.green.offset = 0; -+ info->var.blue.offset = 0; -+ info->var.red.length = 8; /* 8bit DAC */ -+ info->var.green.length = 8; -+ info->var.blue.length = 8; -+ info->var.transp.offset = 0; -+ info->var.transp.length = 0; -+ break; -+ case 15: -+ info->var.red.offset = 10; -+ info->var.green.offset = 5; -+ info->var.blue.offset = 0; -+ info->var.red.length = 5; -+ info->var.green.length = 5; -+ info->var.blue.length = 5; -+ info->var.transp.offset = 15; -+ info->var.transp.length = 1; -+ break; -+ case 16: -+ info->var.red.offset = 11; -+ info->var.green.offset = 5; -+ info->var.blue.offset = 0; -+ info->var.red.length = 5; -+ info->var.green.length = 6; -+ info->var.blue.length = 5; -+ info->var.transp.offset = 0; -+ break; -+ case 24: -+ info->var.red.offset = 16; -+ info->var.green.offset = 8; -+ info->var.blue.offset = 0; -+ info->var.red.length = 8; -+ info->var.green.length = 8; -+ info->var.blue.length = 8; -+ info->var.transp.offset = 0; -+ info->var.transp.length = 0; -+ break; -+ case 32: -+ info->var.red.offset = 16; -+ info->var.green.offset = 8; -+ info->var.blue.offset = 0; -+ info->var.red.length = 8; -+ info->var.green.length = 8; -+ info->var.blue.length = 8; -+ info->var.transp.offset = 24; -+ info->var.transp.length = 8; -+ break; -+ default: -+ break; -+ } -+ -+ info->var.xres = fb_width; -+ info->var.yres = fb_height; -+} -+EXPORT_SYMBOL(drm_fb_helper_fill_var); -diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c -index ffe8f43..230c9ff 100644 ---- a/drivers/gpu/drm/drm_gem.c -+++ b/drivers/gpu/drm/drm_gem.c -@@ -164,7 +164,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc); - * Removes the mapping from handle to filp for this object. - */ - static int --drm_gem_handle_delete(struct drm_file *filp, int handle) -+drm_gem_handle_delete(struct drm_file *filp, u32 handle) - { - struct drm_device *dev; - struct drm_gem_object *obj; -@@ -207,7 +207,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle) - int - drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, -- int *handlep) -+ u32 *handlep) - { - int ret; - -@@ -221,7 +221,7 @@ again: - - /* do the allocation under our spinlock */ - spin_lock(&file_priv->table_lock); -- ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep); -+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep); - spin_unlock(&file_priv->table_lock); - if (ret == -EAGAIN) - goto again; -@@ -237,7 +237,7 @@ EXPORT_SYMBOL(drm_gem_handle_create); - /** Returns a reference to the object named by the handle. */ - struct drm_gem_object * - drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, -- int handle) -+ u32 handle) - { - struct drm_gem_object *obj; - -@@ -344,7 +344,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, - struct drm_gem_open *args = data; - struct drm_gem_object *obj; - int ret; -- int handle; -+ u32 handle; - - if (!(dev->driver->driver_features & DRIVER_GEM)) - return -ENODEV; -@@ -539,7 +539,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) - vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; - vma->vm_ops = obj->dev->driver->gem_vm_ops; - vma->vm_private_data = map->handle; -- /* FIXME: use pgprot_writecombine when available */ - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - - /* Take a ref for this mapping of the object, so that the fault -diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c -index 3e47869..c861d80 100644 ---- a/drivers/gpu/drm/drm_mm.c -+++ b/drivers/gpu/drm/drm_mm.c -@@ -44,6 +44,7 @@ - #include "drmP.h" - #include "drm_mm.h" - #include -+#include - - #define MM_UNUSED_TARGET 4 - -@@ -370,3 +371,23 @@ void drm_mm_takedown(struct drm_mm * mm) - BUG_ON(mm->num_unused != 0); - } - EXPORT_SYMBOL(drm_mm_takedown); -+ -+#if defined(CONFIG_DEBUG_FS) -+int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) -+{ -+ struct drm_mm_node *entry; -+ int total_used = 0, total_free = 0, total = 0; -+ -+ list_for_each_entry(entry, &mm->ml_entry, ml_entry) { -+ seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: %s\n", entry->start, entry->start + entry->size, entry->size, entry->free ? "free" : "used"); -+ total += entry->size; -+ if (entry->free) -+ total_free += entry->size; -+ else -+ total_used += entry->size; -+ } -+ seq_printf(m, "total: %d, used %d free %d\n", total, total_free, total_used); -+ return 0; -+} -+EXPORT_SYMBOL(drm_mm_dump_table); -+#endif -diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c -index 7914097..49404ce 100644 ---- a/drivers/gpu/drm/drm_modes.c -+++ b/drivers/gpu/drm/drm_modes.c -@@ -8,6 +8,8 @@ - * Copyright © 2007 Dave Airlie - * Copyright © 2007-2008 Intel Corporation - * Jesse Barnes -+ * Copyright 2005-2006 Luc Verhaegen -+ * Copyright (c) 2001, Andy Ritger aritger@nvidia.com - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), -@@ -38,7 +40,6 @@ - #include "drm.h" - #include "drm_crtc.h" - --#define DRM_MODESET_DEBUG "drm_mode" - /** - * drm_mode_debug_printmodeline - debug print a mode - * @dev: DRM device -@@ -51,8 +52,8 @@ - */ - void drm_mode_debug_printmodeline(struct drm_display_mode *mode) - { -- DRM_DEBUG_MODE(DRM_MODESET_DEBUG, -- "Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", -+ DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d " -+ "0x%x 0x%x\n", - mode->base.id, mode->name, mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, -@@ -62,6 +63,420 @@ void drm_mode_debug_printmodeline(struct drm_display_mode *mode) - EXPORT_SYMBOL(drm_mode_debug_printmodeline); - - /** -+ * drm_cvt_mode -create a modeline based on CVT algorithm -+ * @dev: DRM device -+ * @hdisplay: hdisplay size -+ * @vdisplay: vdisplay size -+ * @vrefresh : vrefresh rate -+ * @reduced : Whether the GTF calculation is simplified -+ * @interlaced:Whether the interlace is supported -+ * -+ * LOCKING: -+ * none. -+ * -+ * return the modeline based on CVT algorithm -+ * -+ * This function is called to generate the modeline based on CVT algorithm -+ * according to the hdisplay, vdisplay, vrefresh. -+ * It is based from the VESA(TM) Coordinated Video Timing Generator by -+ * Graham Loveridge April 9, 2003 available at -+ * http://www.vesa.org/public/CVT/CVTd6r1.xls -+ * -+ * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. -+ * What I have done is to translate it by using integer calculation. -+ */ -+#define HV_FACTOR 1000 -+struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, -+ int vdisplay, int vrefresh, -+ bool reduced, bool interlaced) -+{ -+ /* 1) top/bottom margin size (% of height) - default: 1.8, */ -+#define CVT_MARGIN_PERCENTAGE 18 -+ /* 2) character cell horizontal granularity (pixels) - default 8 */ -+#define CVT_H_GRANULARITY 8 -+ /* 3) Minimum vertical porch (lines) - default 3 */ -+#define CVT_MIN_V_PORCH 3 -+ /* 4) Minimum number of vertical back porch lines - default 6 */ -+#define CVT_MIN_V_BPORCH 6 -+ /* Pixel Clock step (kHz) */ -+#define CVT_CLOCK_STEP 250 -+ struct drm_display_mode *drm_mode; -+ bool margins = false; -+ unsigned int vfieldrate, hperiod; -+ int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; -+ int interlace; -+ -+ /* allocate the drm_display_mode structure. If failure, we will -+ * return directly -+ */ -+ drm_mode = drm_mode_create(dev); -+ if (!drm_mode) -+ return NULL; -+ -+ /* the CVT default refresh rate is 60Hz */ -+ if (!vrefresh) -+ vrefresh = 60; -+ -+ /* the required field fresh rate */ -+ if (interlaced) -+ vfieldrate = vrefresh * 2; -+ else -+ vfieldrate = vrefresh; -+ -+ /* horizontal pixels */ -+ hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY); -+ -+ /* determine the left&right borders */ -+ hmargin = 0; -+ if (margins) { -+ hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; -+ hmargin -= hmargin % CVT_H_GRANULARITY; -+ } -+ /* find the total active pixels */ -+ drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin; -+ -+ /* find the number of lines per field */ -+ if (interlaced) -+ vdisplay_rnd = vdisplay / 2; -+ else -+ vdisplay_rnd = vdisplay; -+ -+ /* find the top & bottom borders */ -+ vmargin = 0; -+ if (margins) -+ vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; -+ -+ drm_mode->vdisplay = vdisplay + 2 * vmargin; -+ -+ /* Interlaced */ -+ if (interlaced) -+ interlace = 1; -+ else -+ interlace = 0; -+ -+ /* Determine VSync Width from aspect ratio */ -+ if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay)) -+ vsync = 4; -+ else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay)) -+ vsync = 5; -+ else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay)) -+ vsync = 6; -+ else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay)) -+ vsync = 7; -+ else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay)) -+ vsync = 7; -+ else /* custom */ -+ vsync = 10; -+ -+ if (!reduced) { -+ /* simplify the GTF calculation */ -+ /* 4) Minimum time of vertical sync + back porch interval (µs) -+ * default 550.0 -+ */ -+ int tmp1, tmp2; -+#define CVT_MIN_VSYNC_BP 550 -+ /* 3) Nominal HSync width (% of line period) - default 8 */ -+#define CVT_HSYNC_PERCENTAGE 8 -+ unsigned int hblank_percentage; -+ int vsyncandback_porch, vback_porch, hblank; -+ -+ /* estimated the horizontal period */ -+ tmp1 = HV_FACTOR * 1000000 - -+ CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate; -+ tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 + -+ interlace; -+ hperiod = tmp1 * 2 / (tmp2 * vfieldrate); -+ -+ tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1; -+ /* 9. Find number of lines in sync + backporch */ -+ if (tmp1 < (vsync + CVT_MIN_V_PORCH)) -+ vsyncandback_porch = vsync + CVT_MIN_V_PORCH; -+ else -+ vsyncandback_porch = tmp1; -+ /* 10. Find number of lines in back porch */ -+ vback_porch = vsyncandback_porch - vsync; -+ drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + -+ vsyncandback_porch + CVT_MIN_V_PORCH; -+ /* 5) Definition of Horizontal blanking time limitation */ -+ /* Gradient (%/kHz) - default 600 */ -+#define CVT_M_FACTOR 600 -+ /* Offset (%) - default 40 */ -+#define CVT_C_FACTOR 40 -+ /* Blanking time scaling factor - default 128 */ -+#define CVT_K_FACTOR 128 -+ /* Scaling factor weighting - default 20 */ -+#define CVT_J_FACTOR 20 -+#define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256) -+#define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ -+ CVT_J_FACTOR) -+ /* 12. Find ideal blanking duty cycle from formula */ -+ hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME * -+ hperiod / 1000; -+ /* 13. Blanking time */ -+ if (hblank_percentage < 20 * HV_FACTOR) -+ hblank_percentage = 20 * HV_FACTOR; -+ hblank = drm_mode->hdisplay * hblank_percentage / -+ (100 * HV_FACTOR - hblank_percentage); -+ hblank -= hblank % (2 * CVT_H_GRANULARITY); -+ /* 14. find the total pixes per line */ -+ drm_mode->htotal = drm_mode->hdisplay + hblank; -+ drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2; -+ drm_mode->hsync_start = drm_mode->hsync_end - -+ (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100; -+ drm_mode->hsync_start += CVT_H_GRANULARITY - -+ drm_mode->hsync_start % CVT_H_GRANULARITY; -+ /* fill the Vsync values */ -+ drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH; -+ drm_mode->vsync_end = drm_mode->vsync_start + vsync; -+ } else { -+ /* Reduced blanking */ -+ /* Minimum vertical blanking interval time (µs)- default 460 */ -+#define CVT_RB_MIN_VBLANK 460 -+ /* Fixed number of clocks for horizontal sync */ -+#define CVT_RB_H_SYNC 32 -+ /* Fixed number of clocks for horizontal blanking */ -+#define CVT_RB_H_BLANK 160 -+ /* Fixed number of lines for vertical front porch - default 3*/ -+#define CVT_RB_VFPORCH 3 -+ int vbilines; -+ int tmp1, tmp2; -+ /* 8. Estimate Horizontal period. */ -+ tmp1 = HV_FACTOR * 1000000 - -+ CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate; -+ tmp2 = vdisplay_rnd + 2 * vmargin; -+ hperiod = tmp1 / (tmp2 * vfieldrate); -+ /* 9. Find number of lines in vertical blanking */ -+ vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1; -+ /* 10. Check if vertical blanking is sufficient */ -+ if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH)) -+ vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH; -+ /* 11. Find total number of lines in vertical field */ -+ drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; -+ /* 12. Find total number of pixels in a line */ -+ drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; -+ /* Fill in HSync values */ -+ drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; -+ drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; -+ } -+ /* 15/13. Find pixel clock frequency (kHz for xf86) */ -+ drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; -+ drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; -+ /* 18/16. Find actual vertical frame frequency */ -+ /* ignore - just set the mode flag for interlaced */ -+ if (interlaced) -+ drm_mode->vtotal *= 2; -+ /* Fill the mode line name */ -+ drm_mode_set_name(drm_mode); -+ if (reduced) -+ drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | -+ DRM_MODE_FLAG_NVSYNC); -+ else -+ drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | -+ DRM_MODE_FLAG_NHSYNC); -+ if (interlaced) -+ drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; -+ -+ return drm_mode; -+} -+EXPORT_SYMBOL(drm_cvt_mode); -+ -+/** -+ * drm_gtf_mode - create the modeline based on GTF algorithm -+ * -+ * @dev :drm device -+ * @hdisplay :hdisplay size -+ * @vdisplay :vdisplay size -+ * @vrefresh :vrefresh rate. -+ * @interlaced :whether the interlace is supported -+ * @margins :whether the margin is supported -+ * -+ * LOCKING. -+ * none. -+ * -+ * return the modeline based on GTF algorithm -+ * -+ * This function is to create the modeline based on the GTF algorithm. -+ * Generalized Timing Formula is derived from: -+ * GTF Spreadsheet by Andy Morrish (1/5/97) -+ * available at http://www.vesa.org -+ * -+ * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. -+ * What I have done is to translate it by using integer calculation. -+ * I also refer to the function of fb_get_mode in the file of -+ * drivers/video/fbmon.c -+ */ -+struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, -+ int vdisplay, int vrefresh, -+ bool interlaced, int margins) -+{ -+ /* 1) top/bottom margin size (% of height) - default: 1.8, */ -+#define GTF_MARGIN_PERCENTAGE 18 -+ /* 2) character cell horizontal granularity (pixels) - default 8 */ -+#define GTF_CELL_GRAN 8 -+ /* 3) Minimum vertical porch (lines) - default 3 */ -+#define GTF_MIN_V_PORCH 1 -+ /* width of vsync in lines */ -+#define V_SYNC_RQD 3 -+ /* width of hsync as % of total line */ -+#define H_SYNC_PERCENT 8 -+ /* min time of vsync + back porch (microsec) */ -+#define MIN_VSYNC_PLUS_BP 550 -+ /* blanking formula gradient */ -+#define GTF_M 600 -+ /* blanking formula offset */ -+#define GTF_C 40 -+ /* blanking formula scaling factor */ -+#define GTF_K 128 -+ /* blanking formula scaling factor */ -+#define GTF_J 20 -+ /* C' and M' are part of the Blanking Duty Cycle computation */ -+#define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J) -+#define GTF_M_PRIME (GTF_K * GTF_M / 256) -+ struct drm_display_mode *drm_mode; -+ unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; -+ int top_margin, bottom_margin; -+ int interlace; -+ unsigned int hfreq_est; -+ int vsync_plus_bp, vback_porch; -+ unsigned int vtotal_lines, vfieldrate_est, hperiod; -+ unsigned int vfield_rate, vframe_rate; -+ int left_margin, right_margin; -+ unsigned int total_active_pixels, ideal_duty_cycle; -+ unsigned int hblank, total_pixels, pixel_freq; -+ int hsync, hfront_porch, vodd_front_porch_lines; -+ unsigned int tmp1, tmp2; -+ -+ drm_mode = drm_mode_create(dev); -+ if (!drm_mode) -+ return NULL; -+ -+ /* 1. In order to give correct results, the number of horizontal -+ * pixels requested is first processed to ensure that it is divisible -+ * by the character size, by rounding it to the nearest character -+ * cell boundary: -+ */ -+ hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; -+ hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN; -+ -+ /* 2. If interlace is requested, the number of vertical lines assumed -+ * by the calculation must be halved, as the computation calculates -+ * the number of vertical lines per field. -+ */ -+ if (interlaced) -+ vdisplay_rnd = vdisplay / 2; -+ else -+ vdisplay_rnd = vdisplay; -+ -+ /* 3. Find the frame rate required: */ -+ if (interlaced) -+ vfieldrate_rqd = vrefresh * 2; -+ else -+ vfieldrate_rqd = vrefresh; -+ -+ /* 4. Find number of lines in Top margin: */ -+ top_margin = 0; -+ if (margins) -+ top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / -+ 1000; -+ /* 5. Find number of lines in bottom margin: */ -+ bottom_margin = top_margin; -+ -+ /* 6. If interlace is required, then set variable interlace: */ -+ if (interlaced) -+ interlace = 1; -+ else -+ interlace = 0; -+ -+ /* 7. Estimate the Horizontal frequency */ -+ { -+ tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500; -+ tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) * -+ 2 + interlace; -+ hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1; -+ } -+ -+ /* 8. Find the number of lines in V sync + back porch */ -+ /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */ -+ vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000; -+ vsync_plus_bp = (vsync_plus_bp + 500) / 1000; -+ /* 9. Find the number of lines in V back porch alone: */ -+ vback_porch = vsync_plus_bp - V_SYNC_RQD; -+ /* 10. Find the total number of lines in Vertical field period: */ -+ vtotal_lines = vdisplay_rnd + top_margin + bottom_margin + -+ vsync_plus_bp + GTF_MIN_V_PORCH; -+ /* 11. Estimate the Vertical field frequency: */ -+ vfieldrate_est = hfreq_est / vtotal_lines; -+ /* 12. Find the actual horizontal period: */ -+ hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines); -+ -+ /* 13. Find the actual Vertical field frequency: */ -+ vfield_rate = hfreq_est / vtotal_lines; -+ /* 14. Find the Vertical frame frequency: */ -+ if (interlaced) -+ vframe_rate = vfield_rate / 2; -+ else -+ vframe_rate = vfield_rate; -+ /* 15. Find number of pixels in left margin: */ -+ if (margins) -+ left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / -+ 1000; -+ else -+ left_margin = 0; -+ -+ /* 16.Find number of pixels in right margin: */ -+ right_margin = left_margin; -+ /* 17.Find total number of active pixels in image and left and right */ -+ total_active_pixels = hdisplay_rnd + left_margin + right_margin; -+ /* 18.Find the ideal blanking duty cycle from blanking duty cycle */ -+ ideal_duty_cycle = GTF_C_PRIME * 1000 - -+ (GTF_M_PRIME * 1000000 / hfreq_est); -+ /* 19.Find the number of pixels in the blanking time to the nearest -+ * double character cell: */ -+ hblank = total_active_pixels * ideal_duty_cycle / -+ (100000 - ideal_duty_cycle); -+ hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN); -+ hblank = hblank * 2 * GTF_CELL_GRAN; -+ /* 20.Find total number of pixels: */ -+ total_pixels = total_active_pixels + hblank; -+ /* 21.Find pixel clock frequency: */ -+ pixel_freq = total_pixels * hfreq_est / 1000; -+ /* Stage 1 computations are now complete; I should really pass -+ * the results to another function and do the Stage 2 computations, -+ * but I only need a few more values so I'll just append the -+ * computations here for now */ -+ /* 17. Find the number of pixels in the horizontal sync period: */ -+ hsync = H_SYNC_PERCENT * total_pixels / 100; -+ hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; -+ hsync = hsync * GTF_CELL_GRAN; -+ /* 18. Find the number of pixels in horizontal front porch period */ -+ hfront_porch = hblank / 2 - hsync; -+ /* 36. Find the number of lines in the odd front porch period: */ -+ vodd_front_porch_lines = GTF_MIN_V_PORCH ; -+ -+ /* finally, pack the results in the mode struct */ -+ drm_mode->hdisplay = hdisplay_rnd; -+ drm_mode->hsync_start = hdisplay_rnd + hfront_porch; -+ drm_mode->hsync_end = drm_mode->hsync_start + hsync; -+ drm_mode->htotal = total_pixels; -+ drm_mode->vdisplay = vdisplay_rnd; -+ drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines; -+ drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; -+ drm_mode->vtotal = vtotal_lines; -+ -+ drm_mode->clock = pixel_freq; -+ -+ drm_mode_set_name(drm_mode); -+ drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; -+ -+ if (interlaced) { -+ drm_mode->vtotal *= 2; -+ drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; -+ } -+ -+ return drm_mode; -+} -+EXPORT_SYMBOL(drm_gtf_mode); -+/** - * drm_mode_set_name - set the name on a mode - * @mode: name will be set in this mode - * -@@ -151,7 +566,9 @@ EXPORT_SYMBOL(drm_mode_height); - * FIXME: why is this needed? shouldn't vrefresh be set already? - * - * RETURNS: -- * Vertical refresh rate of @mode x 1000. For precision reasons. -+ * Vertical refresh rate. It will be the result of actual value plus 0.5. -+ * If it is 70.288, it will return 70Hz. -+ * If it is 59.6, it will return 60Hz. - */ - int drm_mode_vrefresh(struct drm_display_mode *mode) - { -@@ -161,14 +578,13 @@ int drm_mode_vrefresh(struct drm_display_mode *mode) - if (mode->vrefresh > 0) - refresh = mode->vrefresh; - else if (mode->htotal > 0 && mode->vtotal > 0) { -+ int vtotal; -+ vtotal = mode->vtotal; - /* work out vrefresh the value will be x1000 */ - calc_val = (mode->clock * 1000); -- - calc_val /= mode->htotal; -- calc_val *= 1000; -- calc_val /= mode->vtotal; -+ refresh = (calc_val + vtotal / 2) / vtotal; - -- refresh = calc_val; - if (mode->flags & DRM_MODE_FLAG_INTERLACE) - refresh *= 2; - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) -@@ -403,8 +819,7 @@ void drm_mode_prune_invalid(struct drm_device *dev, - list_del(&mode->head); - if (verbose) { - drm_mode_debug_printmodeline(mode); -- DRM_DEBUG_MODE(DRM_MODESET_DEBUG, -- "Not using %s mode %d\n", -+ DRM_DEBUG_KMS("Not using %s mode %d\n", - mode->name, mode->status); - } - drm_mode_destroy(dev, mode); -diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c -index bbd4b3d..d379c4f 100644 ---- a/drivers/gpu/drm/drm_proc.c -+++ b/drivers/gpu/drm/drm_proc.c -@@ -106,20 +106,25 @@ int drm_proc_create_files(struct drm_info_list *files, int count, - continue; - - tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); -- ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); -+ if (tmp == NULL) { -+ ret = -1; -+ goto fail; -+ } -+ tmp->minor = minor; -+ tmp->info_ent = &files[i]; -+ list_add(&tmp->list, &minor->proc_nodes.list); -+ -+ ent = proc_create_data(files[i].name, S_IRUGO, root, -+ &drm_proc_fops, tmp); - if (!ent) { - DRM_ERROR("Cannot create /proc/dri/%s/%s\n", - name, files[i].name); -+ list_del(&tmp->list); - kfree(tmp); - ret = -1; - goto fail; - } - -- ent->proc_fops = &drm_proc_fops; -- ent->data = tmp; -- tmp->minor = minor; -- tmp->info_ent = &files[i]; -- list_add(&(tmp->list), &(minor->proc_nodes.list)); - } - return 0; - -diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c -index f7a615b..5161172 100644 ---- a/drivers/gpu/drm/drm_sysfs.c -+++ b/drivers/gpu/drm/drm_sysfs.c -@@ -16,6 +16,7 @@ - #include - #include - -+#include "drm_sysfs.h" - #include "drm_core.h" - #include "drmP.h" - -@@ -253,6 +254,7 @@ static ssize_t subconnector_show(struct device *device, - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: -+ case DRM_MODE_CONNECTOR_TV: - prop = dev->mode_config.tv_subconnector_property; - is_tv = 1; - break; -@@ -293,6 +295,7 @@ static ssize_t select_subconnector_show(struct device *device, - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: -+ case DRM_MODE_CONNECTOR_TV: - prop = dev->mode_config.tv_select_subconnector_property; - is_tv = 1; - break; -@@ -391,6 +394,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: -+ case DRM_MODE_CONNECTOR_TV: - for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) { - ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]); - if (ret) -@@ -519,3 +523,27 @@ void drm_sysfs_device_remove(struct drm_minor *minor) - { - device_unregister(&minor->kdev); - } -+ -+ -+/** -+ * drm_class_device_register - Register a struct device in the drm class. -+ * -+ * @dev: pointer to struct device to register. -+ * -+ * @dev should have all relevant members pre-filled with the exception -+ * of the class member. In particular, the device_type member must -+ * be set. -+ */ -+ -+int drm_class_device_register(struct device *dev) -+{ -+ dev->class = drm_class; -+ return device_register(dev); -+} -+EXPORT_SYMBOL_GPL(drm_class_device_register); -+ -+void drm_class_device_unregister(struct device *dev) -+{ -+ return device_unregister(dev); -+} -+EXPORT_SYMBOL_GPL(drm_class_device_unregister); -diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile -index 30d6b99..5269dfa 100644 ---- a/drivers/gpu/drm/i915/Makefile -+++ b/drivers/gpu/drm/i915/Makefile -@@ -4,10 +4,10 @@ - - ccflags-y := -Iinclude/drm - i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ -+ i915_debugfs.o \ - i915_suspend.o \ - i915_gem.o \ - i915_gem_debug.o \ -- i915_gem_debugfs.o \ - i915_gem_tiling.o \ - intel_display.o \ - intel_crt.o \ -diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c -new file mode 100644 -index 0000000..1e3bdce ---- /dev/null -+++ b/drivers/gpu/drm/i915/i915_debugfs.c -@@ -0,0 +1,445 @@ -+/* -+ * Copyright © 2008 Intel Corporation -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ * -+ * Authors: -+ * Eric Anholt -+ * Keith Packard -+ * -+ */ -+ -+#include -+#include "drmP.h" -+#include "drm.h" -+#include "i915_drm.h" -+#include "i915_drv.h" -+ -+#define DRM_I915_RING_DEBUG 1 -+ -+ -+#if defined(CONFIG_DEBUG_FS) -+ -+#define ACTIVE_LIST 1 -+#define FLUSHING_LIST 2 -+#define INACTIVE_LIST 3 -+ -+static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) -+{ -+ if (obj_priv->user_pin_count > 0) -+ return "P"; -+ else if (obj_priv->pin_count > 0) -+ return "p"; -+ else -+ return " "; -+} -+ -+static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) -+{ -+ switch (obj_priv->tiling_mode) { -+ default: -+ case I915_TILING_NONE: return " "; -+ case I915_TILING_X: return "X"; -+ case I915_TILING_Y: return "Y"; -+ } -+} -+ -+static int i915_gem_object_list_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ uintptr_t list = (uintptr_t) node->info_ent->data; -+ struct list_head *head; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct drm_i915_gem_object *obj_priv; -+ spinlock_t *lock = NULL; -+ -+ switch (list) { -+ case ACTIVE_LIST: -+ seq_printf(m, "Active:\n"); -+ lock = &dev_priv->mm.active_list_lock; -+ head = &dev_priv->mm.active_list; -+ break; -+ case INACTIVE_LIST: -+ seq_printf(m, "Inactive:\n"); -+ head = &dev_priv->mm.inactive_list; -+ break; -+ case FLUSHING_LIST: -+ seq_printf(m, "Flushing:\n"); -+ head = &dev_priv->mm.flushing_list; -+ break; -+ default: -+ DRM_INFO("Ooops, unexpected list\n"); -+ return 0; -+ } -+ -+ if (lock) -+ spin_lock(lock); -+ list_for_each_entry(obj_priv, head, list) -+ { -+ struct drm_gem_object *obj = obj_priv->obj; -+ -+ seq_printf(m, " %p: %s %08x %08x %d", -+ obj, -+ get_pin_flag(obj_priv), -+ obj->read_domains, obj->write_domain, -+ obj_priv->last_rendering_seqno); -+ -+ if (obj->name) -+ seq_printf(m, " (name: %d)", obj->name); -+ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) -+ seq_printf(m, " (fence: %d)", obj_priv->fence_reg); -+ if (obj_priv->gtt_space != NULL) -+ seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); -+ -+ seq_printf(m, "\n"); -+ } -+ -+ if (lock) -+ spin_unlock(lock); -+ return 0; -+} -+ -+static int i915_gem_request_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct drm_i915_gem_request *gem_request; -+ -+ seq_printf(m, "Request:\n"); -+ list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { -+ seq_printf(m, " %d @ %d\n", -+ gem_request->seqno, -+ (int) (jiffies - gem_request->emitted_jiffies)); -+ } -+ return 0; -+} -+ -+static int i915_gem_seqno_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ if (dev_priv->hw_status_page != NULL) { -+ seq_printf(m, "Current sequence: %d\n", -+ i915_get_gem_seqno(dev)); -+ } else { -+ seq_printf(m, "Current sequence: hws uninitialized\n"); -+ } -+ seq_printf(m, "Waiter sequence: %d\n", -+ dev_priv->mm.waiting_gem_seqno); -+ seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); -+ return 0; -+} -+ -+ -+static int i915_interrupt_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ if (!IS_IGDNG(dev)) { -+ seq_printf(m, "Interrupt enable: %08x\n", -+ I915_READ(IER)); -+ seq_printf(m, "Interrupt identity: %08x\n", -+ I915_READ(IIR)); -+ seq_printf(m, "Interrupt mask: %08x\n", -+ I915_READ(IMR)); -+ seq_printf(m, "Pipe A stat: %08x\n", -+ I915_READ(PIPEASTAT)); -+ seq_printf(m, "Pipe B stat: %08x\n", -+ I915_READ(PIPEBSTAT)); -+ } else { -+ seq_printf(m, "North Display Interrupt enable: %08x\n", -+ I915_READ(DEIER)); -+ seq_printf(m, "North Display Interrupt identity: %08x\n", -+ I915_READ(DEIIR)); -+ seq_printf(m, "North Display Interrupt mask: %08x\n", -+ I915_READ(DEIMR)); -+ seq_printf(m, "South Display Interrupt enable: %08x\n", -+ I915_READ(SDEIER)); -+ seq_printf(m, "South Display Interrupt identity: %08x\n", -+ I915_READ(SDEIIR)); -+ seq_printf(m, "South Display Interrupt mask: %08x\n", -+ I915_READ(SDEIMR)); -+ seq_printf(m, "Graphics Interrupt enable: %08x\n", -+ I915_READ(GTIER)); -+ seq_printf(m, "Graphics Interrupt identity: %08x\n", -+ I915_READ(GTIIR)); -+ seq_printf(m, "Graphics Interrupt mask: %08x\n", -+ I915_READ(GTIMR)); -+ } -+ seq_printf(m, "Interrupts received: %d\n", -+ atomic_read(&dev_priv->irq_received)); -+ if (dev_priv->hw_status_page != NULL) { -+ seq_printf(m, "Current sequence: %d\n", -+ i915_get_gem_seqno(dev)); -+ } else { -+ seq_printf(m, "Current sequence: hws uninitialized\n"); -+ } -+ seq_printf(m, "Waiter sequence: %d\n", -+ dev_priv->mm.waiting_gem_seqno); -+ seq_printf(m, "IRQ sequence: %d\n", -+ dev_priv->mm.irq_gem_seqno); -+ return 0; -+} -+ -+static int i915_gem_fence_regs_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ int i; -+ -+ seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); -+ seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); -+ for (i = 0; i < dev_priv->num_fence_regs; i++) { -+ struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; -+ -+ if (obj == NULL) { -+ seq_printf(m, "Fenced object[%2d] = unused\n", i); -+ } else { -+ struct drm_i915_gem_object *obj_priv; -+ -+ obj_priv = obj->driver_private; -+ seq_printf(m, "Fenced object[%2d] = %p: %s " -+ "%08x %08zx %08x %s %08x %08x %d", -+ i, obj, get_pin_flag(obj_priv), -+ obj_priv->gtt_offset, -+ obj->size, obj_priv->stride, -+ get_tiling_flag(obj_priv), -+ obj->read_domains, obj->write_domain, -+ obj_priv->last_rendering_seqno); -+ if (obj->name) -+ seq_printf(m, " (name: %d)", obj->name); -+ seq_printf(m, "\n"); -+ } -+ } -+ -+ return 0; -+} -+ -+static int i915_hws_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ int i; -+ volatile u32 *hws; -+ -+ hws = (volatile u32 *)dev_priv->hw_status_page; -+ if (hws == NULL) -+ return 0; -+ -+ for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { -+ seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", -+ i * 4, -+ hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); -+ } -+ return 0; -+} -+ -+static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count) -+{ -+ int page, i; -+ uint32_t *mem; -+ -+ for (page = 0; page < page_count; page++) { -+ mem = kmap(pages[page]); -+ for (i = 0; i < PAGE_SIZE; i += 4) -+ seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); -+ kunmap(pages[page]); -+ } -+} -+ -+static int i915_batchbuffer_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct drm_gem_object *obj; -+ struct drm_i915_gem_object *obj_priv; -+ int ret; -+ -+ spin_lock(&dev_priv->mm.active_list_lock); -+ -+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { -+ obj = obj_priv->obj; -+ if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { -+ ret = i915_gem_object_get_pages(obj); -+ if (ret) { -+ DRM_ERROR("Failed to get pages: %d\n", ret); -+ spin_unlock(&dev_priv->mm.active_list_lock); -+ return ret; -+ } -+ -+ seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset); -+ i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE); -+ -+ i915_gem_object_put_pages(obj); -+ } -+ } -+ -+ spin_unlock(&dev_priv->mm.active_list_lock); -+ -+ return 0; -+} -+ -+static int i915_ringbuffer_data(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ u8 *virt; -+ uint32_t *ptr, off; -+ -+ if (!dev_priv->ring.ring_obj) { -+ seq_printf(m, "No ringbuffer setup\n"); -+ return 0; -+ } -+ -+ virt = dev_priv->ring.virtual_start; -+ -+ for (off = 0; off < dev_priv->ring.Size; off += 4) { -+ ptr = (uint32_t *)(virt + off); -+ seq_printf(m, "%08x : %08x\n", off, *ptr); -+ } -+ -+ return 0; -+} -+ -+static int i915_ringbuffer_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ unsigned int head, tail; -+ -+ head = I915_READ(PRB0_HEAD) & HEAD_ADDR; -+ tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; -+ -+ seq_printf(m, "RingHead : %08x\n", head); -+ seq_printf(m, "RingTail : %08x\n", tail); -+ seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); -+ seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); -+ -+ return 0; -+} -+ -+static int i915_error_state(struct seq_file *m, void *unused) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct drm_i915_error_state *error; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dev_priv->error_lock, flags); -+ if (!dev_priv->first_error) { -+ seq_printf(m, "no error state collected\n"); -+ goto out; -+ } -+ -+ error = dev_priv->first_error; -+ -+ seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, -+ error->time.tv_usec); -+ seq_printf(m, "EIR: 0x%08x\n", error->eir); -+ seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); -+ seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); -+ seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); -+ seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); -+ seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); -+ seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); -+ if (IS_I965G(dev)) { -+ seq_printf(m, " INSTPS: 0x%08x\n", error->instps); -+ seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); -+ } -+ -+out: -+ spin_unlock_irqrestore(&dev_priv->error_lock, flags); -+ -+ return 0; -+} -+ -+static int i915_registers_info(struct seq_file *m, void *data) { -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ uint32_t reg; -+ -+#define DUMP_RANGE(start, end) \ -+ for (reg=start; reg < end; reg += 4) \ -+ seq_printf(m, "%08x\t%08x\n", reg, I915_READ(reg)); -+ -+ DUMP_RANGE(0x00000, 0x00fff); /* VGA registers */ -+ DUMP_RANGE(0x02000, 0x02fff); /* instruction, memory, interrupt control registers */ -+ DUMP_RANGE(0x03000, 0x031ff); /* FENCE and PPGTT control registers */ -+ DUMP_RANGE(0x03200, 0x03fff); /* frame buffer compression registers */ -+ DUMP_RANGE(0x05000, 0x05fff); /* I/O control registers */ -+ DUMP_RANGE(0x06000, 0x06fff); /* clock control registers */ -+ DUMP_RANGE(0x07000, 0x07fff); /* 3D internal debug registers */ -+ DUMP_RANGE(0x07400, 0x088ff); /* GPE debug registers */ -+ DUMP_RANGE(0x0a000, 0x0afff); /* display palette registers */ -+ DUMP_RANGE(0x10000, 0x13fff); /* MMIO MCHBAR */ -+ DUMP_RANGE(0x30000, 0x3ffff); /* overlay registers */ -+ DUMP_RANGE(0x60000, 0x6ffff); /* display engine pipeline registers */ -+ DUMP_RANGE(0x70000, 0x72fff); /* display and cursor registers */ -+ DUMP_RANGE(0x73000, 0x73fff); /* performance counters */ -+ -+ return 0; -+} -+ -+ -+static struct drm_info_list i915_debugfs_list[] = { -+ {"i915_regs", i915_registers_info, 0}, -+ {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, -+ {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, -+ {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, -+ {"i915_gem_request", i915_gem_request_info, 0}, -+ {"i915_gem_seqno", i915_gem_seqno_info, 0}, -+ {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, -+ {"i915_gem_interrupt", i915_interrupt_info, 0}, -+ {"i915_gem_hws", i915_hws_info, 0}, -+ {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, -+ {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, -+ {"i915_batchbuffers", i915_batchbuffer_info, 0}, -+ {"i915_error_state", i915_error_state, 0}, -+}; -+#define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -+ -+int i915_debugfs_init(struct drm_minor *minor) -+{ -+ return drm_debugfs_create_files(i915_debugfs_list, -+ I915_DEBUGFS_ENTRIES, -+ minor->debugfs_root, minor); -+} -+ -+void i915_debugfs_cleanup(struct drm_minor *minor) -+{ -+ drm_debugfs_remove_files(i915_debugfs_list, -+ I915_DEBUGFS_ENTRIES, minor); -+} -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c -index 50d1f78..9909505 100644 ---- a/drivers/gpu/drm/i915/i915_dma.c -+++ b/drivers/gpu/drm/i915/i915_dma.c -@@ -29,12 +29,11 @@ - #include "drmP.h" - #include "drm.h" - #include "drm_crtc_helper.h" -+#include "drm_fb_helper.h" - #include "intel_drv.h" - #include "i915_drm.h" - #include "i915_drv.h" - --#define I915_DRV "i915_drv" -- - /* Really want an OS-independent resettable timer. Would like to have - * this loop run for (eg) 3 sec, but have the timer reset every time - * the head pointer changes, so that EBUSY only happens if the ring -@@ -80,6 +79,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) - return -EBUSY; - } - -+/* As a ringbuffer is only allowed to wrap between instructions, fill -+ * the tail with NOOPs. -+ */ -+int i915_wrap_ring(struct drm_device *dev) -+{ -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ volatile unsigned int *virt; -+ int rem; -+ -+ rem = dev_priv->ring.Size - dev_priv->ring.tail; -+ if (dev_priv->ring.space < rem) { -+ int ret = i915_wait_ring(dev, rem, __func__); -+ if (ret) -+ return ret; -+ } -+ dev_priv->ring.space -= rem; -+ -+ virt = (unsigned int *) -+ (dev_priv->ring.virtual_start + dev_priv->ring.tail); -+ rem /= 4; -+ while (rem--) -+ *virt++ = MI_NOOP; -+ -+ dev_priv->ring.tail = 0; -+ -+ return 0; -+} -+ - /** - * Sets up the hardware status page for devices that need a physical address - * in the register. -@@ -101,7 +128,7 @@ static int i915_init_phys_hws(struct drm_device *dev) - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); -- DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n"); -+ DRM_DEBUG_DRIVER("Enabled hardware status page\n"); - return 0; - } - -@@ -187,8 +214,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) - master_priv->sarea_priv = (drm_i915_sarea_t *) - ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); - } else { -- DRM_DEBUG_DRIVER(I915_DRV, -- "sarea not found assuming DRI2 userspace\n"); -+ DRM_DEBUG_DRIVER("sarea not found assuming DRI2 userspace\n"); - } - - if (init->ring_size != 0) { -@@ -200,7 +226,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) - } - - dev_priv->ring.Size = init->ring_size; -- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; - - dev_priv->ring.map.offset = init->ring_start; - dev_priv->ring.map.size = init->ring_size; -@@ -238,7 +263,7 @@ static int i915_dma_resume(struct drm_device * dev) - { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - -- DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__); -+ DRM_DEBUG_DRIVER("%s\n", __func__); - - if (dev_priv->ring.map.handle == NULL) { - DRM_ERROR("can not ioremap virtual address for" -@@ -251,14 +276,14 @@ static int i915_dma_resume(struct drm_device * dev) - DRM_ERROR("Can not find hardware status page\n"); - return -EINVAL; - } -- DRM_DEBUG_DRIVER(I915_DRV, "hw status page @ %p\n", -+ DRM_DEBUG_DRIVER("hw status page @ %p\n", - dev_priv->hw_status_page); - - if (dev_priv->status_gfx_addr != 0) - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); - else - I915_WRITE(HWS_PGA, dev_priv->dma_status_page); -- DRM_DEBUG_DRIVER(I915_DRV, "Enabled hardware status page\n"); -+ DRM_DEBUG_DRIVER("Enabled hardware status page\n"); - - return 0; - } -@@ -552,7 +577,7 @@ static int i915_dispatch_flip(struct drm_device * dev) - if (!master_priv->sarea_priv) - return -EINVAL; - -- DRM_DEBUG_DRIVER(I915_DRV, "%s: page=%d pfCurrentPage=%d\n", -+ DRM_DEBUG_DRIVER("%s: page=%d pfCurrentPage=%d\n", - __func__, - dev_priv->current_page, - master_priv->sarea_priv->pf_current_page); -@@ -633,8 +658,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, - return -EINVAL; - } - -- DRM_DEBUG_DRIVER(I915_DRV, -- "i915 batchbuffer, start %x used %d cliprects %d\n", -+ DRM_DEBUG_DRIVER("i915 batchbuffer, start %x used %d cliprects %d\n", - batch->start, batch->used, batch->num_cliprects); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); -@@ -681,8 +705,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, - void *batch_data; - int ret; - -- DRM_DEBUG_DRIVER(I915_DRV, -- "i915 cmdbuffer, buf %p sz %d cliprects %d\n", -+ DRM_DEBUG_DRIVER("i915 cmdbuffer, buf %p sz %d cliprects %d\n", - cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); -@@ -735,7 +758,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, - { - int ret; - -- DRM_DEBUG_DRIVER(I915_DRV, "%s\n", __func__); -+ DRM_DEBUG_DRIVER("%s\n", __func__); - - RING_LOCK_TEST_WITH_RETURN(dev, file_priv); - -@@ -778,7 +801,7 @@ static int i915_getparam(struct drm_device *dev, void *data, - value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; - break; - default: -- DRM_DEBUG_DRIVER(I915_DRV, "Unknown parameter %d\n", -+ DRM_DEBUG_DRIVER("Unknown parameter %d\n", - param->param); - return -EINVAL; - } -@@ -819,7 +842,7 @@ static int i915_setparam(struct drm_device *dev, void *data, - dev_priv->fence_reg_start = param->value; - break; - default: -- DRM_DEBUG_DRIVER(I915_DRV, "unknown parameter %d\n", -+ DRM_DEBUG_DRIVER("unknown parameter %d\n", - param->param); - return -EINVAL; - } -@@ -846,7 +869,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, - return 0; - } - -- DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr); -+ DRM_DEBUG_DRIVER("set status page addr 0x%08x\n", (u32)hws->addr); - - dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); - -@@ -868,13 +891,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data, - - memset(dev_priv->hw_status_page, 0, PAGE_SIZE); - I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); -- DRM_DEBUG_DRIVER(I915_DRV, "load hws HWS_PGA with gfx mem 0x%x\n", -+ DRM_DEBUG_DRIVER("load hws HWS_PGA with gfx mem 0x%x\n", - dev_priv->status_gfx_addr); -- DRM_DEBUG_DRIVER(I915_DRV, "load hws at %p\n", -+ DRM_DEBUG_DRIVER("load hws at %p\n", - dev_priv->hw_status_page); - return 0; - } - -+static int i915_get_bridge_dev(struct drm_device *dev) -+{ -+ struct drm_i915_private *dev_priv = dev->dev_private; -+ -+ dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); -+ if (!dev_priv->bridge_dev) { -+ DRM_ERROR("bridge device not found\n"); -+ return -1; -+ } -+ return 0; -+} -+ - /** - * i915_probe_agp - get AGP bootup configuration - * @pdev: PCI device -@@ -888,20 +923,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data, - static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, - uint32_t *preallocated_size) - { -- struct pci_dev *bridge_dev; -+ struct drm_i915_private *dev_priv = dev->dev_private; - u16 tmp = 0; - unsigned long overhead; - unsigned long stolen; - -- bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); -- if (!bridge_dev) { -- DRM_ERROR("bridge device not found\n"); -- return -1; -- } -- - /* Get the fb aperture size and "stolen" memory amount. */ -- pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp); -- pci_dev_put(bridge_dev); -+ pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp); - - *aperture_size = 1024 * 1024; - *preallocated_size = 1024 * 1024; -@@ -1153,11 +1181,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) - base = drm_get_resource_start(dev, mmio_bar); - size = drm_get_resource_len(dev, mmio_bar); - -+ if (i915_get_bridge_dev(dev)) { -+ ret = -EIO; -+ goto free_priv; -+ } -+ - dev_priv->regs = ioremap(base, size); - if (!dev_priv->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -EIO; -- goto free_priv; -+ goto put_bridge; - } - - dev_priv->mm.gtt_mapping = -@@ -1269,6 +1302,8 @@ out_iomapfree: - io_mapping_free(dev_priv->mm.gtt_mapping); - out_rmmap: - iounmap(dev_priv->regs); -+put_bridge: -+ pci_dev_put(dev_priv->bridge_dev); - free_priv: - kfree(dev_priv); - return ret; -@@ -1312,6 +1347,7 @@ int i915_driver_unload(struct drm_device *dev) - i915_gem_lastclose(dev); - } - -+ pci_dev_put(dev_priv->bridge_dev); - kfree(dev->dev_private); - - return 0; -@@ -1321,7 +1357,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) - { - struct drm_i915_file_private *i915_file_priv; - -- DRM_DEBUG_DRIVER(I915_DRV, "\n"); -+ DRM_DEBUG_DRIVER("\n"); - i915_file_priv = (struct drm_i915_file_private *) - kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); - -@@ -1352,7 +1388,7 @@ void i915_driver_lastclose(struct drm_device * dev) - drm_i915_private_t *dev_priv = dev->dev_private; - - if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { -- intelfb_restore(); -+ drm_fb_helper_restore(); - return; - } - -diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c -index fc4b68a..dbe568c 100644 ---- a/drivers/gpu/drm/i915/i915_drv.c -+++ b/drivers/gpu/drm/i915/i915_drv.c -@@ -37,12 +37,15 @@ - #include - #include "drm_crtc_helper.h" - --static unsigned int i915_modeset = -1; -+static int i915_modeset = -1; - module_param_named(modeset, i915_modeset, int, 0400); - - unsigned int i915_fbpercrtc = 0; - module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); - -+unsigned int i915_powersave = 1; -+module_param_named(powersave, i915_powersave, int, 0400); -+ - static struct drm_driver driver; - - static struct pci_device_id pciidlist[] = { -@@ -188,8 +191,8 @@ static struct drm_driver driver = { - .master_create = i915_master_create, - .master_destroy = i915_master_destroy, - #if defined(CONFIG_DEBUG_FS) -- .debugfs_init = i915_gem_debugfs_init, -- .debugfs_cleanup = i915_gem_debugfs_cleanup, -+ .debugfs_init = i915_debugfs_init, -+ .debugfs_cleanup = i915_debugfs_cleanup, - #endif - .gem_init_object = i915_gem_init_object, - .gem_free_object = i915_gem_free_object, -diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h -index 5b4f87e..77ed060 100644 ---- a/drivers/gpu/drm/i915/i915_drv.h -+++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object { - }; - - typedef struct _drm_i915_ring_buffer { -- int tail_mask; - unsigned long Size; - u8 *virtual_start; - int head; -@@ -156,6 +155,7 @@ typedef struct drm_i915_private { - - void __iomem *regs; - -+ struct pci_dev *bridge_dev; - drm_i915_ring_buffer_t ring; - - drm_dma_handle_t *status_page_dmah; -@@ -311,7 +311,7 @@ typedef struct drm_i915_private { - u32 saveIMR; - u32 saveCACHE_MODE_0; - u32 saveD_STATE; -- u32 saveCG_2D_DIS; -+ u32 saveDSPCLK_GATE_D; - u32 saveMI_ARB_STATE; - u32 saveSWF0[16]; - u32 saveSWF1[16]; -@@ -443,6 +443,14 @@ typedef struct drm_i915_private { - struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; - } mm; - struct sdvo_device_mapping sdvo_mappings[2]; -+ -+ /* Reclocking support */ -+ bool render_reclock_avail; -+ bool lvds_downclock_avail; -+ struct work_struct idle_work; -+ struct timer_list idle_timer; -+ bool busy; -+ u16 orig_clock; - } drm_i915_private_t; - - /** driver private structure attached to each drm_gem_object */ -@@ -575,6 +583,7 @@ enum intel_chip_family { - extern struct drm_ioctl_desc i915_ioctls[]; - extern int i915_max_ioctl; - extern unsigned int i915_fbpercrtc; -+extern unsigned int i915_powersave; - - extern int i915_master_create(struct drm_device *dev, struct drm_master *master); - extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); -@@ -730,8 +739,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, - void i915_dump_lru(struct drm_device *dev, const char *where); - - /* i915_debugfs.c */ --int i915_gem_debugfs_init(struct drm_minor *minor); --void i915_gem_debugfs_cleanup(struct drm_minor *minor); -+int i915_debugfs_init(struct drm_minor *minor); -+void i915_debugfs_cleanup(struct drm_minor *minor); - - /* i915_suspend.c */ - extern int i915_save_state(struct drm_device *dev); -@@ -781,33 +790,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev); - - #define I915_VERBOSE 0 - --#define RING_LOCALS unsigned int outring, ringmask, outcount; \ -- volatile char *virt; -- --#define BEGIN_LP_RING(n) do { \ -- if (I915_VERBOSE) \ -- DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ -- if (dev_priv->ring.space < (n)*4) \ -- i915_wait_ring(dev, (n)*4, __func__); \ -- outcount = 0; \ -- outring = dev_priv->ring.tail; \ -- ringmask = dev_priv->ring.tail_mask; \ -- virt = dev_priv->ring.virtual_start; \ -+#define RING_LOCALS volatile unsigned int *ring_virt__; -+ -+#define BEGIN_LP_RING(n) do { \ -+ int bytes__ = 4*(n); \ -+ if (I915_VERBOSE) DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \ -+ /* a wrap must occur between instructions so pad beforehand */ \ -+ if (unlikely (dev_priv->ring.tail + bytes__ > dev_priv->ring.Size)) \ -+ i915_wrap_ring(dev); \ -+ if (unlikely (dev_priv->ring.space < bytes__)) \ -+ i915_wait_ring(dev, bytes__, __func__); \ -+ ring_virt__ = (unsigned int *) \ -+ (dev_priv->ring.virtual_start + dev_priv->ring.tail); \ -+ dev_priv->ring.tail += bytes__; \ -+ dev_priv->ring.tail &= dev_priv->ring.Size - 1; \ -+ dev_priv->ring.space -= bytes__; \ - } while (0) - --#define OUT_RING(n) do { \ -+#define OUT_RING(n) do { \ - if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ -- *(volatile unsigned int *)(virt + outring) = (n); \ -- outcount++; \ -- outring += 4; \ -- outring &= ringmask; \ -+ *ring_virt__++ = (n); \ - } while (0) - - #define ADVANCE_LP_RING() do { \ -- if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \ -- dev_priv->ring.tail = outring; \ -- dev_priv->ring.space -= outcount * 4; \ -- I915_WRITE(PRB0_TAIL, outring); \ -+ if (I915_VERBOSE) \ -+ DRM_DEBUG("ADVANCE_LP_RING %x\n", dev_priv->ring.tail); \ -+ I915_WRITE(PRB0_TAIL, dev_priv->ring.tail); \ - } while(0) - - /** -@@ -830,6 +838,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); - #define I915_GEM_HWS_INDEX 0x20 - #define I915_BREADCRUMB_INDEX 0x21 - -+extern int i915_wrap_ring(struct drm_device * dev); - extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); - - #define IS_I830(dev) ((dev)->pci_device == 0x3577) -@@ -903,6 +912,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); - /* dsparb controlled by hw only */ - #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) - -+#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) -+#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) -+ - #define PRIMARY_RINGBUFFER_SIZE (128*1024) - - #endif -diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c -index 7edb5b9..954fb69 100644 ---- a/drivers/gpu/drm/i915/i915_gem.c -+++ b/drivers/gpu/drm/i915/i915_gem.c -@@ -29,6 +29,7 @@ - #include "drm.h" - #include "i915_drm.h" - #include "i915_drv.h" -+#include "intel_drv.h" - #include - #include - -@@ -111,7 +112,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, - { - struct drm_i915_gem_create *args = data; - struct drm_gem_object *obj; -- int handle, ret; -+ int ret; -+ u32 handle; - - args->size = roundup(args->size, PAGE_SIZE); - -@@ -981,6 +983,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_set_domain *args = data; - struct drm_gem_object *obj; -+ struct drm_i915_gem_object *obj_priv; - uint32_t read_domains = args->read_domains; - uint32_t write_domain = args->write_domain; - int ret; -@@ -1004,15 +1007,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (obj == NULL) - return -EBADF; -+ obj_priv = obj->driver_private; - - mutex_lock(&dev->struct_mutex); -+ -+ intel_mark_busy(dev, obj); -+ - #if WATCH_BUF - DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", - obj, obj->size, read_domains, write_domain); - #endif - if (read_domains & I915_GEM_DOMAIN_GTT) { -- struct drm_i915_gem_object *obj_priv = obj->driver_private; -- - ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); - - /* Update the LRU on the fence for the CPU access that's -@@ -2776,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) - BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); - BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); - -+ intel_mark_busy(dev, obj); -+ - #if WATCH_BUF - DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", - __func__, obj, -@@ -4093,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) - - /* Set up the kernel mapping for the ring. */ - ring->Size = obj->size; -- ring->tail_mask = obj->size - 1; - - ring->map.offset = dev->agp->base + obj_priv->gtt_offset; - ring->map.size = obj->size; -diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c -deleted file mode 100644 -index cb3b974..0000000 ---- a/drivers/gpu/drm/i915/i915_gem_debugfs.c -+++ /dev/null -@@ -1,396 +0,0 @@ --/* -- * Copyright © 2008 Intel Corporation -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice (including the next -- * paragraph) shall be included in all copies or substantial portions of the -- * Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -- * IN THE SOFTWARE. -- * -- * Authors: -- * Eric Anholt -- * Keith Packard -- * -- */ -- --#include --#include "drmP.h" --#include "drm.h" --#include "i915_drm.h" --#include "i915_drv.h" -- --#define DRM_I915_RING_DEBUG 1 -- -- --#if defined(CONFIG_DEBUG_FS) -- --#define ACTIVE_LIST 1 --#define FLUSHING_LIST 2 --#define INACTIVE_LIST 3 -- --static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) --{ -- if (obj_priv->user_pin_count > 0) -- return "P"; -- else if (obj_priv->pin_count > 0) -- return "p"; -- else -- return " "; --} -- --static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) --{ -- switch (obj_priv->tiling_mode) { -- default: -- case I915_TILING_NONE: return " "; -- case I915_TILING_X: return "X"; -- case I915_TILING_Y: return "Y"; -- } --} -- --static int i915_gem_object_list_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- uintptr_t list = (uintptr_t) node->info_ent->data; -- struct list_head *head; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- struct drm_i915_gem_object *obj_priv; -- spinlock_t *lock = NULL; -- -- switch (list) { -- case ACTIVE_LIST: -- seq_printf(m, "Active:\n"); -- lock = &dev_priv->mm.active_list_lock; -- head = &dev_priv->mm.active_list; -- break; -- case INACTIVE_LIST: -- seq_printf(m, "Inactive:\n"); -- head = &dev_priv->mm.inactive_list; -- break; -- case FLUSHING_LIST: -- seq_printf(m, "Flushing:\n"); -- head = &dev_priv->mm.flushing_list; -- break; -- default: -- DRM_INFO("Ooops, unexpected list\n"); -- return 0; -- } -- -- if (lock) -- spin_lock(lock); -- list_for_each_entry(obj_priv, head, list) -- { -- struct drm_gem_object *obj = obj_priv->obj; -- -- seq_printf(m, " %p: %s %08x %08x %d", -- obj, -- get_pin_flag(obj_priv), -- obj->read_domains, obj->write_domain, -- obj_priv->last_rendering_seqno); -- -- if (obj->name) -- seq_printf(m, " (name: %d)", obj->name); -- if (obj_priv->fence_reg != I915_FENCE_REG_NONE) -- seq_printf(m, " (fence: %d)", obj_priv->fence_reg); -- if (obj_priv->gtt_space != NULL) -- seq_printf(m, " (gtt_offset: %08x)", obj_priv->gtt_offset); -- -- seq_printf(m, "\n"); -- } -- -- if (lock) -- spin_unlock(lock); -- return 0; --} -- --static int i915_gem_request_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- struct drm_i915_gem_request *gem_request; -- -- seq_printf(m, "Request:\n"); -- list_for_each_entry(gem_request, &dev_priv->mm.request_list, list) { -- seq_printf(m, " %d @ %d\n", -- gem_request->seqno, -- (int) (jiffies - gem_request->emitted_jiffies)); -- } -- return 0; --} -- --static int i915_gem_seqno_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- -- if (dev_priv->hw_status_page != NULL) { -- seq_printf(m, "Current sequence: %d\n", -- i915_get_gem_seqno(dev)); -- } else { -- seq_printf(m, "Current sequence: hws uninitialized\n"); -- } -- seq_printf(m, "Waiter sequence: %d\n", -- dev_priv->mm.waiting_gem_seqno); -- seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); -- return 0; --} -- -- --static int i915_interrupt_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- -- seq_printf(m, "Interrupt enable: %08x\n", -- I915_READ(IER)); -- seq_printf(m, "Interrupt identity: %08x\n", -- I915_READ(IIR)); -- seq_printf(m, "Interrupt mask: %08x\n", -- I915_READ(IMR)); -- seq_printf(m, "Pipe A stat: %08x\n", -- I915_READ(PIPEASTAT)); -- seq_printf(m, "Pipe B stat: %08x\n", -- I915_READ(PIPEBSTAT)); -- seq_printf(m, "Interrupts received: %d\n", -- atomic_read(&dev_priv->irq_received)); -- if (dev_priv->hw_status_page != NULL) { -- seq_printf(m, "Current sequence: %d\n", -- i915_get_gem_seqno(dev)); -- } else { -- seq_printf(m, "Current sequence: hws uninitialized\n"); -- } -- seq_printf(m, "Waiter sequence: %d\n", -- dev_priv->mm.waiting_gem_seqno); -- seq_printf(m, "IRQ sequence: %d\n", -- dev_priv->mm.irq_gem_seqno); -- return 0; --} -- --static int i915_gem_fence_regs_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- int i; -- -- seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); -- seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); -- for (i = 0; i < dev_priv->num_fence_regs; i++) { -- struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; -- -- if (obj == NULL) { -- seq_printf(m, "Fenced object[%2d] = unused\n", i); -- } else { -- struct drm_i915_gem_object *obj_priv; -- -- obj_priv = obj->driver_private; -- seq_printf(m, "Fenced object[%2d] = %p: %s " -- "%08x %08zx %08x %s %08x %08x %d", -- i, obj, get_pin_flag(obj_priv), -- obj_priv->gtt_offset, -- obj->size, obj_priv->stride, -- get_tiling_flag(obj_priv), -- obj->read_domains, obj->write_domain, -- obj_priv->last_rendering_seqno); -- if (obj->name) -- seq_printf(m, " (name: %d)", obj->name); -- seq_printf(m, "\n"); -- } -- } -- -- return 0; --} -- --static int i915_hws_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- int i; -- volatile u32 *hws; -- -- hws = (volatile u32 *)dev_priv->hw_status_page; -- if (hws == NULL) -- return 0; -- -- for (i = 0; i < 4096 / sizeof(u32) / 4; i += 4) { -- seq_printf(m, "0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", -- i * 4, -- hws[i], hws[i + 1], hws[i + 2], hws[i + 3]); -- } -- return 0; --} -- --static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_count) --{ -- int page, i; -- uint32_t *mem; -- -- for (page = 0; page < page_count; page++) { -- mem = kmap(pages[page]); -- for (i = 0; i < PAGE_SIZE; i += 4) -- seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); -- kunmap(pages[page]); -- } --} -- --static int i915_batchbuffer_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- struct drm_gem_object *obj; -- struct drm_i915_gem_object *obj_priv; -- int ret; -- -- spin_lock(&dev_priv->mm.active_list_lock); -- -- list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) { -- obj = obj_priv->obj; -- if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { -- ret = i915_gem_object_get_pages(obj); -- if (ret) { -- DRM_ERROR("Failed to get pages: %d\n", ret); -- spin_unlock(&dev_priv->mm.active_list_lock); -- return ret; -- } -- -- seq_printf(m, "--- gtt_offset = 0x%08x\n", obj_priv->gtt_offset); -- i915_dump_pages(m, obj_priv->pages, obj->size / PAGE_SIZE); -- -- i915_gem_object_put_pages(obj); -- } -- } -- -- spin_unlock(&dev_priv->mm.active_list_lock); -- -- return 0; --} -- --static int i915_ringbuffer_data(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- u8 *virt; -- uint32_t *ptr, off; -- -- if (!dev_priv->ring.ring_obj) { -- seq_printf(m, "No ringbuffer setup\n"); -- return 0; -- } -- -- virt = dev_priv->ring.virtual_start; -- -- for (off = 0; off < dev_priv->ring.Size; off += 4) { -- ptr = (uint32_t *)(virt + off); -- seq_printf(m, "%08x : %08x\n", off, *ptr); -- } -- -- return 0; --} -- --static int i915_ringbuffer_info(struct seq_file *m, void *data) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- unsigned int head, tail, mask; -- -- head = I915_READ(PRB0_HEAD) & HEAD_ADDR; -- tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; -- mask = dev_priv->ring.tail_mask; -- -- seq_printf(m, "RingHead : %08x\n", head); -- seq_printf(m, "RingTail : %08x\n", tail); -- seq_printf(m, "RingMask : %08x\n", mask); -- seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); -- seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); -- -- return 0; --} -- --static int i915_error_state(struct seq_file *m, void *unused) --{ -- struct drm_info_node *node = (struct drm_info_node *) m->private; -- struct drm_device *dev = node->minor->dev; -- drm_i915_private_t *dev_priv = dev->dev_private; -- struct drm_i915_error_state *error; -- unsigned long flags; -- -- spin_lock_irqsave(&dev_priv->error_lock, flags); -- if (!dev_priv->first_error) { -- seq_printf(m, "no error state collected\n"); -- goto out; -- } -- -- error = dev_priv->first_error; -- -- seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, -- error->time.tv_usec); -- seq_printf(m, "EIR: 0x%08x\n", error->eir); -- seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); -- seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); -- seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); -- seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); -- seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); -- seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); -- if (IS_I965G(dev)) { -- seq_printf(m, " INSTPS: 0x%08x\n", error->instps); -- seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); -- } -- --out: -- spin_unlock_irqrestore(&dev_priv->error_lock, flags); -- -- return 0; --} -- --static struct drm_info_list i915_gem_debugfs_list[] = { -- {"i915_gem_active", i915_gem_object_list_info, 0, (void *) ACTIVE_LIST}, -- {"i915_gem_flushing", i915_gem_object_list_info, 0, (void *) FLUSHING_LIST}, -- {"i915_gem_inactive", i915_gem_object_list_info, 0, (void *) INACTIVE_LIST}, -- {"i915_gem_request", i915_gem_request_info, 0}, -- {"i915_gem_seqno", i915_gem_seqno_info, 0}, -- {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, -- {"i915_gem_interrupt", i915_interrupt_info, 0}, -- {"i915_gem_hws", i915_hws_info, 0}, -- {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, -- {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, -- {"i915_batchbuffers", i915_batchbuffer_info, 0}, -- {"i915_error_state", i915_error_state, 0}, --}; --#define I915_GEM_DEBUGFS_ENTRIES ARRAY_SIZE(i915_gem_debugfs_list) -- --int i915_gem_debugfs_init(struct drm_minor *minor) --{ -- return drm_debugfs_create_files(i915_gem_debugfs_list, -- I915_GEM_DEBUGFS_ENTRIES, -- minor->debugfs_root, minor); --} -- --void i915_gem_debugfs_cleanup(struct drm_minor *minor) --{ -- drm_debugfs_remove_files(i915_gem_debugfs_list, -- I915_GEM_DEBUGFS_ENTRIES, minor); --} -- --#endif /* CONFIG_DEBUG_FS */ -- -diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c -index a2d527b..200e398 100644 ---- a/drivers/gpu/drm/i915/i915_gem_tiling.c -+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c -@@ -94,23 +94,15 @@ - static int - intel_alloc_mchbar_resource(struct drm_device *dev) - { -- struct pci_dev *bridge_dev; - drm_i915_private_t *dev_priv = dev->dev_private; - int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp_lo, temp_hi = 0; - u64 mchbar_addr; - int ret = 0; - -- bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); -- if (!bridge_dev) { -- DRM_DEBUG("no bridge dev?!\n"); -- ret = -ENODEV; -- goto out; -- } -- - if (IS_I965G(dev)) -- pci_read_config_dword(bridge_dev, reg + 4, &temp_hi); -- pci_read_config_dword(bridge_dev, reg, &temp_lo); -+ pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi); -+ pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo); - mchbar_addr = ((u64)temp_hi << 32) | temp_lo; - - /* If ACPI doesn't have it, assume we need to allocate it ourselves */ -@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev) - if (mchbar_addr && - pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { - ret = 0; -- goto out_put; -+ goto out; - } - #endif - - /* Get some space for it */ -- ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, -+ ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res, - MCHBAR_SIZE, MCHBAR_SIZE, - PCIBIOS_MIN_MEM, - 0, pcibios_align_resource, -- bridge_dev); -+ dev_priv->bridge_dev); - if (ret) { - DRM_DEBUG("failed bus alloc: %d\n", ret); - dev_priv->mch_res.start = 0; -- goto out_put; -+ goto out; - } - - if (IS_I965G(dev)) -- pci_write_config_dword(bridge_dev, reg + 4, -+ pci_write_config_dword(dev_priv->bridge_dev, reg + 4, - upper_32_bits(dev_priv->mch_res.start)); - -- pci_write_config_dword(bridge_dev, reg, -+ pci_write_config_dword(dev_priv->bridge_dev, reg, - lower_32_bits(dev_priv->mch_res.start)); --out_put: -- pci_dev_put(bridge_dev); - out: - return ret; - } -@@ -150,44 +140,36 @@ out: - static bool - intel_setup_mchbar(struct drm_device *dev) - { -- struct pci_dev *bridge_dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; - int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - bool need_disable = false, enabled; - -- bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); -- if (!bridge_dev) { -- DRM_DEBUG("no bridge dev?!\n"); -- goto out; -- } -- - if (IS_I915G(dev) || IS_I915GM(dev)) { -- pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); -+ pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - enabled = !!(temp & DEVEN_MCHBAR_EN); - } else { -- pci_read_config_dword(bridge_dev, mchbar_reg, &temp); -+ pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - enabled = temp & 1; - } - - /* If it's already enabled, don't have to do anything */ - if (enabled) -- goto out_put; -+ goto out; - - if (intel_alloc_mchbar_resource(dev)) -- goto out_put; -+ goto out; - - need_disable = true; - - /* Space is allocated or reserved, so enable it. */ - if (IS_I915G(dev) || IS_I915GM(dev)) { -- pci_write_config_dword(bridge_dev, DEVEN_REG, -+ pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, - temp | DEVEN_MCHBAR_EN); - } else { -- pci_read_config_dword(bridge_dev, mchbar_reg, &temp); -- pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1); -+ pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); -+ pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1); - } --out_put: -- pci_dev_put(bridge_dev); - out: - return need_disable; - } -@@ -196,25 +178,18 @@ static void - intel_teardown_mchbar(struct drm_device *dev, bool disable) - { - drm_i915_private_t *dev_priv = dev->dev_private; -- struct pci_dev *bridge_dev; - int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; - -- bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); -- if (!bridge_dev) { -- DRM_DEBUG("no bridge dev?!\n"); -- return; -- } -- - if (disable) { - if (IS_I915G(dev) || IS_I915GM(dev)) { -- pci_read_config_dword(bridge_dev, DEVEN_REG, &temp); -+ pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - temp &= ~DEVEN_MCHBAR_EN; -- pci_write_config_dword(bridge_dev, DEVEN_REG, temp); -+ pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); - } else { -- pci_read_config_dword(bridge_dev, mchbar_reg, &temp); -+ pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - temp &= ~1; -- pci_write_config_dword(bridge_dev, mchbar_reg, temp); -+ pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); - } - } - -@@ -234,7 +209,13 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) - uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; - bool need_disable; - -- if (!IS_I9XX(dev)) { -+ if (IS_IGDNG(dev)) { -+ /* On IGDNG whatever DRAM config, GPU always do -+ * same swizzling setup. -+ */ -+ swizzle_x = I915_BIT_6_SWIZZLE_9_10; -+ swizzle_y = I915_BIT_6_SWIZZLE_9; -+ } else if (!IS_I9XX(dev)) { - /* As far as we know, the 865 doesn't have these bit 6 - * swizzling issues. - */ -@@ -317,13 +298,6 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) - } - } - -- /* FIXME: check with memory config on IGDNG */ -- if (IS_IGDNG(dev)) { -- DRM_ERROR("disable tiling on IGDNG...\n"); -- swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN; -- swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN; -- } -- - dev_priv->mm.bit_6_swizzle_x = swizzle_x; - dev_priv->mm.bit_6_swizzle_y = swizzle_y; - } -diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c -index 7ebc84c..6c89f2f 100644 ---- a/drivers/gpu/drm/i915/i915_irq.c -+++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) - - I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); - I915_READ(PORT_HOTPLUG_STAT); -+ -+ /* EOS interrupts occurs */ -+ if (IS_IGD(dev) && -+ (hotplug_status & CRT_EOS_INT_STATUS)) { -+ u32 temp; -+ -+ DRM_DEBUG("EOS interrupt occurs\n"); -+ /* status is already cleared */ -+ temp = I915_READ(ADPA); -+ temp &= ~ADPA_DAC_ENABLE; -+ I915_WRITE(ADPA, temp); -+ -+ temp = I915_READ(PORT_HOTPLUG_EN); -+ temp &= ~CRT_EOS_INT_EN; -+ I915_WRITE(PORT_HOTPLUG_EN, temp); -+ -+ temp = I915_READ(PORT_HOTPLUG_STAT); -+ if (temp & CRT_EOS_INT_STATUS) -+ I915_WRITE(PORT_HOTPLUG_STAT, -+ CRT_EOS_INT_STATUS); -+ } - } - - I915_WRITE(IIR, iir); -diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index 2955083..e38cd21 100644 ---- a/drivers/gpu/drm/i915/i915_reg.h -+++ b/drivers/gpu/drm/i915/i915_reg.h -@@ -55,7 +55,7 @@ - /* PCI config space */ - - #define HPLLCC 0xc0 /* 855 only */ --#define GC_CLOCK_CONTROL_MASK (3 << 0) -+#define GC_CLOCK_CONTROL_MASK (0xf << 0) - #define GC_CLOCK_133_200 (0 << 0) - #define GC_CLOCK_100_200 (1 << 0) - #define GC_CLOCK_100_133 (2 << 0) -@@ -65,6 +65,25 @@ - #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) - #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) - #define GC_DISPLAY_CLOCK_MASK (7 << 4) -+#define GM45_GC_RENDER_CLOCK_MASK (0xf << 0) -+#define GM45_GC_RENDER_CLOCK_266_MHZ (8 << 0) -+#define GM45_GC_RENDER_CLOCK_320_MHZ (9 << 0) -+#define GM45_GC_RENDER_CLOCK_400_MHZ (0xb << 0) -+#define GM45_GC_RENDER_CLOCK_533_MHZ (0xc << 0) -+#define I965_GC_RENDER_CLOCK_MASK (0xf << 0) -+#define I965_GC_RENDER_CLOCK_267_MHZ (2 << 0) -+#define I965_GC_RENDER_CLOCK_333_MHZ (3 << 0) -+#define I965_GC_RENDER_CLOCK_444_MHZ (4 << 0) -+#define I965_GC_RENDER_CLOCK_533_MHZ (5 << 0) -+#define I945_GC_RENDER_CLOCK_MASK (7 << 0) -+#define I945_GC_RENDER_CLOCK_166_MHZ (0 << 0) -+#define I945_GC_RENDER_CLOCK_200_MHZ (1 << 0) -+#define I945_GC_RENDER_CLOCK_250_MHZ (3 << 0) -+#define I945_GC_RENDER_CLOCK_400_MHZ (5 << 0) -+#define I915_GC_RENDER_CLOCK_MASK (7 << 0) -+#define I915_GC_RENDER_CLOCK_166_MHZ (0 << 0) -+#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) -+#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) - #define LBB 0xf4 - - /* VGA stuff */ -@@ -553,9 +572,118 @@ - #define DPLLA_TEST_M_BYPASS (1 << 2) - #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) - #define D_STATE 0x6104 --#define CG_2D_DIS 0x6200 --#define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) --#define CG_3D_DIS 0x6204 -+#define DSTATE_PLL_D3_OFF (1<<3) -+#define DSTATE_GFX_CLOCK_GATING (1<<1) -+#define DSTATE_DOT_CLOCK_GATING (1<<0) -+#define DSPCLK_GATE_D 0x6200 -+# define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ -+# define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ -+# define VRHUNIT_CLOCK_GATE_DISABLE (1 << 28) /* 965 */ -+# define VRDUNIT_CLOCK_GATE_DISABLE (1 << 27) /* 965 */ -+# define AUDUNIT_CLOCK_GATE_DISABLE (1 << 26) /* 965 */ -+# define DPUNIT_A_CLOCK_GATE_DISABLE (1 << 25) /* 965 */ -+# define DPCUNIT_CLOCK_GATE_DISABLE (1 << 24) /* 965 */ -+# define TVRUNIT_CLOCK_GATE_DISABLE (1 << 23) /* 915-945 */ -+# define TVCUNIT_CLOCK_GATE_DISABLE (1 << 22) /* 915-945 */ -+# define TVFUNIT_CLOCK_GATE_DISABLE (1 << 21) /* 915-945 */ -+# define TVEUNIT_CLOCK_GATE_DISABLE (1 << 20) /* 915-945 */ -+# define DVSUNIT_CLOCK_GATE_DISABLE (1 << 19) /* 915-945 */ -+# define DSSUNIT_CLOCK_GATE_DISABLE (1 << 18) /* 915-945 */ -+# define DDBUNIT_CLOCK_GATE_DISABLE (1 << 17) /* 915-945 */ -+# define DPRUNIT_CLOCK_GATE_DISABLE (1 << 16) /* 915-945 */ -+# define DPFUNIT_CLOCK_GATE_DISABLE (1 << 15) /* 915-945 */ -+# define DPBMUNIT_CLOCK_GATE_DISABLE (1 << 14) /* 915-945 */ -+# define DPLSUNIT_CLOCK_GATE_DISABLE (1 << 13) /* 915-945 */ -+# define DPLUNIT_CLOCK_GATE_DISABLE (1 << 12) /* 915-945 */ -+# define DPOUNIT_CLOCK_GATE_DISABLE (1 << 11) -+# define DPBUNIT_CLOCK_GATE_DISABLE (1 << 10) -+# define DCUNIT_CLOCK_GATE_DISABLE (1 << 9) -+# define DPUNIT_CLOCK_GATE_DISABLE (1 << 8) -+# define VRUNIT_CLOCK_GATE_DISABLE (1 << 7) /* 915+: reserved */ -+# define OVHUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 830-865 */ -+# define DPIOUNIT_CLOCK_GATE_DISABLE (1 << 6) /* 915-945 */ -+# define OVFUNIT_CLOCK_GATE_DISABLE (1 << 5) -+# define OVBUNIT_CLOCK_GATE_DISABLE (1 << 4) -+/** -+ * This bit must be set on the 830 to prevent hangs when turning off the -+ * overlay scaler. -+ */ -+# define OVRUNIT_CLOCK_GATE_DISABLE (1 << 3) -+# define OVCUNIT_CLOCK_GATE_DISABLE (1 << 2) -+# define OVUUNIT_CLOCK_GATE_DISABLE (1 << 1) -+# define ZVUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 830 */ -+# define OVLUNIT_CLOCK_GATE_DISABLE (1 << 0) /* 845,865 */ -+ -+#define RENCLK_GATE_D1 0x6204 -+# define BLITTER_CLOCK_GATE_DISABLE (1 << 13) /* 945GM only */ -+# define MPEG_CLOCK_GATE_DISABLE (1 << 12) /* 945GM only */ -+# define PC_FE_CLOCK_GATE_DISABLE (1 << 11) -+# define PC_BE_CLOCK_GATE_DISABLE (1 << 10) -+# define WINDOWER_CLOCK_GATE_DISABLE (1 << 9) -+# define INTERPOLATOR_CLOCK_GATE_DISABLE (1 << 8) -+# define COLOR_CALCULATOR_CLOCK_GATE_DISABLE (1 << 7) -+# define MOTION_COMP_CLOCK_GATE_DISABLE (1 << 6) -+# define MAG_CLOCK_GATE_DISABLE (1 << 5) -+/** This bit must be unset on 855,865 */ -+# define MECI_CLOCK_GATE_DISABLE (1 << 4) -+# define DCMP_CLOCK_GATE_DISABLE (1 << 3) -+# define MEC_CLOCK_GATE_DISABLE (1 << 2) -+# define MECO_CLOCK_GATE_DISABLE (1 << 1) -+/** This bit must be set on 855,865. */ -+# define SV_CLOCK_GATE_DISABLE (1 << 0) -+# define I915_MPEG_CLOCK_GATE_DISABLE (1 << 16) -+# define I915_VLD_IP_PR_CLOCK_GATE_DISABLE (1 << 15) -+# define I915_MOTION_COMP_CLOCK_GATE_DISABLE (1 << 14) -+# define I915_BD_BF_CLOCK_GATE_DISABLE (1 << 13) -+# define I915_SF_SE_CLOCK_GATE_DISABLE (1 << 12) -+# define I915_WM_CLOCK_GATE_DISABLE (1 << 11) -+# define I915_IZ_CLOCK_GATE_DISABLE (1 << 10) -+# define I915_PI_CLOCK_GATE_DISABLE (1 << 9) -+# define I915_DI_CLOCK_GATE_DISABLE (1 << 8) -+# define I915_SH_SV_CLOCK_GATE_DISABLE (1 << 7) -+# define I915_PL_DG_QC_FT_CLOCK_GATE_DISABLE (1 << 6) -+# define I915_SC_CLOCK_GATE_DISABLE (1 << 5) -+# define I915_FL_CLOCK_GATE_DISABLE (1 << 4) -+# define I915_DM_CLOCK_GATE_DISABLE (1 << 3) -+# define I915_PS_CLOCK_GATE_DISABLE (1 << 2) -+# define I915_CC_CLOCK_GATE_DISABLE (1 << 1) -+# define I915_BY_CLOCK_GATE_DISABLE (1 << 0) -+ -+# define I965_RCZ_CLOCK_GATE_DISABLE (1 << 30) -+/** This bit must always be set on 965G/965GM */ -+# define I965_RCC_CLOCK_GATE_DISABLE (1 << 29) -+# define I965_RCPB_CLOCK_GATE_DISABLE (1 << 28) -+# define I965_DAP_CLOCK_GATE_DISABLE (1 << 27) -+# define I965_ROC_CLOCK_GATE_DISABLE (1 << 26) -+# define I965_GW_CLOCK_GATE_DISABLE (1 << 25) -+# define I965_TD_CLOCK_GATE_DISABLE (1 << 24) -+/** This bit must always be set on 965G */ -+# define I965_ISC_CLOCK_GATE_DISABLE (1 << 23) -+# define I965_IC_CLOCK_GATE_DISABLE (1 << 22) -+# define I965_EU_CLOCK_GATE_DISABLE (1 << 21) -+# define I965_IF_CLOCK_GATE_DISABLE (1 << 20) -+# define I965_TC_CLOCK_GATE_DISABLE (1 << 19) -+# define I965_SO_CLOCK_GATE_DISABLE (1 << 17) -+# define I965_FBC_CLOCK_GATE_DISABLE (1 << 16) -+# define I965_MARI_CLOCK_GATE_DISABLE (1 << 15) -+# define I965_MASF_CLOCK_GATE_DISABLE (1 << 14) -+# define I965_MAWB_CLOCK_GATE_DISABLE (1 << 13) -+# define I965_EM_CLOCK_GATE_DISABLE (1 << 12) -+# define I965_UC_CLOCK_GATE_DISABLE (1 << 11) -+# define I965_SI_CLOCK_GATE_DISABLE (1 << 6) -+# define I965_MT_CLOCK_GATE_DISABLE (1 << 5) -+# define I965_PL_CLOCK_GATE_DISABLE (1 << 4) -+# define I965_DG_CLOCK_GATE_DISABLE (1 << 3) -+# define I965_QC_CLOCK_GATE_DISABLE (1 << 2) -+# define I965_FT_CLOCK_GATE_DISABLE (1 << 1) -+# define I965_DM_CLOCK_GATE_DISABLE (1 << 0) -+ -+#define RENCLK_GATE_D2 0x6208 -+#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9) -+#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7) -+#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6) -+#define RAMCLK_GATE_D 0x6210 /* CRL only */ -+#define DEUC 0x6214 /* CRL only */ - - /* - * Palette regs -@@ -683,6 +811,7 @@ - #define SDVOB_HOTPLUG_INT_EN (1 << 26) - #define SDVOC_HOTPLUG_INT_EN (1 << 25) - #define TV_HOTPLUG_INT_EN (1 << 18) -+#define CRT_EOS_INT_EN (1 << 10) - #define CRT_HOTPLUG_INT_EN (1 << 9) - #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) - #define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) -@@ -717,6 +846,7 @@ - #define DPC_HOTPLUG_INT_STATUS (1 << 28) - #define HDMID_HOTPLUG_INT_STATUS (1 << 27) - #define DPD_HOTPLUG_INT_STATUS (1 << 27) -+#define CRT_EOS_INT_STATUS (1 << 12) - #define CRT_HOTPLUG_INT_STATUS (1 << 11) - #define TV_HOTPLUG_INT_STATUS (1 << 10) - #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -@@ -1586,6 +1716,7 @@ - #define PIPECONF_PROGRESSIVE (0 << 21) - #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) - #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) -+#define PIPECONF_CXSR_DOWNCLOCK (1<<16) - #define PIPEASTAT 0x70024 - #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) - #define PIPE_CRC_ERROR_ENABLE (1UL<<29) -@@ -1733,6 +1864,7 @@ - #define DISPPLANE_NO_LINE_DOUBLE 0 - #define DISPPLANE_STEREO_POLARITY_FIRST 0 - #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) -+#define DISPPLANE_TRICKLE_FEED_DISABLE (1<<14) /* IGDNG */ - #define DISPPLANE_TILED (1<<10) - #define DSPAADDR 0x70184 - #define DSPASTRIDE 0x70188 -@@ -1913,6 +2045,9 @@ - #define GTIIR 0x44018 - #define GTIER 0x4401c - -+#define DISP_ARB_CTL 0x45000 -+#define DISP_TILE_SURFACE_SWIZZLING (1<<13) -+ - /* PCH */ - - /* south display engine interrupt */ -diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c -index 1d04e19..20d4d19 100644 ---- a/drivers/gpu/drm/i915/i915_suspend.c -+++ b/drivers/gpu/drm/i915/i915_suspend.c -@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev) - - /* Clock gating state */ - dev_priv->saveD_STATE = I915_READ(D_STATE); -- dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); -+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); - - /* Cache mode state */ - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); -@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev) - - /* Clock gating state */ - I915_WRITE (D_STATE, dev_priv->saveD_STATE); -- I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); -+ I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D); - - /* Cache mode state */ - I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); -diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c -index f806fcc..1e28c16 100644 ---- a/drivers/gpu/drm/i915/intel_bios.c -+++ b/drivers/gpu/drm/i915/intel_bios.c -@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv, - } - - driver = find_section(bdb, BDB_DRIVER_FEATURES); -- if (driver && driver->lvds_config == BDB_DRIVER_FEATURE_EDP) -+ if (!driver) -+ return; -+ -+ if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) - dev_priv->edp_support = 1; -+ -+ if (driver->dual_frequency) -+ dev_priv->render_reclock_avail = true; - } - - /** -diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c -index 590f81c..88814fa 100644 ---- a/drivers/gpu/drm/i915/intel_crt.c -+++ b/drivers/gpu/drm/i915/intel_crt.c -@@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) - } - - I915_WRITE(reg, temp); -+ -+ if (IS_IGD(dev)) { -+ if (mode == DRM_MODE_DPMS_OFF) { -+ /* turn off DAC */ -+ temp = I915_READ(PORT_HOTPLUG_EN); -+ temp &= ~CRT_EOS_INT_EN; -+ I915_WRITE(PORT_HOTPLUG_EN, temp); -+ -+ temp = I915_READ(PORT_HOTPLUG_STAT); -+ if (temp & CRT_EOS_INT_STATUS) -+ I915_WRITE(PORT_HOTPLUG_STAT, -+ CRT_EOS_INT_STATUS); -+ } else { -+ /* turn on DAC. EOS interrupt must be enabled after DAC -+ * is enabled, so it sounds not good to enable it in -+ * i915_driver_irq_postinstall() -+ * wait 12.5ms after DAC is enabled -+ */ -+ msleep(13); -+ temp = I915_READ(PORT_HOTPLUG_STAT); -+ if (temp & CRT_EOS_INT_STATUS) -+ I915_WRITE(PORT_HOTPLUG_STAT, -+ CRT_EOS_INT_STATUS); -+ temp = I915_READ(PORT_HOTPLUG_EN); -+ temp |= CRT_EOS_INT_EN; -+ I915_WRITE(PORT_HOTPLUG_EN, temp); -+ } -+ } - } - - static int intel_crt_mode_valid(struct drm_connector *connector, -diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 748ed50..155719f 100644 ---- a/drivers/gpu/drm/i915/intel_display.c -+++ b/drivers/gpu/drm/i915/intel_display.c -@@ -38,6 +38,7 @@ - - bool intel_pipe_has_type (struct drm_crtc *crtc, int type); - static void intel_update_watermarks(struct drm_device *dev); -+static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule); - - typedef struct { - /* given values */ -@@ -67,6 +68,8 @@ struct intel_limit { - intel_p2_t p2; - bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, - int, int, intel_clock_t *); -+ bool (* find_reduced_pll)(const intel_limit_t *, struct drm_crtc *, -+ int, int, intel_clock_t *); - }; - - #define I8XX_DOT_MIN 25000 -@@ -261,6 +264,9 @@ static bool - intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); - static bool -+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, -+ int target, int refclk, intel_clock_t *best_clock); -+static bool - intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); - static bool -@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = { - .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - static const intel_limit_t intel_limits_i8xx_lvds = { -@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = { - .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - static const intel_limit_t intel_limits_i9xx_sdvo = { -@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { - .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - static const intel_limit_t intel_limits_i9xx_lvds = { -@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = { - .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - /* below parameter and function is for G4X Chipset Family*/ -@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = { - .p2_fast = G4X_P2_SDVO_FAST - }, - .find_pll = intel_g4x_find_best_PLL, -+ .find_reduced_pll = intel_g4x_find_best_PLL, - }; - - static const intel_limit_t intel_limits_g4x_hdmi = { -@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = { - .p2_fast = G4X_P2_HDMI_DAC_FAST - }, - .find_pll = intel_g4x_find_best_PLL, -+ .find_reduced_pll = intel_g4x_find_best_PLL, - }; - - static const intel_limit_t intel_limits_g4x_single_channel_lvds = { -@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { - .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST - }, - .find_pll = intel_g4x_find_best_PLL, -+ .find_reduced_pll = intel_g4x_find_best_PLL, - }; - - static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { -@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { - .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST - }, - .find_pll = intel_g4x_find_best_PLL, -+ .find_reduced_pll = intel_g4x_find_best_PLL, - }; - - static const intel_limit_t intel_limits_g4x_display_port = { -@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = { - .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - static const intel_limit_t intel_limits_igd_lvds = { -@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = { - .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, - .find_pll = intel_find_best_PLL, -+ .find_reduced_pll = intel_find_best_reduced_PLL, - }; - - static const intel_limit_t intel_limits_igdng_sdvo = { -@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - - memset (best_clock, 0, sizeof (*best_clock)); - -- for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { -- for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { -- /* m1 is always 0 in IGD */ -- if (clock.m2 >= clock.m1 && !IS_IGD(dev)) -- break; -- for (clock.n = limit->n.min; clock.n <= limit->n.max; -- clock.n++) { -- for (clock.p1 = limit->p1.min; -- clock.p1 <= limit->p1.max; clock.p1++) { -+ for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { -+ for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; -+ clock.m1++) { -+ for (clock.m2 = limit->m2.min; -+ clock.m2 <= limit->m2.max; clock.m2++) { -+ /* m1 is always 0 in IGD */ -+ if (clock.m2 >= clock.m1 && !IS_IGD(dev)) -+ break; -+ for (clock.n = limit->n.min; -+ clock.n <= limit->n.max; clock.n++) { - int this_err; - - intel_clock(dev, refclk, &clock); -@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - return (err != target); - } - -+ -+static bool -+intel_find_best_reduced_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, -+ int target, int refclk, intel_clock_t *best_clock) -+ -+{ -+ struct drm_device *dev = crtc->dev; -+ intel_clock_t clock; -+ int err = target; -+ bool found = false; -+ -+ memcpy(&clock, best_clock, sizeof(intel_clock_t)); -+ -+ for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) { -+ for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) { -+ /* m1 is always 0 in IGD */ -+ if (clock.m2 >= clock.m1 && !IS_IGD(dev)) -+ break; -+ for (clock.n = limit->n.min; clock.n <= limit->n.max; -+ clock.n++) { -+ int this_err; -+ -+ intel_clock(dev, refclk, &clock); -+ -+ if (!intel_PLL_is_valid(crtc, &clock)) -+ continue; -+ -+ this_err = abs(clock.dot - target); -+ if (this_err < err) { -+ *best_clock = clock; -+ err = this_err; -+ found = true; -+ } -+ } -+ } -+ } -+ -+ return found; -+} -+ - static bool - intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) -@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - max_n = limit->n.max; - /* based on hardware requriment prefer smaller n to precision */ - for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { -- /* based on hardware requirment prefere larger m1,m2, p1 */ -+ /* based on hardware requirment prefere larger m1,m2 */ - for (clock.m1 = limit->m1.max; - clock.m1 >= limit->m1.min; clock.m1--) { - for (clock.m2 = limit->m2.max; -@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - - memset(best_clock, 0, sizeof(*best_clock)); - max_n = limit->n.max; -- /* based on hardware requriment prefer smaller n to precision */ -- for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { -- /* based on hardware requirment prefere larger m1,m2, p1 */ -- for (clock.m1 = limit->m1.max; -- clock.m1 >= limit->m1.min; clock.m1--) { -- for (clock.m2 = limit->m2.max; -- clock.m2 >= limit->m2.min; clock.m2--) { -- for (clock.p1 = limit->p1.max; -- clock.p1 >= limit->p1.min; clock.p1--) { -+ for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { -+ /* based on hardware requriment prefer smaller n to precision */ -+ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { -+ /* based on hardware requirment prefere larger m1,m2 */ -+ for (clock.m1 = limit->m1.max; -+ clock.m1 >= limit->m1.min; clock.m1--) { -+ for (clock.m2 = limit->m2.max; -+ clock.m2 >= limit->m2.min; clock.m2--) { - int this_err; - - intel_clock(dev, refclk, &clock); -@@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, - dspcntr &= ~DISPPLANE_TILED; - } - -+ if (IS_IGDNG(dev)) -+ /* must disable */ -+ dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; -+ - I915_WRITE(dspcntr_reg, dspcntr); - - Start = obj_priv->gtt_offset; -@@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, - - if (old_fb) { - intel_fb = to_intel_framebuffer(old_fb); -+ obj_priv = intel_fb->obj->driver_private; - i915_gem_object_unpin(intel_fb->obj); - } -+ intel_increase_pllclock(crtc, true); -+ - mutex_unlock(&dev->struct_mutex); - - if (!dev->primary->master) -@@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) - else - i9xx_crtc_dpms(crtc, mode); - -+ intel_crtc->dpms_mode = mode; -+ - if (!dev->primary->master) - return; - -@@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) - DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); - break; - } -- -- intel_crtc->dpms_mode = mode; - } - - static void intel_crtc_prepare (struct drm_crtc *crtc) -@@ -2054,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) - return size; - } - -+static void g4x_update_wm(struct drm_device *dev) -+{ -+ struct drm_i915_private *dev_priv = dev->dev_private; -+ u32 fw_blc_self = I915_READ(FW_BLC_SELF); -+ -+ if (i915_powersave) -+ fw_blc_self |= FW_BLC_SELF_EN; -+ else -+ fw_blc_self &= ~FW_BLC_SELF_EN; -+ I915_WRITE(FW_BLC_SELF, fw_blc_self); -+} -+ - static void i965_update_wm(struct drm_device *dev) - { - struct drm_i915_private *dev_priv = dev->dev_private; -@@ -2105,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, - cwm = 2; - - /* Calc sr entries for one plane configs */ -- if (sr_hdisplay && (!planea_clock || !planeb_clock)) { -+ if (HAS_FW_BLC(dev) && sr_hdisplay && -+ (!planea_clock || !planeb_clock)) { - /* self-refresh has much higher latency */ - const static int sr_latency_ns = 6000; - -@@ -2120,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, - srwm = total_size - sr_entries; - if (srwm < 0) - srwm = 1; -- if (IS_I9XX(dev)) -- I915_WRITE(FW_BLC_SELF, (srwm & 0x3f)); -+ I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN | (srwm & 0x3f)); - } - - DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", -@@ -2195,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev) - unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; - int enabled = 0, pixel_size = 0; - -- if (DSPARB_HWCONTROL(dev)) -- return; -- - /* Get the clock config from both planes */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - intel_crtc = to_intel_crtc(crtc); -@@ -2230,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev) - else if (IS_IGD(dev)) - igd_disable_cxsr(dev); - -- if (IS_I965G(dev)) -+ if (IS_G4X(dev)) -+ g4x_update_wm(dev); -+ else if (IS_I965G(dev)) - i965_update_wm(dev); - else if (IS_I9XX(dev) || IS_MOBILE(dev)) - i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, -@@ -2264,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk, num_outputs = 0; -- intel_clock_t clock; -- u32 dpll = 0, fp = 0, dspcntr, pipeconf; -- bool ok, is_sdvo = false, is_dvo = false; -+ intel_clock_t clock, reduced_clock; -+ u32 dpll = 0, fp = 0, fp2 = 0, dspcntr, pipeconf; -+ bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; - bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; - bool is_edp = false; - struct drm_mode_config *mode_config = &dev->mode_config; -@@ -2349,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - return -EINVAL; - } - -+ if (limit->find_reduced_pll && dev_priv->lvds_downclock_avail) { -+ memcpy(&reduced_clock, &clock, sizeof(intel_clock_t)); -+ has_reduced_clock = limit->find_reduced_pll(limit, crtc, -+ (adjusted_mode->clock*3/4), -+ refclk, -+ &reduced_clock); -+ } -+ - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { -@@ -2394,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - link_bw, &m_n); - } - -- if (IS_IGD(dev)) -+ if (IS_IGD(dev)) { - fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; -- else -+ if (has_reduced_clock) -+ fp2 = (1 << reduced_clock.n) << 16 | -+ reduced_clock.m1 << 8 | reduced_clock.m2; -+ } else { - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; -+ if (has_reduced_clock) -+ fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | -+ reduced_clock.m2; -+ } - - if (!IS_IGDNG(dev)) - dpll = DPLL_VGA_MODE_DIS; -@@ -2426,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - /* also FPA1 */ - if (IS_IGDNG(dev)) - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; -+ if (IS_G4X(dev) && has_reduced_clock) -+ dpll |= (1 << (reduced_clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - } - switch (clock.p2) { - case 5: -@@ -2573,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - udelay(150); - } - -+ if (is_lvds && has_reduced_clock && i915_powersave) { -+ I915_WRITE(fp_reg + 4, fp2); -+ intel_crtc->lowfreq_avail = true; -+ if (HAS_PIPE_CXSR(dev)) { -+ DRM_DEBUG("enabling CxSR downclocking\n"); -+ pipeconf |= PIPECONF_CXSR_DOWNCLOCK; -+ } -+ } else { -+ I915_WRITE(fp_reg + 4, fp); -+ intel_crtc->lowfreq_avail = false; -+ if (HAS_PIPE_CXSR(dev)) { -+ DRM_DEBUG("disabling CxSR downclocking\n"); -+ pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; -+ } -+ } -+ - I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | - ((adjusted_mode->crtc_htotal - 1) << 16)); - I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | -@@ -2616,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - - intel_wait_for_vblank(dev); - -+ if (IS_IGDNG(dev)) { -+ /* enable address swizzle for tiling buffer */ -+ temp = I915_READ(DISP_ARB_CTL); -+ I915_WRITE(DISP_ARB_CTL, temp | DISP_TILE_SURFACE_SWIZZLING); -+ } -+ - I915_WRITE(dspcntr_reg, dspcntr); - - /* Flush the plane changes */ -@@ -2769,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ struct intel_framebuffer *intel_fb; - int pipe = intel_crtc->pipe; - uint32_t temp = 0; - uint32_t adder; - -+ if (crtc->fb) { -+ intel_fb = to_intel_framebuffer(crtc->fb); -+ intel_mark_busy(dev, intel_fb->obj); -+ } -+ - if (x < 0) { - temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; -@@ -3070,12 +3189,319 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, - return mode; - } - -+#define GPU_IDLE_TIMEOUT 500 /* ms */ -+ -+/* When this timer fires, we've been idle for awhile */ -+static void intel_gpu_idle_timer(unsigned long arg) -+{ -+ struct drm_device *dev = (struct drm_device *)arg; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ DRM_DEBUG("idle timer fired, downclocking\n"); -+ -+ dev_priv->busy = false; -+ -+ queue_work(dev_priv->wq, &dev_priv->idle_work); -+} -+ -+void intel_increase_renderclock(struct drm_device *dev, bool schedule) -+{ -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ if (IS_IGDNG(dev)) -+ return; -+ -+ if (!dev_priv->render_reclock_avail) { -+ DRM_DEBUG("not reclocking render clock\n"); -+ return; -+ } -+ -+ /* Restore render clock frequency to original value */ -+ if (IS_G4X(dev) || IS_I9XX(dev)) -+ pci_write_config_word(dev->pdev, GCFGC, dev_priv->orig_clock); -+ else if (IS_I85X(dev)) -+ pci_write_config_word(dev->pdev, HPLLCC, dev_priv->orig_clock); -+ DRM_DEBUG("increasing render clock frequency\n"); -+ -+ /* Schedule downclock */ -+ if (schedule) -+ mod_timer(&dev_priv->idle_timer, jiffies + -+ msecs_to_jiffies(GPU_IDLE_TIMEOUT)); -+} -+ -+void intel_decrease_renderclock(struct drm_device *dev) -+{ -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ -+ if (IS_IGDNG(dev)) -+ return; -+ -+ if (!dev_priv->render_reclock_avail) { -+ DRM_DEBUG("not reclocking render clock\n"); -+ return; -+ } -+ -+ if (IS_G4X(dev)) { -+ u16 gcfgc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); -+ -+ /* Down to minimum... */ -+ gcfgc &= ~GM45_GC_RENDER_CLOCK_MASK; -+ gcfgc |= GM45_GC_RENDER_CLOCK_266_MHZ; -+ -+ pci_write_config_word(dev->pdev, GCFGC, gcfgc); -+ } else if (IS_I965G(dev)) { -+ u16 gcfgc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); -+ -+ /* Down to minimum... */ -+ gcfgc &= ~I965_GC_RENDER_CLOCK_MASK; -+ gcfgc |= I965_GC_RENDER_CLOCK_267_MHZ; -+ -+ pci_write_config_word(dev->pdev, GCFGC, gcfgc); -+ } else if (IS_I945G(dev) || IS_I945GM(dev)) { -+ u16 gcfgc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); -+ -+ /* Down to minimum... */ -+ gcfgc &= ~I945_GC_RENDER_CLOCK_MASK; -+ gcfgc |= I945_GC_RENDER_CLOCK_166_MHZ; -+ -+ pci_write_config_word(dev->pdev, GCFGC, gcfgc); -+ } else if (IS_I915G(dev)) { -+ u16 gcfgc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); -+ -+ /* Down to minimum... */ -+ gcfgc &= ~I915_GC_RENDER_CLOCK_MASK; -+ gcfgc |= I915_GC_RENDER_CLOCK_166_MHZ; -+ -+ pci_write_config_word(dev->pdev, GCFGC, gcfgc); -+ } else if (IS_I85X(dev)) { -+ u16 hpllcc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, HPLLCC, &hpllcc); -+ -+ /* Up to maximum... */ -+ hpllcc &= ~GC_CLOCK_CONTROL_MASK; -+ hpllcc |= GC_CLOCK_133_200; -+ -+ pci_write_config_word(dev->pdev, HPLLCC, hpllcc); -+ } -+ DRM_DEBUG("decreasing render clock frequency\n"); -+} -+ -+/* Note that no increase function is needed for this - increase_renderclock() -+ * will also rewrite these bits -+ */ -+void intel_decrease_displayclock(struct drm_device *dev) -+{ -+ if (IS_IGDNG(dev)) -+ return; -+ -+ if (IS_I945G(dev) || IS_I945GM(dev) || IS_I915G(dev) || -+ IS_I915GM(dev)) { -+ u16 gcfgc; -+ -+ /* Adjust render clock... */ -+ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); -+ -+ /* Down to minimum... */ -+ gcfgc &= ~0xf0; -+ gcfgc |= 0x80; -+ -+ pci_write_config_word(dev->pdev, GCFGC, gcfgc); -+ } -+} -+ -+#define CRTC_IDLE_TIMEOUT 1000 /* ms */ -+ -+static void intel_crtc_idle_timer(unsigned long arg) -+{ -+ struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; -+ struct drm_crtc *crtc = &intel_crtc->base; -+ drm_i915_private_t *dev_priv = crtc->dev->dev_private; -+ -+ DRM_DEBUG("idle timer fired, downclocking\n"); -+ -+ intel_crtc->busy = false; -+ -+ queue_work(dev_priv->wq, &dev_priv->idle_work); -+} -+ -+static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) -+{ -+ struct drm_device *dev = crtc->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ int pipe = intel_crtc->pipe; -+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; -+ int dpll = I915_READ(dpll_reg); -+ -+ if (IS_IGDNG(dev)) -+ return; -+ -+ if (!dev_priv->lvds_downclock_avail) -+ return; -+ -+ if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { -+ DRM_DEBUG("upclocking LVDS\n"); -+ -+ /* Unlock panel regs */ -+ I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); -+ -+ dpll &= ~DISPLAY_RATE_SELECT_FPA1; -+ I915_WRITE(dpll_reg, dpll); -+ dpll = I915_READ(dpll_reg); -+ intel_wait_for_vblank(dev); -+ dpll = I915_READ(dpll_reg); -+ if (dpll & DISPLAY_RATE_SELECT_FPA1) -+ DRM_DEBUG("failed to upclock LVDS!\n"); -+ -+ /* ...and lock them again */ -+ I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); -+ } -+ -+ /* Schedule downclock */ -+ if (schedule) -+ mod_timer(&intel_crtc->idle_timer, jiffies + -+ msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); -+} -+ -+static void intel_decrease_pllclock(struct drm_crtc *crtc) -+{ -+ struct drm_device *dev = crtc->dev; -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -+ int pipe = intel_crtc->pipe; -+ int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; -+ int dpll = I915_READ(dpll_reg); -+ -+ if (IS_IGDNG(dev)) -+ return; -+ -+ if (!dev_priv->lvds_downclock_avail) -+ return; -+ -+ /* -+ * Since this is called by a timer, we should never get here in -+ * the manual case. -+ */ -+ if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { -+ DRM_DEBUG("downclocking LVDS\n"); -+ -+ /* Unlock panel regs */ -+ I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) | (0xabcd << 16)); -+ -+ dpll |= DISPLAY_RATE_SELECT_FPA1; -+ I915_WRITE(dpll_reg, dpll); -+ dpll = I915_READ(dpll_reg); -+ intel_wait_for_vblank(dev); -+ dpll = I915_READ(dpll_reg); -+ if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) -+ DRM_DEBUG("failed to downclock LVDS!\n"); -+ -+ /* ...and lock them again */ -+ I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) & 0x3); -+ } -+ -+} -+ -+/** -+ * intel_idle_update - adjust clocks for idleness -+ * @work: work struct -+ * -+ * Either the GPU or display (or both) went idle. Check the busy status -+ * here and adjust the CRTC and GPU clocks as necessary. -+ */ -+static void intel_idle_update(struct work_struct *work) -+{ -+ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, -+ idle_work); -+ struct drm_device *dev = dev_priv->dev; -+ struct drm_crtc *crtc; -+ struct intel_crtc *intel_crtc; -+ -+ if (!i915_powersave) -+ return; -+ -+ mutex_lock(&dev->struct_mutex); -+ -+ /* GPU isn't processing, downclock it. */ -+ if (!dev_priv->busy) { -+ intel_decrease_renderclock(dev); -+ intel_decrease_displayclock(dev); -+ } -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ /* Skip inactive CRTCs */ -+ if (!crtc->fb) -+ continue; -+ -+ intel_crtc = to_intel_crtc(crtc); -+ if (!intel_crtc->busy) -+ intel_decrease_pllclock(crtc); -+ } -+ -+ mutex_unlock(&dev->struct_mutex); -+} -+ -+/** -+ * intel_mark_busy - mark the GPU and possibly the display busy -+ * @dev: drm device -+ * @obj: object we're operating on -+ * -+ * Callers can use this function to indicate that the GPU is busy processing -+ * commands. If @obj matches one of the CRTC objects (i.e. it's a scanout -+ * buffer), we'll also mark the display as busy, so we know to increase its -+ * clock frequency. -+ */ -+void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) -+{ -+ drm_i915_private_t *dev_priv = dev->dev_private; -+ struct drm_crtc *crtc = NULL; -+ struct intel_framebuffer *intel_fb; -+ struct intel_crtc *intel_crtc; -+ -+ if (!drm_core_check_feature(dev, DRIVER_MODESET)) -+ return; -+ -+ dev_priv->busy = true; -+ intel_increase_renderclock(dev, true); -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ if (!crtc->fb) -+ continue; -+ -+ intel_crtc = to_intel_crtc(crtc); -+ intel_fb = to_intel_framebuffer(crtc->fb); -+ if (intel_fb->obj == obj) { -+ if (!intel_crtc->busy) { -+ /* Non-busy -> busy, upclock */ -+ intel_increase_pllclock(crtc, true); -+ intel_crtc->busy = true; -+ } else { -+ /* Busy -> busy, put off timer */ -+ mod_timer(&intel_crtc->idle_timer, jiffies + -+ msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); -+ } -+ } -+ } -+} -+ - static void intel_crtc_destroy(struct drm_crtc *crtc) - { - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - -- if (intel_crtc->mode_set.mode) -- drm_mode_destroy(crtc->dev, intel_crtc->mode_set.mode); - drm_crtc_cleanup(crtc); - kfree(intel_crtc); - } -@@ -3122,15 +3548,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) - intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; - drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); - -- intel_crtc->mode_set.crtc = &intel_crtc->base; -- intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1); -- intel_crtc->mode_set.num_connectors = 0; -- -- if (i915_fbpercrtc) { -- -+ intel_crtc->busy = false; - -- -- } -+ setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, -+ (unsigned long)intel_crtc); - } - - int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, -@@ -3138,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - { - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; -- struct drm_crtc *crtc = NULL; -- int pipe = -1; -+ struct drm_mode_object *drmmode_obj; -+ struct intel_crtc *crtc; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -- if (crtc->base.id == pipe_from_crtc_id->crtc_id) { -- pipe = intel_crtc->pipe; -- break; -- } -- } -+ drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, -+ DRM_MODE_OBJECT_CRTC); - -- if (pipe == -1) { -+ if (!drmmode_obj) { - DRM_ERROR("no such CRTC id\n"); - return -EINVAL; - } - -- pipe_from_crtc_id->pipe = pipe; -+ crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); -+ pipe_from_crtc_id->pipe = crtc->pipe; - -- return 0; -+ return 0; - } - - struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) -@@ -3362,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { - .fb_changed = intelfb_probe, - }; - -+void intel_init_clock_gating(struct drm_device *dev) -+{ -+ struct drm_i915_private *dev_priv = dev->dev_private; -+ -+ /* -+ * Disable clock gating reported to work incorrectly according to the -+ * specs, but enable as much else as we can. -+ */ -+ if (IS_G4X(dev)) { -+ uint32_t dspclk_gate; -+ I915_WRITE(RENCLK_GATE_D1, 0); -+ I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | -+ GS_UNIT_CLOCK_GATE_DISABLE | -+ CL_UNIT_CLOCK_GATE_DISABLE); -+ I915_WRITE(RAMCLK_GATE_D, 0); -+ dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | -+ OVRUNIT_CLOCK_GATE_DISABLE | -+ OVCUNIT_CLOCK_GATE_DISABLE; -+ if (IS_GM45(dev)) -+ dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; -+ I915_WRITE(DSPCLK_GATE_D, dspclk_gate); -+ } else if (IS_I965GM(dev)) { -+ I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); -+ I915_WRITE(RENCLK_GATE_D2, 0); -+ I915_WRITE(DSPCLK_GATE_D, 0); -+ I915_WRITE(RAMCLK_GATE_D, 0); -+ I915_WRITE16(DEUC, 0); -+ } else if (IS_I965G(dev)) { -+ I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | -+ I965_RCC_CLOCK_GATE_DISABLE | -+ I965_RCPB_CLOCK_GATE_DISABLE | -+ I965_ISC_CLOCK_GATE_DISABLE | -+ I965_FBC_CLOCK_GATE_DISABLE); -+ I915_WRITE(RENCLK_GATE_D2, 0); -+ } else if (IS_I9XX(dev)) { -+ u32 dstate = I915_READ(D_STATE); -+ -+ dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | -+ DSTATE_DOT_CLOCK_GATING; -+ I915_WRITE(D_STATE, dstate); -+ } else if (IS_I855(dev) || IS_I865G(dev)) { -+ I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); -+ } else if (IS_I830(dev)) { -+ I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); -+ } -+} -+ - void intel_modeset_init(struct drm_device *dev) - { -+ struct drm_i915_private *dev_priv = dev->dev_private; - int num_pipe; - int i; - -@@ -3398,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev) - DRM_DEBUG("%d display pipe%s available.\n", - num_pipe, num_pipe > 1 ? "s" : ""); - -+ if (IS_I85X(dev)) -+ pci_read_config_word(dev->pdev, HPLLCC, &dev_priv->orig_clock); -+ else if (IS_I9XX(dev) || IS_G4X(dev)) -+ pci_read_config_word(dev->pdev, GCFGC, &dev_priv->orig_clock); -+ - for (i = 0; i < num_pipe; i++) { - intel_crtc_init(dev, i); - } - - intel_setup_outputs(dev); -+ -+ intel_init_clock_gating(dev); -+ -+ INIT_WORK(&dev_priv->idle_work, intel_idle_update); -+ setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, -+ (unsigned long)dev); - } - - void intel_modeset_cleanup(struct drm_device *dev) - { -+ struct drm_i915_private *dev_priv = dev->dev_private; -+ struct drm_crtc *crtc; -+ struct intel_crtc *intel_crtc; -+ -+ mutex_lock(&dev->struct_mutex); -+ -+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -+ /* Skip inactive CRTCs */ -+ if (!crtc->fb) -+ continue; -+ -+ intel_crtc = to_intel_crtc(crtc); -+ intel_increase_pllclock(crtc, false); -+ del_timer_sync(&intel_crtc->idle_timer); -+ } -+ -+ intel_increase_renderclock(dev, false); -+ del_timer_sync(&dev_priv->idle_timer); -+ -+ mutex_unlock(&dev->struct_mutex); -+ - drm_mode_config_cleanup(dev); - } - -diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h -index 25aa6fa..b9e47f1 100644 ---- a/drivers/gpu/drm/i915/intel_drv.h -+++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -116,9 +116,9 @@ struct intel_crtc { - uint32_t cursor_addr; - u8 lut_r[256], lut_g[256], lut_b[256]; - int dpms_mode; -- struct intel_framebuffer *fbdev_fb; -- /* a mode_set for fbdev users on this crtc */ -- struct drm_mode_set mode_set; -+ bool busy; /* is scanout buffer being updated frequently? */ -+ struct timer_list idle_timer; -+ bool lowfreq_avail; - }; - - #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -@@ -137,6 +137,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); - extern bool intel_sdvo_init(struct drm_device *dev, int output_device); - extern void intel_dvo_init(struct drm_device *dev); - extern void intel_tv_init(struct drm_device *dev); -+extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj); - extern void intel_lvds_init(struct drm_device *dev); - extern void intel_dp_init(struct drm_device *dev, int dp_reg); - void -diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c -index 1d30802..7ba4a23 100644 ---- a/drivers/gpu/drm/i915/intel_fb.c -+++ b/drivers/gpu/drm/i915/intel_fb.c -@@ -39,339 +39,34 @@ - #include "drmP.h" - #include "drm.h" - #include "drm_crtc.h" -+#include "drm_fb_helper.h" - #include "intel_drv.h" - #include "i915_drm.h" - #include "i915_drv.h" - - struct intelfb_par { -- struct drm_device *dev; -- struct drm_display_mode *our_mode; -+ struct drm_fb_helper helper; - struct intel_framebuffer *intel_fb; -- int crtc_count; -- /* crtc currently bound to this */ -- uint32_t crtc_ids[2]; -+ struct drm_display_mode *our_mode; - }; - --static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, -- unsigned blue, unsigned transp, -- struct fb_info *info) --{ -- struct intelfb_par *par = info->par; -- struct drm_device *dev = par->dev; -- struct drm_crtc *crtc; -- int i; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -- struct drm_mode_set *modeset = &intel_crtc->mode_set; -- struct drm_framebuffer *fb = modeset->fb; -- -- for (i = 0; i < par->crtc_count; i++) -- if (crtc->base.id == par->crtc_ids[i]) -- break; -- -- if (i == par->crtc_count) -- continue; -- -- -- if (regno > 255) -- return 1; -- -- if (fb->depth == 8) { -- intel_crtc_fb_gamma_set(crtc, red, green, blue, regno); -- return 0; -- } -- -- if (regno < 16) { -- switch (fb->depth) { -- case 15: -- fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | -- ((green & 0xf800) >> 6) | -- ((blue & 0xf800) >> 11); -- break; -- case 16: -- fb->pseudo_palette[regno] = (red & 0xf800) | -- ((green & 0xfc00) >> 5) | -- ((blue & 0xf800) >> 11); -- break; -- case 24: -- case 32: -- fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | -- (green & 0xff00) | -- ((blue & 0xff00) >> 8); -- break; -- } -- } -- } -- return 0; --} -- --static int intelfb_check_var(struct fb_var_screeninfo *var, -- struct fb_info *info) --{ -- struct intelfb_par *par = info->par; -- struct intel_framebuffer *intel_fb = par->intel_fb; -- struct drm_framebuffer *fb = &intel_fb->base; -- int depth; -- -- if (var->pixclock == -1 || !var->pixclock) -- return -EINVAL; -- -- /* Need to resize the fb object !!! */ -- if (var->xres > fb->width || var->yres > fb->height) { -- DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height); -- DRM_ERROR("Need resizing code.\n"); -- return -EINVAL; -- } -- -- switch (var->bits_per_pixel) { -- case 16: -- depth = (var->green.length == 6) ? 16 : 15; -- break; -- case 32: -- depth = (var->transp.length > 0) ? 32 : 24; -- break; -- default: -- depth = var->bits_per_pixel; -- break; -- } -- -- switch (depth) { -- case 8: -- var->red.offset = 0; -- var->green.offset = 0; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 15: -- var->red.offset = 10; -- var->green.offset = 5; -- var->blue.offset = 0; -- var->red.length = 5; -- var->green.length = 5; -- var->blue.length = 5; -- var->transp.length = 1; -- var->transp.offset = 15; -- break; -- case 16: -- var->red.offset = 11; -- var->green.offset = 5; -- var->blue.offset = 0; -- var->red.length = 5; -- var->green.length = 6; -- var->blue.length = 5; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 24: -- var->red.offset = 16; -- var->green.offset = 8; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 32: -- var->red.offset = 16; -- var->green.offset = 8; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 8; -- var->transp.offset = 24; -- break; -- default: -- return -EINVAL; -- } -- -- return 0; --} -- --/* this will let fbcon do the mode init */ --/* FIXME: take mode config lock? */ --static int intelfb_set_par(struct fb_info *info) --{ -- struct intelfb_par *par = info->par; -- struct drm_device *dev = par->dev; -- struct fb_var_screeninfo *var = &info->var; -- int i; -- -- DRM_DEBUG("%d %d\n", var->xres, var->pixclock); -- -- if (var->pixclock != -1) { -- -- DRM_ERROR("PIXEL CLOCK SET\n"); -- return -EINVAL; -- } else { -- struct drm_crtc *crtc; -- int ret; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -- -- for (i = 0; i < par->crtc_count; i++) -- if (crtc->base.id == par->crtc_ids[i]) -- break; -- -- if (i == par->crtc_count) -- continue; -- -- if (crtc->fb == intel_crtc->mode_set.fb) { -- mutex_lock(&dev->mode_config.mutex); -- ret = crtc->funcs->set_config(&intel_crtc->mode_set); -- mutex_unlock(&dev->mode_config.mutex); -- if (ret) -- return ret; -- } -- } -- return 0; -- } --} -- --static int intelfb_pan_display(struct fb_var_screeninfo *var, -- struct fb_info *info) --{ -- struct intelfb_par *par = info->par; -- struct drm_device *dev = par->dev; -- struct drm_mode_set *modeset; -- struct drm_crtc *crtc; -- struct intel_crtc *intel_crtc; -- int ret = 0; -- int i; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- for (i = 0; i < par->crtc_count; i++) -- if (crtc->base.id == par->crtc_ids[i]) -- break; -- -- if (i == par->crtc_count) -- continue; -- -- intel_crtc = to_intel_crtc(crtc); -- modeset = &intel_crtc->mode_set; -- -- modeset->x = var->xoffset; -- modeset->y = var->yoffset; -- -- if (modeset->num_connectors) { -- mutex_lock(&dev->mode_config.mutex); -- ret = crtc->funcs->set_config(modeset); -- mutex_unlock(&dev->mode_config.mutex); -- if (!ret) { -- info->var.xoffset = var->xoffset; -- info->var.yoffset = var->yoffset; -- } -- } -- } -- -- return ret; --} -- --static void intelfb_on(struct fb_info *info) --{ -- struct intelfb_par *par = info->par; -- struct drm_device *dev = par->dev; -- struct drm_crtc *crtc; -- struct drm_encoder *encoder; -- int i; -- -- /* -- * For each CRTC in this fb, find all associated encoders -- * and turn them off, then turn off the CRTC. -- */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -- -- for (i = 0; i < par->crtc_count; i++) -- if (crtc->base.id == par->crtc_ids[i]) -- break; -- -- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -- -- /* Found a CRTC on this fb, now find encoders */ -- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -- if (encoder->crtc == crtc) { -- struct drm_encoder_helper_funcs *encoder_funcs; -- encoder_funcs = encoder->helper_private; -- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); -- } -- } -- } --} -- --static void intelfb_off(struct fb_info *info, int dpms_mode) --{ -- struct intelfb_par *par = info->par; -- struct drm_device *dev = par->dev; -- struct drm_crtc *crtc; -- struct drm_encoder *encoder; -- int i; -- -- /* -- * For each CRTC in this fb, find all associated encoders -- * and turn them off, then turn off the CRTC. -- */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -- -- for (i = 0; i < par->crtc_count; i++) -- if (crtc->base.id == par->crtc_ids[i]) -- break; -- -- /* Found a CRTC on this fb, now find encoders */ -- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -- if (encoder->crtc == crtc) { -- struct drm_encoder_helper_funcs *encoder_funcs; -- encoder_funcs = encoder->helper_private; -- encoder_funcs->dpms(encoder, dpms_mode); -- } -- } -- if (dpms_mode == DRM_MODE_DPMS_OFF) -- crtc_funcs->dpms(crtc, dpms_mode); -- } --} -- --static int intelfb_blank(int blank, struct fb_info *info) --{ -- switch (blank) { -- case FB_BLANK_UNBLANK: -- intelfb_on(info); -- break; -- case FB_BLANK_NORMAL: -- intelfb_off(info, DRM_MODE_DPMS_STANDBY); -- break; -- case FB_BLANK_HSYNC_SUSPEND: -- intelfb_off(info, DRM_MODE_DPMS_STANDBY); -- break; -- case FB_BLANK_VSYNC_SUSPEND: -- intelfb_off(info, DRM_MODE_DPMS_SUSPEND); -- break; -- case FB_BLANK_POWERDOWN: -- intelfb_off(info, DRM_MODE_DPMS_OFF); -- break; -- } -- return 0; --} -- - static struct fb_ops intelfb_ops = { - .owner = THIS_MODULE, -- .fb_check_var = intelfb_check_var, -- .fb_set_par = intelfb_set_par, -- .fb_setcolreg = intelfb_setcolreg, -+ .fb_check_var = drm_fb_helper_check_var, -+ .fb_set_par = drm_fb_helper_set_par, -+ .fb_setcolreg = drm_fb_helper_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -- .fb_pan_display = intelfb_pan_display, -- .fb_blank = intelfb_blank, -+ .fb_pan_display = drm_fb_helper_pan_display, -+ .fb_blank = drm_fb_helper_blank, - }; - -+static struct drm_fb_helper_funcs intel_fb_helper_funcs = { -+ .gamma_set = intel_crtc_fb_gamma_set, -+}; -+ -+ - /** - * Curretly it is assumed that the old framebuffer is reused. - * -@@ -412,25 +107,10 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc) - } - EXPORT_SYMBOL(intelfb_resize); - --static struct drm_mode_set kernelfb_mode; -- --static int intelfb_panic(struct notifier_block *n, unsigned long ununsed, -- void *panic_str) --{ -- DRM_ERROR("panic occurred, switching back to text console\n"); -- -- intelfb_restore(); -- return 0; --} -- --static struct notifier_block paniced = { -- .notifier_call = intelfb_panic, --}; -- - static int intelfb_create(struct drm_device *dev, uint32_t fb_width, - uint32_t fb_height, uint32_t surface_width, - uint32_t surface_height, -- struct intel_framebuffer **intel_fb_p) -+ struct drm_framebuffer **fb_p) - { - struct fb_info *info; - struct intelfb_par *par; -@@ -479,7 +159,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, - list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list); - - intel_fb = to_intel_framebuffer(fb); -- *intel_fb_p = intel_fb; -+ *fb_p = fb; - - info = framebuffer_alloc(sizeof(struct intelfb_par), device); - if (!info) { -@@ -489,21 +169,19 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, - - par = info->par; - -+ par->helper.funcs = &intel_fb_helper_funcs; -+ par->helper.dev = dev; -+ ret = drm_fb_helper_init_crtc_count(&par->helper, 2, -+ INTELFB_CONN_LIMIT); -+ if (ret) -+ goto out_unref; -+ - strcpy(info->fix.id, "inteldrmfb"); -- info->fix.type = FB_TYPE_PACKED_PIXELS; -- info->fix.visual = FB_VISUAL_TRUECOLOR; -- info->fix.type_aux = 0; -- info->fix.xpanstep = 1; /* doing it in hw */ -- info->fix.ypanstep = 1; /* doing it in hw */ -- info->fix.ywrapstep = 0; -- info->fix.accel = FB_ACCEL_I830; -- info->fix.type_aux = 0; - - info->flags = FBINFO_DEFAULT; - - info->fbops = &intelfb_ops; - -- info->fix.line_length = fb->pitch; - - /* setup aperture base/size for vesafb takeover */ - info->aperture_base = dev->mode_config.fb_base; -@@ -527,18 +205,8 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, - - // memset(info->screen_base, 0, size); - -- info->pseudo_palette = fb->pseudo_palette; -- info->var.xres_virtual = fb->width; -- info->var.yres_virtual = fb->height; -- info->var.bits_per_pixel = fb->bits_per_pixel; -- info->var.xoffset = 0; -- info->var.yoffset = 0; -- info->var.activate = FB_ACTIVATE_NOW; -- info->var.height = -1; -- info->var.width = -1; -- -- info->var.xres = fb_width; -- info->var.yres = fb_height; -+ drm_fb_helper_fill_fix(info, fb->pitch); -+ drm_fb_helper_fill_var(info, fb, fb_width, fb_height); - - /* FIXME: we really shouldn't expose mmio space at all */ - info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar); -@@ -550,64 +218,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, - info->pixmap.flags = FB_PIXMAP_SYSTEM; - info->pixmap.scan_align = 1; - -- switch(fb->depth) { -- case 8: -- info->var.red.offset = 0; -- info->var.green.offset = 0; -- info->var.blue.offset = 0; -- info->var.red.length = 8; /* 8bit DAC */ -- info->var.green.length = 8; -- info->var.blue.length = 8; -- info->var.transp.offset = 0; -- info->var.transp.length = 0; -- break; -- case 15: -- info->var.red.offset = 10; -- info->var.green.offset = 5; -- info->var.blue.offset = 0; -- info->var.red.length = 5; -- info->var.green.length = 5; -- info->var.blue.length = 5; -- info->var.transp.offset = 15; -- info->var.transp.length = 1; -- break; -- case 16: -- info->var.red.offset = 11; -- info->var.green.offset = 5; -- info->var.blue.offset = 0; -- info->var.red.length = 5; -- info->var.green.length = 6; -- info->var.blue.length = 5; -- info->var.transp.offset = 0; -- break; -- case 24: -- info->var.red.offset = 16; -- info->var.green.offset = 8; -- info->var.blue.offset = 0; -- info->var.red.length = 8; -- info->var.green.length = 8; -- info->var.blue.length = 8; -- info->var.transp.offset = 0; -- info->var.transp.length = 0; -- break; -- case 32: -- info->var.red.offset = 16; -- info->var.green.offset = 8; -- info->var.blue.offset = 0; -- info->var.red.length = 8; -- info->var.green.length = 8; -- info->var.blue.length = 8; -- info->var.transp.offset = 24; -- info->var.transp.length = 8; -- break; -- default: -- break; -- } -- - fb->fbdev = info; - - par->intel_fb = intel_fb; -- par->dev = dev; - - /* To allow resizeing without swapping buffers */ - DRM_DEBUG("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width, -@@ -625,307 +238,12 @@ out: - return ret; - } - --static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc) --{ -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -- struct intel_framebuffer *intel_fb; -- struct drm_framebuffer *fb; -- struct drm_connector *connector; -- struct fb_info *info; -- struct intelfb_par *par; -- struct drm_mode_set *modeset; -- unsigned int width, height; -- int new_fb = 0; -- int ret, i, conn_count; -- -- if (!drm_helper_crtc_in_use(crtc)) -- return 0; -- -- if (!crtc->desired_mode) -- return 0; -- -- width = crtc->desired_mode->hdisplay; -- height = crtc->desired_mode->vdisplay; -- -- /* is there an fb bound to this crtc already */ -- if (!intel_crtc->mode_set.fb) { -- ret = intelfb_create(dev, width, height, width, height, &intel_fb); -- if (ret) -- return -EINVAL; -- new_fb = 1; -- } else { -- fb = intel_crtc->mode_set.fb; -- intel_fb = to_intel_framebuffer(fb); -- if ((intel_fb->base.width < width) || (intel_fb->base.height < height)) -- return -EINVAL; -- } -- -- info = intel_fb->base.fbdev; -- par = info->par; -- -- modeset = &intel_crtc->mode_set; -- modeset->fb = &intel_fb->base; -- conn_count = 0; -- list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -- if (connector->encoder) -- if (connector->encoder->crtc == modeset->crtc) { -- modeset->connectors[conn_count] = connector; -- conn_count++; -- if (conn_count > INTELFB_CONN_LIMIT) -- BUG(); -- } -- } -- -- for (i = conn_count; i < INTELFB_CONN_LIMIT; i++) -- modeset->connectors[i] = NULL; -- -- par->crtc_ids[0] = crtc->base.id; -- -- modeset->num_connectors = conn_count; -- if (modeset->crtc->desired_mode) { -- if (modeset->mode) -- drm_mode_destroy(dev, modeset->mode); -- modeset->mode = drm_mode_duplicate(dev, -- modeset->crtc->desired_mode); -- } -- -- par->crtc_count = 1; -- -- if (new_fb) { -- info->var.pixclock = -1; -- if (register_framebuffer(info) < 0) -- return -EINVAL; -- } else -- intelfb_set_par(info); -- -- DRM_INFO("fb%d: %s frame buffer device\n", info->node, -- info->fix.id); -- -- /* Switch back to kernel console on panic */ -- kernelfb_mode = *modeset; -- atomic_notifier_chain_register(&panic_notifier_list, &paniced); -- DRM_DEBUG("registered panic notifier\n"); -- -- return 0; --} -- --static int intelfb_multi_fb_probe(struct drm_device *dev) --{ -- -- struct drm_crtc *crtc; -- int ret = 0; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- ret = intelfb_multi_fb_probe_crtc(dev, crtc); -- if (ret) -- return ret; -- } -- return ret; --} -- --static int intelfb_single_fb_probe(struct drm_device *dev) --{ -- struct drm_crtc *crtc; -- struct drm_connector *connector; -- unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; -- unsigned int surface_width = 0, surface_height = 0; -- int new_fb = 0; -- int crtc_count = 0; -- int ret, i, conn_count = 0; -- struct intel_framebuffer *intel_fb; -- struct fb_info *info; -- struct intelfb_par *par; -- struct drm_mode_set *modeset = NULL; -- -- DRM_DEBUG("\n"); -- -- /* Get a count of crtcs now in use and new min/maxes width/heights */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- if (!drm_helper_crtc_in_use(crtc)) -- continue; -- -- crtc_count++; -- if (!crtc->desired_mode) -- continue; -- -- /* Smallest mode determines console size... */ -- if (crtc->desired_mode->hdisplay < fb_width) -- fb_width = crtc->desired_mode->hdisplay; -- -- if (crtc->desired_mode->vdisplay < fb_height) -- fb_height = crtc->desired_mode->vdisplay; -- -- /* ... but largest for memory allocation dimensions */ -- if (crtc->desired_mode->hdisplay > surface_width) -- surface_width = crtc->desired_mode->hdisplay; -- -- if (crtc->desired_mode->vdisplay > surface_height) -- surface_height = crtc->desired_mode->vdisplay; -- } -- -- if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { -- /* hmm everyone went away - assume VGA cable just fell out -- and will come back later. */ -- DRM_DEBUG("no CRTCs available?\n"); -- return 0; -- } -- --//fail -- /* Find the fb for our new config */ -- if (list_empty(&dev->mode_config.fb_kernel_list)) { -- DRM_DEBUG("creating new fb (console size %dx%d, " -- "buffer size %dx%d)\n", fb_width, fb_height, -- surface_width, surface_height); -- ret = intelfb_create(dev, fb_width, fb_height, surface_width, -- surface_height, &intel_fb); -- if (ret) -- return -EINVAL; -- new_fb = 1; -- } else { -- struct drm_framebuffer *fb; -- -- fb = list_first_entry(&dev->mode_config.fb_kernel_list, -- struct drm_framebuffer, filp_head); -- intel_fb = to_intel_framebuffer(fb); -- -- /* if someone hotplugs something bigger than we have already -- * allocated, we are pwned. As really we can't resize an -- * fbdev that is in the wild currently due to fbdev not really -- * being designed for the lower layers moving stuff around -- * under it. -- * - so in the grand style of things - punt. -- */ -- if ((fb->width < surface_width) || -- (fb->height < surface_height)) { -- DRM_ERROR("fb not large enough for console\n"); -- return -EINVAL; -- } -- } --// fail -- -- info = intel_fb->base.fbdev; -- par = info->par; -- -- crtc_count = 0; -- /* -- * For each CRTC, set up the connector list for the CRTC's mode -- * set configuration. -- */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct intel_crtc *intel_crtc = to_intel_crtc(crtc); -- -- modeset = &intel_crtc->mode_set; -- modeset->fb = &intel_fb->base; -- conn_count = 0; -- list_for_each_entry(connector, &dev->mode_config.connector_list, -- head) { -- if (!connector->encoder) -- continue; -- -- if(connector->encoder->crtc == modeset->crtc) { -- modeset->connectors[conn_count++] = connector; -- if (conn_count > INTELFB_CONN_LIMIT) -- BUG(); -- } -- } -- -- /* Zero out remaining connector pointers */ -- for (i = conn_count; i < INTELFB_CONN_LIMIT; i++) -- modeset->connectors[i] = NULL; -- -- par->crtc_ids[crtc_count++] = crtc->base.id; -- -- modeset->num_connectors = conn_count; -- if (modeset->crtc->desired_mode) { -- if (modeset->mode) -- drm_mode_destroy(dev, modeset->mode); -- modeset->mode = drm_mode_duplicate(dev, -- modeset->crtc->desired_mode); -- } -- } -- par->crtc_count = crtc_count; -- -- if (new_fb) { -- info->var.pixclock = -1; -- if (register_framebuffer(info) < 0) -- return -EINVAL; -- } else -- intelfb_set_par(info); -- -- DRM_INFO("fb%d: %s frame buffer device\n", info->node, -- info->fix.id); -- -- /* Switch back to kernel console on panic */ -- kernelfb_mode = *modeset; -- atomic_notifier_chain_register(&panic_notifier_list, &paniced); -- DRM_DEBUG("registered panic notifier\n"); -- -- return 0; --} -- --/** -- * intelfb_restore - restore the framebuffer console (kernel) config -- * -- * Restore's the kernel's fbcon mode, used for lastclose & panic paths. -- */ --void intelfb_restore(void) --{ -- int ret; -- if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { -- DRM_ERROR("Failed to restore crtc configuration: %d\n", -- ret); -- } --} -- --static void intelfb_restore_work_fn(struct work_struct *ignored) --{ -- intelfb_restore(); --} --static DECLARE_WORK(intelfb_restore_work, intelfb_restore_work_fn); -- --static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3) --{ -- schedule_work(&intelfb_restore_work); --} -- --static struct sysrq_key_op sysrq_intelfb_restore_op = { -- .handler = intelfb_sysrq, -- .help_msg = "force-fb(V)", -- .action_msg = "Restore framebuffer console", --}; -- - int intelfb_probe(struct drm_device *dev) - { - int ret; - - DRM_DEBUG("\n"); -- -- /* something has changed in the lower levels of hell - deal with it -- here */ -- -- /* two modes : a) 1 fb to rule all crtcs. -- b) one fb per crtc. -- two actions 1) new connected device -- 2) device removed. -- case a/1 : if the fb surface isn't big enough - resize the surface fb. -- if the fb size isn't big enough - resize fb into surface. -- if everything big enough configure the new crtc/etc. -- case a/2 : undo the configuration -- possibly resize down the fb to fit the new configuration. -- case b/1 : see if it is on a new crtc - setup a new fb and add it. -- case b/2 : teardown the new fb. -- */ -- -- /* mode a first */ -- /* search for an fb */ -- if (i915_fbpercrtc == 1) { -- ret = intelfb_multi_fb_probe(dev); -- } else { -- ret = intelfb_single_fb_probe(dev); -- } -- -- register_sysrq_key('v', &sysrq_intelfb_restore_op); -- -+ ret = drm_fb_helper_single_fb_probe(dev, intelfb_create); - return ret; - } - EXPORT_SYMBOL(intelfb_probe); -@@ -940,13 +258,14 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) - info = fb->fbdev; - - if (info) { -+ struct intelfb_par *par = info->par; - unregister_framebuffer(info); - iounmap(info->screen_base); -+ if (info->par) -+ drm_fb_helper_free(&par->helper); - framebuffer_release(info); - } - -- atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); -- memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set)); - return 0; - } - EXPORT_SYMBOL(intelfb_remove); -diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c -index 62b8bea..c7eab72 100644 ---- a/drivers/gpu/drm/i915/intel_i2c.c -+++ b/drivers/gpu/drm/i915/intel_i2c.c -@@ -42,11 +42,11 @@ void intel_i2c_quirk_set(struct drm_device *dev, bool enable) - if (!IS_IGD(dev)) - return; - if (enable) -- I915_WRITE(CG_2D_DIS, -- I915_READ(CG_2D_DIS) | DPCUNIT_CLOCK_GATE_DISABLE); -+ I915_WRITE(DSPCLK_GATE_D, -+ I915_READ(DSPCLK_GATE_D) | DPCUNIT_CLOCK_GATE_DISABLE); - else -- I915_WRITE(CG_2D_DIS, -- I915_READ(CG_2D_DIS) & (~DPCUNIT_CLOCK_GATE_DISABLE)); -+ I915_WRITE(DSPCLK_GATE_D, -+ I915_READ(DSPCLK_GATE_D) & (~DPCUNIT_CLOCK_GATE_DISABLE)); - } - - /* -diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c -index 8df02ef..dafc0da 100644 ---- a/drivers/gpu/drm/i915/intel_lvds.c -+++ b/drivers/gpu/drm/i915/intel_lvds.c -@@ -38,16 +38,6 @@ - #include "i915_drv.h" - #include - --#define I915_LVDS "i915_lvds" -- --/* -- * the following four scaling options are defined. -- * #define DRM_MODE_SCALE_NON_GPU 0 -- * #define DRM_MODE_SCALE_FULLSCREEN 1 -- * #define DRM_MODE_SCALE_NO_SCALE 2 -- * #define DRM_MODE_SCALE_ASPECT 3 -- */ -- - /* Private structure for the integrated LVDS support */ - struct intel_lvds_priv { - int fitting_mode; -@@ -336,7 +326,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, - I915_WRITE(BCLRPAT_B, 0); - - switch (lvds_priv->fitting_mode) { -- case DRM_MODE_SCALE_NO_SCALE: -+ case DRM_MODE_SCALE_CENTER: - /* - * For centered modes, we have to calculate border widths & - * heights and modify the values programmed into the CRTC. -@@ -672,9 +662,8 @@ static int intel_lvds_set_property(struct drm_connector *connector, - connector->encoder) { - struct drm_crtc *crtc = connector->encoder->crtc; - struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; -- if (value == DRM_MODE_SCALE_NON_GPU) { -- DRM_DEBUG_KMS(I915_LVDS, -- "non_GPU property is unsupported\n"); -+ if (value == DRM_MODE_SCALE_NONE) { -+ DRM_DEBUG_KMS("no scaling not supported\n"); - return 0; - } - if (lvds_priv->fitting_mode == value) { -@@ -731,8 +720,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { - - static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) - { -- DRM_DEBUG_KMS(I915_LVDS, -- "Skipping LVDS initialization for %s\n", id->ident); -+ DRM_DEBUG_KMS("Skipping LVDS initialization for %s\n", id->ident); - return 1; - } - -@@ -1027,7 +1015,7 @@ out: - return; - - failed: -- DRM_DEBUG_KMS(I915_LVDS, "No LVDS modes found, disabling.\n"); -+ DRM_DEBUG_KMS("No LVDS modes found, disabling.\n"); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); - drm_connector_cleanup(connector); -diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c -index d3b74ba..0bf28ef 100644 ---- a/drivers/gpu/drm/i915/intel_sdvo.c -+++ b/drivers/gpu/drm/i915/intel_sdvo.c -@@ -37,7 +37,19 @@ - #include "intel_sdvo_regs.h" - - #undef SDVO_DEBUG --#define I915_SDVO "i915_sdvo" -+ -+static char *tv_format_names[] = { -+ "NTSC_M" , "NTSC_J" , "NTSC_443", -+ "PAL_B" , "PAL_D" , "PAL_G" , -+ "PAL_H" , "PAL_I" , "PAL_M" , -+ "PAL_N" , "PAL_NC" , "PAL_60" , -+ "SECAM_B" , "SECAM_D" , "SECAM_G" , -+ "SECAM_K" , "SECAM_K1", "SECAM_L" , -+ "SECAM_60" -+}; -+ -+#define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) -+ - struct intel_sdvo_priv { - u8 slave_addr; - -@@ -71,6 +83,15 @@ struct intel_sdvo_priv { - */ - bool is_tv; - -+ /* This is for current tv format name */ -+ char *tv_format_name; -+ -+ /* This contains all current supported TV format */ -+ char *tv_format_supported[TV_FORMAT_NUM]; -+ int format_supported_num; -+ struct drm_property *tv_format_property; -+ struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; -+ - /** - * This is set if we treat the device as HDMI, instead of DVI. - */ -@@ -97,14 +118,6 @@ struct intel_sdvo_priv { - */ - struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; - -- /** -- * Current selected TV format. -- * -- * This is stored in the same structure that's passed to the device, for -- * convenience. -- */ -- struct intel_sdvo_tv_format tv_format; -- - /* - * supported encoding mode, used to determine whether HDMI is - * supported -@@ -114,6 +127,9 @@ struct intel_sdvo_priv { - /* DDC bus used by this SDVO output */ - uint8_t ddc_bus; - -+ /* Mac mini hack -- use the same DDC as the analog connector */ -+ struct i2c_adapter *analog_ddc_bus; -+ - int save_sdvo_mult; - u16 save_active_outputs; - struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; -@@ -188,7 +204,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, - return true; - } - -- DRM_DEBUG("i2c transfer returned %d\n", ret); -+ DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); - return false; - } - -@@ -298,7 +314,7 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; - int i; - -- DRM_DEBUG_KMS(I915_SDVO, "%s: W: %02X ", -+ DRM_DEBUG_KMS("%s: W: %02X ", - SDVO_NAME(sdvo_priv), cmd); - for (i = 0; i < args_len; i++) - DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); -@@ -351,7 +367,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; - int i; - -- DRM_DEBUG_KMS(I915_SDVO, "%s: R: ", SDVO_NAME(sdvo_priv)); -+ DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); - for (i = 0; i < response_len; i++) - DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); - for (; i < 8; i++) -@@ -668,10 +684,10 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) - status = intel_sdvo_read_response(intel_output, &response, 1); - - if (status != SDVO_CMD_STATUS_SUCCESS) { -- DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n"); -+ DRM_DEBUG_KMS("Couldn't get SDVO clock rate multiplier\n"); - return SDVO_CLOCK_RATE_MULT_1X; - } else { -- DRM_DEBUG("Current clock rate multiplier: %d\n", response); -+ DRM_DEBUG_KMS("Current clock rate multiplier: %d\n", response); - } - - return response; -@@ -945,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, - - static void intel_sdvo_set_tv_format(struct intel_output *output) - { -+ -+ struct intel_sdvo_tv_format format; - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; -- struct intel_sdvo_tv_format *format, unset; -- u8 status; -+ uint32_t format_map, i; -+ uint8_t status; - -- format = &sdvo_priv->tv_format; -- memset(&unset, 0, sizeof(unset)); -- if (memcmp(format, &unset, sizeof(*format))) { -- DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n", -- SDVO_NAME(sdvo_priv)); -- format->ntsc_m = 1; -- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, -- sizeof(*format)); -- status = intel_sdvo_read_response(output, NULL, 0); -- if (status != SDVO_CMD_STATUS_SUCCESS) -- DRM_DEBUG("%s: Failed to set TV format\n", -- SDVO_NAME(sdvo_priv)); -- } -+ for (i = 0; i < TV_FORMAT_NUM; i++) -+ if (tv_format_names[i] == sdvo_priv->tv_format_name) -+ break; -+ -+ format_map = 1 << i; -+ memset(&format, 0, sizeof(format)); -+ memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? -+ sizeof(format) : sizeof(format_map)); -+ -+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, -+ sizeof(format)); -+ -+ status = intel_sdvo_read_response(output, NULL, 0); -+ if (status != SDVO_CMD_STATUS_SUCCESS) -+ DRM_DEBUG("%s: Failed to set TV format\n", -+ SDVO_NAME(sdvo_priv)); - } - - static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, -@@ -1230,8 +1251,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) - * a given it the status is a success, we succeeded. - */ - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { -- DRM_DEBUG("First %s output reported failure to sync\n", -- SDVO_NAME(sdvo_priv)); -+ DRM_DEBUG_KMS("First %s output reported failure to " -+ "sync\n", SDVO_NAME(sdvo_priv)); - } - - if (0) -@@ -1326,8 +1347,8 @@ static void intel_sdvo_restore(struct drm_connector *connector) - intel_wait_for_vblank(dev); - status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) -- DRM_DEBUG("First %s output reported failure to sync\n", -- SDVO_NAME(sdvo_priv)); -+ DRM_DEBUG_KMS("First %s output reported failure to " -+ "sync\n", SDVO_NAME(sdvo_priv)); - } - - intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); -@@ -1405,7 +1426,7 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) - u8 response[2]; - u8 status; - struct intel_output *intel_output; -- DRM_DEBUG("\n"); -+ DRM_DEBUG_KMS("\n"); - - if (!connector) - return 0; -@@ -1478,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) - return (caps > 1); - } - -+static struct drm_connector * -+intel_find_analog_connector(struct drm_device *dev) -+{ -+ struct drm_connector *connector; -+ struct intel_output *intel_output; -+ -+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -+ intel_output = to_intel_output(connector); -+ if (intel_output->type == INTEL_OUTPUT_ANALOG) -+ return connector; -+ } -+ return NULL; -+} -+ -+static int -+intel_analog_is_connected(struct drm_device *dev) -+{ -+ struct drm_connector *analog_connector; -+ analog_connector = intel_find_analog_connector(dev); -+ -+ if (!analog_connector) -+ return false; -+ -+ if (analog_connector->funcs->detect(analog_connector) == -+ connector_status_disconnected) -+ return false; -+ -+ return true; -+} -+ - enum drm_connector_status - intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) - { -@@ -1488,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) - - edid = drm_get_edid(&intel_output->base, - intel_output->ddc_bus); -+ -+ /* when there is no edid and no monitor is connected with VGA -+ * port, try to use the CRT ddc to read the EDID for DVI-connector -+ */ -+ if (edid == NULL && -+ sdvo_priv->analog_ddc_bus && -+ !intel_analog_is_connected(intel_output->base.dev)) -+ edid = drm_get_edid(&intel_output->base, -+ sdvo_priv->analog_ddc_bus); - if (edid != NULL) { - /* Don't report the output as connected if it's a DVI-I - * connector with a non-digital EDID coming out. -@@ -1516,10 +1576,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect - struct intel_output *intel_output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; - -- intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); -+ intel_sdvo_write_cmd(intel_output, -+ SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); - status = intel_sdvo_read_response(intel_output, &response, 2); - -- DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8); -+ DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return connector_status_unknown; -@@ -1540,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect - static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) - { - struct intel_output *intel_output = to_intel_output(connector); -+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; -+ int num_modes; - - /* set the bus switch and get the modes */ -- intel_ddc_get_modes(intel_output); -+ num_modes = intel_ddc_get_modes(intel_output); - --#if 0 -- struct drm_device *dev = encoder->dev; -- struct drm_i915_private *dev_priv = dev->dev_private; -- /* Mac mini hack. On this device, I get DDC through the analog, which -- * load-detects as disconnected. I fail to DDC through the SDVO DDC, -- * but it does load-detect as connected. So, just steal the DDC bits -- * from analog when we fail at finding it the right way. -+ /* -+ * Mac mini hack. On this device, the DVI-I connector shares one DDC -+ * link between analog and digital outputs. So, if the regular SDVO -+ * DDC fails, check to see if the analog output is disconnected, in -+ * which case we'll look there for the digital DDC data. - */ -- crt = xf86_config->output[0]; -- intel_output = crt->driver_private; -- if (intel_output->type == I830_OUTPUT_ANALOG && -- crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { -- I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); -- edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); -- xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); -- } -- if (edid_mon) { -- xf86OutputSetEDID(output, edid_mon); -- modes = xf86OutputGetEDIDModes(output); -- } --#endif --} -+ if (num_modes == 0 && -+ sdvo_priv->analog_ddc_bus && -+ !intel_analog_is_connected(intel_output->base.dev)) { -+ struct i2c_adapter *digital_ddc_bus; - --/** -- * This function checks the current TV format, and chooses a default if -- * it hasn't been set. -- */ --static void --intel_sdvo_check_tv_format(struct intel_output *output) --{ -- struct intel_sdvo_priv *dev_priv = output->dev_priv; -- struct intel_sdvo_tv_format format; -- uint8_t status; -+ /* Switch to the analog ddc bus and try that -+ */ -+ digital_ddc_bus = intel_output->ddc_bus; -+ intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; - -- intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); -- status = intel_sdvo_read_response(output, &format, sizeof(format)); -- if (status != SDVO_CMD_STATUS_SUCCESS) -- return; -+ (void) intel_ddc_get_modes(intel_output); - -- memcpy(&dev_priv->tv_format, &format, sizeof(format)); -+ intel_output->ddc_bus = digital_ddc_bus; -+ } - } - - /* -@@ -1656,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) - struct intel_output *output = to_intel_output(connector); - struct intel_sdvo_priv *sdvo_priv = output->dev_priv; - struct intel_sdvo_sdtv_resolution_request tv_res; -- uint32_t reply = 0; -+ uint32_t reply = 0, format_map = 0; -+ int i; - uint8_t status; -- int i = 0; - -- intel_sdvo_check_tv_format(output); - - /* Read the list of supported input resolutions for the selected TV - * format. - */ -- memset(&tv_res, 0, sizeof(tv_res)); -- memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res)); -+ for (i = 0; i < TV_FORMAT_NUM; i++) -+ if (tv_format_names[i] == sdvo_priv->tv_format_name) -+ break; -+ -+ format_map = (1 << i); -+ memcpy(&tv_res, &format_map, -+ sizeof(struct intel_sdvo_sdtv_resolution_request) > -+ sizeof(format_map) ? sizeof(format_map) : -+ sizeof(struct intel_sdvo_sdtv_resolution_request)); -+ -+ intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); -+ - intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, - &tv_res, sizeof(tv_res)); - status = intel_sdvo_read_response(output, &reply, 3); -@@ -1681,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) - if (nmode) - drm_mode_probed_add(connector, nmode); - } -+ - } - - static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) -@@ -1748,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector) - intel_i2c_destroy(intel_output->i2c_bus); - if (intel_output->ddc_bus) - intel_i2c_destroy(intel_output->ddc_bus); -+ if (sdvo_priv->analog_ddc_bus) -+ intel_i2c_destroy(sdvo_priv->analog_ddc_bus); - - if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) - drm_mode_destroy(connector->dev, - sdvo_priv->sdvo_lvds_fixed_mode); - -+ if (sdvo_priv->tv_format_property) -+ drm_property_destroy(connector->dev, -+ sdvo_priv->tv_format_property); -+ - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - - kfree(intel_output); - } - -+static int -+intel_sdvo_set_property(struct drm_connector *connector, -+ struct drm_property *property, -+ uint64_t val) -+{ -+ struct intel_output *intel_output = to_intel_output(connector); -+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; -+ struct drm_encoder *encoder = &intel_output->enc; -+ struct drm_crtc *crtc = encoder->crtc; -+ int ret = 0; -+ bool changed = false; -+ -+ ret = drm_connector_property_set_value(connector, property, val); -+ if (ret < 0) -+ goto out; -+ -+ if (property == sdvo_priv->tv_format_property) { -+ if (val >= TV_FORMAT_NUM) { -+ ret = -EINVAL; -+ goto out; -+ } -+ if (sdvo_priv->tv_format_name == -+ sdvo_priv->tv_format_supported[val]) -+ goto out; -+ -+ sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; -+ changed = true; -+ } else { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ if (changed && crtc) -+ drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, -+ crtc->y, crtc->fb); -+out: -+ return ret; -+} -+ - static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { - .dpms = intel_sdvo_dpms, - .mode_fixup = intel_sdvo_mode_fixup, -@@ -1773,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { - .restore = intel_sdvo_restore, - .detect = intel_sdvo_detect, - .fill_modes = drm_helper_probe_single_connector_modes, -+ .set_property = intel_sdvo_set_property, - .destroy = intel_sdvo_destroy, - }; - -@@ -2013,10 +2112,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) - - sdvo_priv->controlled_output = 0; - memcpy(bytes, &sdvo_priv->caps.output_flags, 2); -- DRM_DEBUG_KMS(I915_SDVO, -- "%s: Unknown SDVO output type (0x%02x%02x)\n", -- SDVO_NAME(sdvo_priv), -- bytes[0], bytes[1]); -+ DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", -+ SDVO_NAME(sdvo_priv), -+ bytes[0], bytes[1]); - ret = false; - } - intel_output->crtc_mask = (1 << 0) | (1 << 1); -@@ -2029,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) - - } - -+static void intel_sdvo_tv_create_property(struct drm_connector *connector) -+{ -+ struct intel_output *intel_output = to_intel_output(connector); -+ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; -+ struct intel_sdvo_tv_format format; -+ uint32_t format_map, i; -+ uint8_t status; -+ -+ intel_sdvo_set_target_output(intel_output, -+ sdvo_priv->controlled_output); -+ -+ intel_sdvo_write_cmd(intel_output, -+ SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); -+ status = intel_sdvo_read_response(intel_output, -+ &format, sizeof(format)); -+ if (status != SDVO_CMD_STATUS_SUCCESS) -+ return; -+ -+ memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? -+ sizeof(format_map) : sizeof(format)); -+ -+ if (format_map == 0) -+ return; -+ -+ sdvo_priv->format_supported_num = 0; -+ for (i = 0 ; i < TV_FORMAT_NUM; i++) -+ if (format_map & (1 << i)) { -+ sdvo_priv->tv_format_supported -+ [sdvo_priv->format_supported_num++] = -+ tv_format_names[i]; -+ } -+ -+ -+ sdvo_priv->tv_format_property = -+ drm_property_create( -+ connector->dev, DRM_MODE_PROP_ENUM, -+ "mode", sdvo_priv->format_supported_num); -+ -+ for (i = 0; i < sdvo_priv->format_supported_num; i++) -+ drm_property_add_enum( -+ sdvo_priv->tv_format_property, i, -+ i, sdvo_priv->tv_format_supported[i]); -+ -+ sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0]; -+ drm_connector_attach_property( -+ connector, sdvo_priv->tv_format_property, 0); -+ -+} -+ - bool intel_sdvo_init(struct drm_device *dev, int output_device) - { - struct drm_connector *connector; -@@ -2066,18 +2213,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) - /* Read the regs to test if we can talk to the device */ - for (i = 0; i < 0x40; i++) { - if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { -- DRM_DEBUG_KMS(I915_SDVO, -- "No SDVO device found on SDVO%c\n", -+ DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); - goto err_i2c; - } - } - - /* setup the DDC bus. */ -- if (output_device == SDVOB) -+ if (output_device == SDVOB) { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); -- else -+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, -+ "SDVOB/VGA DDC BUS"); -+ } else { - intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); -+ sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, -+ "SDVOC/VGA DDC BUS"); -+ } - - if (intel_output->ddc_bus == NULL) - goto err_i2c; -@@ -2090,7 +2241,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) - - if (intel_sdvo_output_setup(intel_output, - sdvo_priv->caps.output_flags) != true) { -- DRM_DEBUG("SDVO output failed to setup on SDVO%c\n", -+ DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); - goto err_i2c; - } -@@ -2111,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) - drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); - - drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); -+ if (sdvo_priv->is_tv) -+ intel_sdvo_tv_create_property(connector); - drm_sysfs_connector_add(connector); - - intel_sdvo_select_ddc_bus(sdvo_priv); -@@ -2123,7 +2276,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) - &sdvo_priv->pixel_clock_max); - - -- DRM_DEBUG_KMS(I915_SDVO, "%s device VID/DID: %02X:%02X.%02X, " -+ DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " - "clock range %dMHz - %dMHz, " - "input 1: %c, input 2: %c, " - "output 1: %c, output 2: %c\n", -@@ -2143,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) - return true; - - err_i2c: -+ if (sdvo_priv->analog_ddc_bus != NULL) -+ intel_i2c_destroy(sdvo_priv->analog_ddc_bus); - if (intel_output->ddc_bus != NULL) - intel_i2c_destroy(intel_output->ddc_bus); - if (intel_output->i2c_bus != NULL) -diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c -index 2fbe13a..a6c686c 100644 ---- a/drivers/gpu/drm/i915/intel_tv.c -+++ b/drivers/gpu/drm/i915/intel_tv.c -@@ -1437,6 +1437,35 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) - return type; - } - -+/* -+ * Here we set accurate tv format according to connector type -+ * i.e Component TV should not be assigned by NTSC or PAL -+ */ -+static void intel_tv_find_better_format(struct drm_connector *connector) -+{ -+ struct intel_output *intel_output = to_intel_output(connector); -+ struct intel_tv_priv *tv_priv = intel_output->dev_priv; -+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); -+ int i; -+ -+ if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == -+ tv_mode->component_only) -+ return; -+ -+ -+ for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { -+ tv_mode = tv_modes + i; -+ -+ if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == -+ tv_mode->component_only) -+ break; -+ } -+ -+ tv_priv->tv_format = tv_mode->name; -+ drm_connector_property_set_value(connector, -+ connector->dev->mode_config.tv_mode_property, i); -+} -+ - /** - * Detect the TV connection. - * -@@ -1473,6 +1502,7 @@ intel_tv_detect(struct drm_connector *connector) - if (type < 0) - return connector_status_disconnected; - -+ intel_tv_find_better_format(connector); - return connector_status_connected; - } - -diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c -index 6c67a02..3c917fb 100644 ---- a/drivers/gpu/drm/mga/mga_dma.c -+++ b/drivers/gpu/drm/mga/mga_dma.c -@@ -444,7 +444,7 @@ static int mga_do_agp_dma_bootstrap(struct drm_device * dev, - { - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; -- unsigned int warp_size = mga_warp_microcode_size(dev_priv); -+ unsigned int warp_size = MGA_WARP_UCODE_SIZE; - int err; - unsigned offset; - const unsigned secondary_size = dma_bs->secondary_bin_count -@@ -619,7 +619,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device * dev, - { - drm_mga_private_t *const dev_priv = - (drm_mga_private_t *) dev->dev_private; -- unsigned int warp_size = mga_warp_microcode_size(dev_priv); -+ unsigned int warp_size = MGA_WARP_UCODE_SIZE; - unsigned int primary_size; - unsigned int bin_count; - int err; -diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h -index 3d264f2..be6c6b9 100644 ---- a/drivers/gpu/drm/mga/mga_drv.h -+++ b/drivers/gpu/drm/mga/mga_drv.h -@@ -177,7 +177,6 @@ extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv); - extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf); - - /* mga_warp.c */ --extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv); - extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv); - extern int mga_warp_init(drm_mga_private_t * dev_priv); - -diff --git a/drivers/gpu/drm/mga/mga_ucode.h b/drivers/gpu/drm/mga/mga_ucode.h -deleted file mode 100644 -index b611e27..0000000 ---- a/drivers/gpu/drm/mga/mga_ucode.h -+++ /dev/null -@@ -1,11645 +0,0 @@ --/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*- -- * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com -- * -- * Copyright 1999 Matrox Graphics Inc. -- * All Rights Reserved. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included -- * in all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, -- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- * -- * Kernel-based WARP engine management: -- * Gareth Hughes -- */ -- --/* -- * WARP pipes are named according to the functions they perform, where: -- * -- * - T stands for computation of texture stage 0 -- * - T2 stands for computation of both texture stage 0 and texture stage 1 -- * - G stands for computation of triangle intensity (Gouraud interpolation) -- * - Z stands for computation of Z buffer interpolation -- * - S stands for computation of specular highlight -- * - A stands for computation of the alpha channel -- * - F stands for computation of vertex fog interpolation -- */ -- --static unsigned char warp_g200_tgz[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x72, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x60, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x03, 0x80, 0x0A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x57, 0x39, 0x20, 0xE9, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0x2B, 0x32, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0xB3, 0x05, -- 0x00, 0xE0, -- 0x16, 0x28, 0x20, 0xE9, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x1E, 0x2B, 0x20, 0xE9, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x85, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x84, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x82, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x7F, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgza[] = { -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x7D, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x6B, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2D, 0x44, 0x4C, 0xB6, -- 0x25, 0x44, 0x54, 0xB6, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x07, 0xC0, 0x44, 0xC6, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x1F, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x3F, 0x3D, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x07, 0x20, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0xB3, 0x05, -- 0x00, 0xE0, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0x26, 0x1F, 0xDF, -- 0x9D, 0x1F, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x9E, 0x3F, 0x4F, 0xE9, -- -- 0x07, 0x07, 0x1F, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x9C, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x7A, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x79, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x77, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x74, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzaf[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x83, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x6F, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0D, 0x21, 0x1A, 0xB6, -- 0x05, 0x21, 0x31, 0xB6, -- -- 0x2D, 0x44, 0x4C, 0xB6, -- 0x25, 0x44, 0x54, 0xB6, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x0D, 0x20, -- 0x05, 0x20, -- 0x2F, 0xC0, 0x21, 0xC6, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x07, 0xC0, 0x44, 0xC6, -- -- 0x17, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x2D, 0x20, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x1F, 0x62, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x07, 0x20, -- -- 0x3F, 0x3D, 0x5D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0xB3, 0x05, -- 0x00, 0xE0, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x35, 0x17, 0x4F, 0xE9, -- -- 0x1F, 0x26, 0x1F, 0xDF, -- 0x9D, 0x1F, 0x4F, 0xE9, -- -- 0x9E, 0x3F, 0x4F, 0xE9, -- 0x39, 0x37, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x17, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x07, 0x07, 0x1F, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x31, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x9C, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x74, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x73, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x71, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6E, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzf[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x7F, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x6B, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0D, 0x21, 0x1A, 0xB6, -- 0x05, 0x21, 0x31, 0xB6, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x0D, 0x20, -- 0x05, 0x20, -- 0x2F, 0xC0, 0x21, 0xC6, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x17, 0x50, 0x56, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0xB3, 0x05, -- 0x00, 0xE0, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x17, 0x26, 0x17, 0xDF, -- 0x35, 0x17, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x39, 0x37, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x17, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x31, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x78, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x77, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x75, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x72, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzs[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x8B, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x77, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2D, 0x21, 0x1A, 0xB0, -- 0x25, 0x21, 0x31, 0xB0, -- -- 0x0D, 0x21, 0x1A, 0xB2, -- 0x05, 0x21, 0x31, 0xB2, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x05, 0x20, -- 0x0D, 0x20, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x2F, 0xC0, 0x21, 0xC0, -- -- 0x16, 0x42, 0x56, 0x9F, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x1E, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x21, 0x31, 0xB4, -- 0x2D, 0x21, 0x1A, 0xB4, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0x05, -- 0x00, 0xE0, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x1E, 0x26, 0x1E, 0xDF, -- -- 0xA7, 0x1E, 0x4F, 0xE9, -- 0x17, 0x26, 0x16, 0xDF, -- -- 0x2D, 0x20, -- 0x00, 0xE0, -- 0xA8, 0x3F, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x1E, 0xAF, -- 0x25, 0x20, -- 0x00, 0xE0, -- -- 0xA4, 0x16, 0x4F, 0xE9, -- 0x0F, 0xC0, 0x21, 0xC2, -- -- 0xA6, 0x80, 0x4F, 0xE9, -- 0x1F, 0x62, 0x57, 0x9F, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x8F, 0x20, -- -- 0xA5, 0x37, 0x4F, 0xE9, -- 0x0F, 0x17, 0x0F, 0xAF, -- -- 0x06, 0xC0, 0x21, 0xC4, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0xA3, 0x80, 0x4F, 0xE9, -- -- 0x06, 0x20, -- 0x00, 0xE0, -- 0x1F, 0x26, 0x1F, 0xDF, -- -- 0xA1, 0x1F, 0x4F, 0xE9, -- 0xA2, 0x3F, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x06, 0x06, 0x1F, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x6C, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6B, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x69, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzsa[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x8F, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x7B, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2D, 0x21, 0x1A, 0xB0, -- 0x25, 0x21, 0x31, 0xB0, -- -- 0x0D, 0x21, 0x1A, 0xB2, -- 0x05, 0x21, 0x31, 0xB2, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x05, 0x20, -- 0x0D, 0x20, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x2F, 0xC0, 0x21, 0xC0, -- -- 0x16, 0x42, 0x56, 0x9F, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x1E, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x21, 0x31, 0xB4, -- 0x2D, 0x21, 0x1A, 0xB4, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0x05, -- 0x00, 0xE0, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0x0D, 0x44, 0x4C, 0xB6, -- 0x05, 0x44, 0x54, 0xB6, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x1E, 0x26, 0x1E, 0xDF, -- -- 0xA7, 0x1E, 0x4F, 0xE9, -- 0x17, 0x26, 0x16, 0xDF, -- -- 0x2D, 0x20, -- 0x00, 0xE0, -- 0xA8, 0x3F, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x1E, 0xAF, -- 0x25, 0x20, -- 0x00, 0xE0, -- -- 0xA4, 0x16, 0x4F, 0xE9, -- 0x0F, 0xC0, 0x21, 0xC2, -- -- 0xA6, 0x80, 0x4F, 0xE9, -- 0x1F, 0x62, 0x57, 0x9F, -- -- 0x0D, 0x20, -- 0x05, 0x20, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x0F, 0x20, -- -- 0x17, 0x50, 0x56, 0x9F, -- 0xA5, 0x37, 0x4F, 0xE9, -- -- 0x06, 0xC0, 0x21, 0xC4, -- 0x0F, 0x17, 0x0F, 0xAF, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2F, 0xC0, 0x44, 0xC6, -- 0xA3, 0x80, 0x4F, 0xE9, -- -- 0x06, 0x20, -- 0x00, 0xE0, -- 0x1F, 0x26, 0x1F, 0xDF, -- -- 0x17, 0x26, 0x17, 0xDF, -- 0x9D, 0x17, 0x4F, 0xE9, -- -- 0xA1, 0x1F, 0x4F, 0xE9, -- 0xA2, 0x3F, 0x4F, 0xE9, -- -- 0x06, 0x06, 0x1F, 0xAF, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x9E, 0x37, 0x4F, 0xE9, -- 0x2F, 0x17, 0x2F, 0xAF, -- -- 0xA0, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x9C, 0x80, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x68, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x67, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x65, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x62, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzsaf[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x94, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x80, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2D, 0x21, 0x1A, 0xB0, -- 0x25, 0x21, 0x31, 0xB0, -- -- 0x0D, 0x21, 0x1A, 0xB2, -- 0x05, 0x21, 0x31, 0xB2, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x05, 0x20, -- 0x0D, 0x20, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x2F, 0xC0, 0x21, 0xC0, -- -- 0x16, 0x42, 0x56, 0x9F, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x1E, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x21, 0x31, 0xB4, -- 0x2D, 0x21, 0x1A, 0xB4, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0x05, -- 0x00, 0xE0, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0x0D, 0x21, 0x1A, 0xB6, -- 0x05, 0x21, 0x31, 0xB6, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x1E, 0x26, 0x1E, 0xDF, -- -- 0xA7, 0x1E, 0x4F, 0xE9, -- 0x17, 0x26, 0x16, 0xDF, -- -- 0x2D, 0x20, -- 0x00, 0xE0, -- 0xA8, 0x3F, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x1E, 0xAF, -- 0x25, 0x20, -- 0x00, 0xE0, -- -- 0xA4, 0x16, 0x4F, 0xE9, -- 0x0F, 0xC0, 0x21, 0xC2, -- -- 0xA6, 0x80, 0x4F, 0xE9, -- 0x1F, 0x62, 0x57, 0x9F, -- -- 0x0D, 0x20, -- 0x05, 0x20, -- 0x2F, 0xC0, 0x21, 0xC6, -- -- 0x2D, 0x44, 0x4C, 0xB6, -- 0x25, 0x44, 0x54, 0xB6, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x0F, 0x20, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x07, 0xC0, 0x44, 0xC6, -- -- 0x17, 0x50, 0x56, 0x9F, -- 0xA5, 0x37, 0x4F, 0xE9, -- -- 0x06, 0xC0, 0x21, 0xC4, -- 0x0F, 0x17, 0x0F, 0xAF, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1E, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x3E, 0x3D, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x07, 0x20, -- -- 0x2F, 0x20, -- 0x00, 0xE0, -- 0xA3, 0x0F, 0x4F, 0xE9, -- -- 0x06, 0x20, -- 0x00, 0xE0, -- 0x1F, 0x26, 0x1F, 0xDF, -- -- 0x17, 0x26, 0x17, 0xDF, -- 0xA1, 0x1F, 0x4F, 0xE9, -- -- 0x1E, 0x26, 0x1E, 0xDF, -- 0x9D, 0x1E, 0x4F, 0xE9, -- -- 0x35, 0x17, 0x4F, 0xE9, -- 0xA2, 0x3F, 0x4F, 0xE9, -- -- 0x06, 0x06, 0x1F, 0xAF, -- 0x39, 0x37, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x17, 0xAF, -- 0x07, 0x07, 0x1E, 0xAF, -- -- 0xA0, 0x80, 0x4F, 0xE9, -- 0x9E, 0x3E, 0x4F, 0xE9, -- -- 0x31, 0x80, 0x4F, 0xE9, -- 0x9C, 0x80, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x63, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x62, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x60, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x5D, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g200_tgzsf[] = { -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x98, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x81, 0x04, -- 0x89, 0x04, -- 0x01, 0x04, -- 0x09, 0x04, -- -- 0xC9, 0x41, 0xC0, 0xEC, -- 0x11, 0x04, -- 0x00, 0xE0, -- -- 0x41, 0xCC, 0x41, 0xCD, -- 0x49, 0xCC, 0x49, 0xCD, -- -- 0xD1, 0x41, 0xC0, 0xEC, -- 0x51, 0xCC, 0x51, 0xCD, -- -- 0x80, 0x04, -- 0x10, 0x04, -- 0x08, 0x04, -- 0x00, 0xE0, -- -- 0x00, 0xCC, 0xC0, 0xCD, -- 0xD1, 0x49, 0xC0, 0xEC, -- -- 0x8A, 0x1F, 0x20, 0xE9, -- 0x8B, 0x3F, 0x20, 0xE9, -- -- 0x41, 0x3C, 0x41, 0xAD, -- 0x49, 0x3C, 0x49, 0xAD, -- -- 0x10, 0xCC, 0x10, 0xCD, -- 0x08, 0xCC, 0x08, 0xCD, -- -- 0xB9, 0x41, 0x49, 0xBB, -- 0x1F, 0xF0, 0x41, 0xCD, -- -- 0x51, 0x3C, 0x51, 0xAD, -- 0x00, 0x98, 0x80, 0xE9, -- -- 0x8F, 0x80, 0x07, 0xEA, -- 0x24, 0x1F, 0x20, 0xE9, -- -- 0x21, 0x45, 0x80, 0xE8, -- 0x1A, 0x4D, 0x80, 0xE8, -- -- 0x31, 0x55, 0x80, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0x41, 0x49, 0xBD, -- 0x1D, 0x41, 0x51, 0xBD, -- -- 0x2E, 0x41, 0x2A, 0xB8, -- 0x34, 0x53, 0xA0, 0xE8, -- -- 0x15, 0x30, -- 0x1D, 0x30, -- 0x58, 0xE3, -- 0x00, 0xE0, -- -- 0xB5, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x24, 0x43, 0xA0, 0xE8, -- 0x2C, 0x4B, 0xA0, 0xE8, -- -- 0x15, 0x72, -- 0x09, 0xE3, -- 0x00, 0xE0, -- 0x1D, 0x72, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0x97, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x6C, 0x64, 0xC8, 0xEC, -- 0x98, 0xE1, -- 0xB5, 0x05, -- -- 0xBD, 0x05, -- 0x2E, 0x30, -- 0x32, 0xC0, 0xA0, 0xE8, -- -- 0x33, 0xC0, 0xA0, 0xE8, -- 0x74, 0x64, 0xC8, 0xEC, -- -- 0x40, 0x3C, 0x40, 0xAD, -- 0x32, 0x6A, -- 0x2A, 0x30, -- -- 0x20, 0x73, -- 0x33, 0x6A, -- 0x00, 0xE0, -- 0x28, 0x73, -- -- 0x1C, 0x72, -- 0x83, 0xE2, -- 0x7B, 0x80, 0x15, 0xEA, -- -- 0xB8, 0x3D, 0x28, 0xDF, -- 0x30, 0x35, 0x20, 0xDF, -- -- 0x40, 0x30, -- 0x00, 0xE0, -- 0xCC, 0xE2, -- 0x64, 0x72, -- -- 0x25, 0x42, 0x52, 0xBF, -- 0x2D, 0x42, 0x4A, 0xBF, -- -- 0x30, 0x2E, 0x30, 0xDF, -- 0x38, 0x2E, 0x38, 0xDF, -- -- 0x18, 0x1D, 0x45, 0xE9, -- 0x1E, 0x15, 0x45, 0xE9, -- -- 0x2B, 0x49, 0x51, 0xBD, -- 0x00, 0xE0, -- 0x1F, 0x73, -- -- 0x38, 0x38, 0x40, 0xAF, -- 0x30, 0x30, 0x40, 0xAF, -- -- 0x24, 0x1F, 0x24, 0xDF, -- 0x1D, 0x32, 0x20, 0xE9, -- -- 0x2C, 0x1F, 0x2C, 0xDF, -- 0x1A, 0x33, 0x20, 0xE9, -- -- 0xB0, 0x10, -- 0x08, 0xE3, -- 0x40, 0x10, -- 0xB8, 0x10, -- -- 0x26, 0xF0, 0x30, 0xCD, -- 0x2F, 0xF0, 0x38, 0xCD, -- -- 0x2B, 0x80, 0x20, 0xE9, -- 0x2A, 0x80, 0x20, 0xE9, -- -- 0xA6, 0x20, -- 0x88, 0xE2, -- 0x00, 0xE0, -- 0xAF, 0x20, -- -- 0x28, 0x2A, 0x26, 0xAF, -- 0x20, 0x2A, 0xC0, 0xAF, -- -- 0x34, 0x1F, 0x34, 0xDF, -- 0x46, 0x24, 0x46, 0xDF, -- -- 0x28, 0x30, 0x80, 0xBF, -- 0x20, 0x38, 0x80, 0xBF, -- -- 0x47, 0x24, 0x47, 0xDF, -- 0x4E, 0x2C, 0x4E, 0xDF, -- -- 0x4F, 0x2C, 0x4F, 0xDF, -- 0x56, 0x34, 0x56, 0xDF, -- -- 0x28, 0x15, 0x28, 0xDF, -- 0x20, 0x1D, 0x20, 0xDF, -- -- 0x57, 0x34, 0x57, 0xDF, -- 0x00, 0xE0, -- 0x1D, 0x05, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x89, 0xE2, -- 0x2B, 0x30, -- -- 0x3F, 0xC1, 0x1D, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x68, -- 0xBF, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x20, 0xC0, 0x20, 0xAF, -- 0x28, 0x05, -- 0x97, 0x74, -- -- 0x00, 0xE0, -- 0x2A, 0x10, -- 0x16, 0xC0, 0x20, 0xE9, -- -- 0x04, 0x80, 0x10, 0xEA, -- 0x8C, 0xE2, -- 0x95, 0x05, -- -- 0x28, 0xC1, 0x28, 0xAD, -- 0x1F, 0xC1, 0x15, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA8, 0x67, -- 0x9F, 0x6B, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x28, 0xC0, 0x28, 0xAD, -- 0x1D, 0x25, -- 0x20, 0x05, -- -- 0x28, 0x32, 0x80, 0xAD, -- 0x40, 0x2A, 0x40, 0xBD, -- -- 0x1C, 0x80, 0x20, 0xE9, -- 0x20, 0x33, 0x20, 0xAD, -- -- 0x20, 0x73, -- 0x00, 0xE0, -- 0xB6, 0x49, 0x51, 0xBB, -- -- 0x26, 0x2F, 0xB0, 0xE8, -- 0x19, 0x20, 0x20, 0xE9, -- -- 0x35, 0x20, 0x35, 0xDF, -- 0x3D, 0x20, 0x3D, 0xDF, -- -- 0x15, 0x20, 0x15, 0xDF, -- 0x1D, 0x20, 0x1D, 0xDF, -- -- 0x26, 0xD0, 0x26, 0xCD, -- 0x29, 0x49, 0x2A, 0xB8, -- -- 0x26, 0x40, 0x80, 0xBD, -- 0x3B, 0x48, 0x50, 0xBD, -- -- 0x3E, 0x54, 0x57, 0x9F, -- 0x00, 0xE0, -- 0x82, 0xE1, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x26, 0x30, -- 0x29, 0x30, -- 0x48, 0x3C, 0x48, 0xAD, -- -- 0x2B, 0x72, -- 0xC2, 0xE1, -- 0x2C, 0xC0, 0x44, 0xC2, -- -- 0x05, 0x24, 0x34, 0xBF, -- 0x0D, 0x24, 0x2C, 0xBF, -- -- 0x2D, 0x46, 0x4E, 0xBF, -- 0x25, 0x46, 0x56, 0xBF, -- -- 0x20, 0x1D, 0x6F, 0x8F, -- 0x32, 0x3E, 0x5F, 0xE9, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x30, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x33, 0x1E, 0x5F, 0xE9, -- -- 0x05, 0x44, 0x54, 0xB2, -- 0x0D, 0x44, 0x4C, 0xB2, -- -- 0x19, 0xC0, 0xB0, 0xE8, -- 0x34, 0xC0, 0x44, 0xC4, -- -- 0x33, 0x73, -- 0x00, 0xE0, -- 0x3E, 0x62, 0x57, 0x9F, -- -- 0x1E, 0xAF, 0x59, 0x9F, -- 0x00, 0xE0, -- 0x0D, 0x20, -- -- 0x84, 0x3E, 0x58, 0xE9, -- 0x28, 0x1D, 0x6F, 0x8F, -- -- 0x05, 0x20, -- 0x00, 0xE0, -- 0x85, 0x1E, 0x58, 0xE9, -- -- 0x9B, 0x3B, 0x33, 0xDF, -- 0x20, 0x20, 0x42, 0xAF, -- -- 0x30, 0x42, 0x56, 0x9F, -- 0x80, 0x3E, 0x57, 0xE9, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x30, 0x80, 0x5F, 0xE9, -- -- 0x28, 0x28, 0x24, 0xAF, -- 0x81, 0x1E, 0x57, 0xE9, -- -- 0x05, 0x47, 0x57, 0xBF, -- 0x0D, 0x47, 0x4F, 0xBF, -- -- 0x88, 0x80, 0x58, 0xE9, -- 0x1B, 0x29, 0x1B, 0xDF, -- -- 0x30, 0x1D, 0x6F, 0x8F, -- 0x3A, 0x30, 0x4F, 0xE9, -- -- 0x1C, 0x30, 0x26, 0xDF, -- 0x09, 0xE3, -- 0x3B, 0x05, -- -- 0x3E, 0x50, 0x56, 0x9F, -- 0x3B, 0x3F, 0x4F, 0xE9, -- -- 0x1E, 0x8F, 0x51, 0x9F, -- 0x00, 0xE0, -- 0xAC, 0x20, -- -- 0x2D, 0x44, 0x4C, 0xB4, -- 0x2C, 0x1C, 0xC0, 0xAF, -- -- 0x25, 0x44, 0x54, 0xB4, -- 0x00, 0xE0, -- 0xC8, 0x30, -- -- 0x30, 0x46, 0x30, 0xAF, -- 0x1B, 0x1B, 0x48, 0xAF, -- -- 0x00, 0xE0, -- 0x25, 0x20, -- 0x38, 0x2C, 0x4F, 0xE9, -- -- 0x86, 0x80, 0x57, 0xE9, -- 0x38, 0x1D, 0x6F, 0x8F, -- -- 0x28, 0x74, -- 0x00, 0xE0, -- 0x0D, 0x44, 0x4C, 0xB0, -- -- 0x05, 0x44, 0x54, 0xB0, -- 0x2D, 0x20, -- 0x9B, 0x10, -- -- 0x82, 0x3E, 0x57, 0xE9, -- 0x32, 0xF0, 0x1B, 0xCD, -- -- 0x1E, 0xBD, 0x59, 0x9F, -- 0x83, 0x1E, 0x57, 0xE9, -- -- 0x38, 0x47, 0x38, 0xAF, -- 0x34, 0x20, -- 0x2A, 0x30, -- -- 0x00, 0xE0, -- 0x0D, 0x20, -- 0x32, 0x20, -- 0x05, 0x20, -- -- 0x87, 0x80, 0x57, 0xE9, -- 0x1F, 0x54, 0x57, 0x9F, -- -- 0x17, 0x42, 0x56, 0x9F, -- 0x00, 0xE0, -- 0x3B, 0x6A, -- -- 0x3F, 0x8F, 0x51, 0x9F, -- 0x37, 0x1E, 0x4F, 0xE9, -- -- 0x37, 0x32, 0x2A, 0xAF, -- 0x00, 0xE0, -- 0x32, 0x00, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x27, 0xC0, 0x44, 0xC0, -- -- 0x36, 0x1F, 0x4F, 0xE9, -- 0x1F, 0x1F, 0x26, 0xDF, -- -- 0x37, 0x1B, 0x37, 0xBF, -- 0x17, 0x26, 0x17, 0xDF, -- -- 0x3E, 0x17, 0x4F, 0xE9, -- 0x3F, 0x3F, 0x4F, 0xE9, -- -- 0x34, 0x1F, 0x34, 0xAF, -- 0x2B, 0x05, -- 0xA7, 0x20, -- -- 0x33, 0x2B, 0x37, 0xDF, -- 0x27, 0x17, 0xC0, 0xAF, -- -- 0x34, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2D, 0x21, 0x1A, 0xB0, -- 0x25, 0x21, 0x31, 0xB0, -- -- 0x0D, 0x21, 0x1A, 0xB2, -- 0x05, 0x21, 0x31, 0xB2, -- -- 0x03, 0x80, 0x2A, 0xEA, -- 0x17, 0xC1, 0x2B, 0xBD, -- -- 0x2D, 0x20, -- 0x25, 0x20, -- 0x05, 0x20, -- 0x0D, 0x20, -- -- 0xB3, 0x68, -- 0x97, 0x25, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0xC0, 0x33, 0xAF, -- 0x2F, 0xC0, 0x21, 0xC0, -- -- 0x16, 0x42, 0x56, 0x9F, -- 0x3C, 0x27, 0x4F, 0xE9, -- -- 0x1E, 0x62, 0x57, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x21, 0x31, 0xB4, -- 0x2D, 0x21, 0x1A, 0xB4, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x33, 0x05, -- 0x00, 0xE0, -- 0x28, 0x19, 0x60, 0xEC, -- -- 0x0D, 0x21, 0x1A, 0xB6, -- 0x05, 0x21, 0x31, 0xB6, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0xE0, -- 0x2F, 0x20, -- -- 0x23, 0x3B, 0x33, 0xAD, -- 0x1E, 0x26, 0x1E, 0xDF, -- -- 0xA7, 0x1E, 0x4F, 0xE9, -- 0x17, 0x26, 0x16, 0xDF, -- -- 0x2D, 0x20, -- 0x00, 0xE0, -- 0xA8, 0x3F, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x1E, 0xAF, -- 0x25, 0x20, -- 0x00, 0xE0, -- -- 0xA4, 0x16, 0x4F, 0xE9, -- 0x0F, 0xC0, 0x21, 0xC2, -- -- 0xA6, 0x80, 0x4F, 0xE9, -- 0x1F, 0x62, 0x57, 0x9F, -- -- 0x0D, 0x20, -- 0x05, 0x20, -- 0x2F, 0xC0, 0x21, 0xC6, -- -- 0x3F, 0x2F, 0x5D, 0x9F, -- 0x00, 0xE0, -- 0x0F, 0x20, -- -- 0x17, 0x50, 0x56, 0x9F, -- 0xA5, 0x37, 0x4F, 0xE9, -- -- 0x06, 0xC0, 0x21, 0xC4, -- 0x0F, 0x17, 0x0F, 0xAF, -- -- 0x37, 0x0F, 0x5C, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2F, 0x20, -- 0x00, 0xE0, -- 0xA3, 0x80, 0x4F, 0xE9, -- -- 0x06, 0x20, -- 0x00, 0xE0, -- 0x1F, 0x26, 0x1F, 0xDF, -- -- 0x17, 0x26, 0x17, 0xDF, -- 0x35, 0x17, 0x4F, 0xE9, -- -- 0xA1, 0x1F, 0x4F, 0xE9, -- 0xA2, 0x3F, 0x4F, 0xE9, -- -- 0x06, 0x06, 0x1F, 0xAF, -- 0x39, 0x37, 0x4F, 0xE9, -- -- 0x2F, 0x2F, 0x17, 0xAF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xA0, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x31, 0x80, 0x4F, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x57, 0x39, 0x20, 0xE9, -- -- 0x16, 0x28, 0x20, 0xE9, -- 0x1D, 0x3B, 0x20, 0xE9, -- -- 0x1E, 0x2B, 0x20, 0xE9, -- 0x2B, 0x32, 0x20, 0xE9, -- -- 0x1C, 0x23, 0x20, 0xE9, -- 0x57, 0x36, 0x20, 0xE9, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x40, 0x40, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x90, 0xE2, -- 0x00, 0xE0, -- -- 0x68, 0xFF, 0x20, 0xEA, -- 0x19, 0xC8, 0xC1, 0xCD, -- -- 0x1F, 0xD7, 0x18, 0xBD, -- 0x3F, 0xD7, 0x22, 0xBD, -- -- 0x9F, 0x41, 0x49, 0xBD, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x25, 0x41, 0x49, 0xBD, -- 0x2D, 0x41, 0x51, 0xBD, -- -- 0x0D, 0x80, 0x07, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x35, 0x40, 0x48, 0xBD, -- 0x3D, 0x40, 0x50, 0xBD, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x25, 0x30, -- 0x2D, 0x30, -- -- 0x35, 0x30, -- 0xB5, 0x30, -- 0xBD, 0x30, -- 0x3D, 0x30, -- -- 0x9C, 0xA7, 0x5B, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x67, 0xFF, 0x0A, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC9, 0x41, 0xC8, 0xEC, -- 0x42, 0xE1, -- 0x00, 0xE0, -- -- 0x65, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xC8, 0x40, 0xC0, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x62, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- --}; -- --static unsigned char warp_g400_t2gz[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x78, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x69, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x25, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2A, 0x44, 0x54, 0xB4, -- 0x1A, 0x44, 0x64, 0xB4, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x9F, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xBE, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x7D, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gza[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x7C, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x6D, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x29, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0F, 0xCF, 0x74, 0xC6, -- 0x3D, 0xCF, 0x74, 0xC2, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x0F, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB4, -- 0x02, 0x44, 0x64, 0xB4, -- -- 0x2A, 0x44, 0x54, 0xB6, -- 0x1A, 0x44, 0x64, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x9B, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xBA, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x79, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzaf[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x81, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x72, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x2E, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x0F, 0xCF, 0x74, 0xC6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x0F, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB4, -- 0x02, 0x44, 0x64, 0xB4, -- -- 0x2A, 0x44, 0x54, 0xB6, -- 0x1A, 0x44, 0x64, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x3D, 0xCF, 0x75, 0xC6, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x45, 0x55, 0xB6, -- 0x02, 0x45, 0x65, 0xB6, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x3D, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x96, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xB5, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x74, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzf[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x7D, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x6E, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0F, 0xCF, 0x75, 0xC6, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x28, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x31, 0x0F, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x54, 0xB4, -- 0x02, 0x44, 0x64, 0xB4, -- -- 0x2A, 0x45, 0x55, 0xB6, -- 0x1A, 0x45, 0x65, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x9A, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xBB, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x78, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzs[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x85, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x76, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x0F, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x31, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0F, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB4, -- 0x1A, 0x44, 0x64, 0xB4, -- -- 0x0A, 0x45, 0x55, 0xB0, -- 0x02, 0x45, 0x65, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x55, 0xB2, -- 0x1A, 0x45, 0x65, 0xB2, -- -- 0x0A, 0x45, 0x55, 0xB4, -- 0x02, 0x45, 0x65, 0xB4, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x20, -- 0x1A, 0x20, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA7, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x92, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xB2, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x70, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzsa[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x8A, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x7B, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x0F, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x36, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0F, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB4, -- 0x1A, 0x44, 0x64, 0xB4, -- -- 0x0A, 0x45, 0x55, 0xB0, -- 0x02, 0x45, 0x65, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x55, 0xB2, -- 0x1A, 0x45, 0x65, 0xB2, -- -- 0x0A, 0x45, 0x55, 0xB4, -- 0x02, 0x45, 0x65, 0xB4, -- -- 0x0F, 0xCF, 0x74, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB6, -- 0x1A, 0x44, 0x64, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x8D, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xAD, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x6B, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzsaf[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x8E, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x7F, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x0F, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x3A, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0F, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB4, -- 0x1A, 0x44, 0x64, 0xB4, -- -- 0x0A, 0x45, 0x55, 0xB0, -- 0x02, 0x45, 0x65, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x55, 0xB2, -- 0x1A, 0x45, 0x65, 0xB2, -- -- 0x0A, 0x45, 0x55, 0xB4, -- 0x02, 0x45, 0x65, 0xB4, -- -- 0x0F, 0xCF, 0x74, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB6, -- 0x1A, 0x44, 0x64, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x45, 0x55, 0xB6, -- 0x02, 0x45, 0x65, 0xB6, -- -- 0x3D, 0xCF, 0x75, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x3D, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x89, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xA9, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x67, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_t2gzsf[] = { -- -- 0x00, 0x8A, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x0A, 0x40, 0x50, 0xBF, -- 0x2A, 0x40, 0x60, 0xBF, -- -- 0x32, 0x41, 0x51, 0xBF, -- 0x3A, 0x41, 0x61, 0xBF, -- -- 0xC3, 0x6B, -- 0xD3, 0x6B, -- 0x00, 0x8A, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x23, 0x9F, -- 0x00, 0xE0, -- 0x51, 0x04, -- -- 0x90, 0xE2, -- 0x61, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x51, 0x41, 0xE0, 0xEC, -- 0x39, 0x67, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x63, 0xA0, 0xE8, -- -- 0x61, 0x41, 0xE0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x8A, 0x80, 0x15, 0xEA, -- 0x10, 0x04, -- 0x20, 0x04, -- -- 0x61, 0x51, 0xE0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x52, 0xBF, -- 0x0F, 0x52, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x62, 0xBF, -- 0x1E, 0x51, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x0E, 0x61, 0x60, 0xEA, -- -- 0x32, 0x40, 0x50, 0xBD, -- 0x22, 0x40, 0x60, 0xBD, -- -- 0x12, 0x41, 0x51, 0xBD, -- 0x3A, 0x41, 0x61, 0xBD, -- -- 0xBF, 0x2F, 0x0E, 0xBD, -- 0x97, 0xE2, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x35, 0x48, 0xB1, 0xE8, -- 0x3D, 0x59, 0xB1, 0xE8, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x56, 0x31, 0x56, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x66, 0x31, 0x66, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x57, 0x39, 0x57, 0xBF, -- 0x67, 0x39, 0x67, 0xBF, -- -- 0x7B, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x35, 0x00, -- 0x3D, 0x00, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0x8D, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x75, 0xF8, 0xEC, -- 0x35, 0x20, -- 0x3D, 0x20, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x53, 0x53, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x0E, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x48, 0x35, 0x48, 0xBF, -- 0x58, 0x35, 0x58, 0xBF, -- -- 0x68, 0x35, 0x68, 0xBF, -- 0x49, 0x3D, 0x49, 0xBF, -- -- 0x59, 0x3D, 0x59, 0xBF, -- 0x69, 0x3D, 0x69, 0xBF, -- -- 0x63, 0x63, 0x2D, 0xDF, -- 0x4D, 0x7D, 0xF8, 0xEC, -- -- 0x59, 0xE3, -- 0x00, 0xE0, -- 0xB8, 0x38, 0x33, 0xBF, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x18, 0x3A, 0x41, 0xE9, -- -- 0x3F, 0x53, 0xA0, 0xE8, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x63, 0xA0, 0xE8, -- -- 0x50, 0x70, 0xF8, 0xEC, -- 0x2B, 0x50, 0x3C, 0xE9, -- -- 0x1F, 0x0F, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x59, 0x78, 0xF8, 0xEC, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x56, 0x3F, 0x56, 0xDF, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x66, 0x3D, 0x66, 0xDF, -- -- 0x1D, 0x32, 0x41, 0xE9, -- 0x67, 0x3D, 0x67, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3F, 0x57, 0xDF, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x59, 0x3F, 0x59, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x69, 0x3D, 0x69, 0xDF, -- -- 0x48, 0x37, 0x48, 0xDF, -- 0x58, 0x3F, 0x58, 0xDF, -- -- 0x68, 0x3D, 0x68, 0xDF, -- 0x49, 0x37, 0x49, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x0F, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x54, 0xB0, -- 0x02, 0x44, 0x64, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB2, -- 0x1A, 0x44, 0x64, 0xB2, -- -- 0x36, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0F, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x54, 0xB4, -- 0x1A, 0x44, 0x64, 0xB4, -- -- 0x0A, 0x45, 0x55, 0xB0, -- 0x02, 0x45, 0x65, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x55, 0xB2, -- 0x1A, 0x45, 0x65, 0xB2, -- -- 0x0A, 0x45, 0x55, 0xB4, -- 0x02, 0x45, 0x65, 0xB4, -- -- 0x0F, 0xCF, 0x75, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x31, 0x0F, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x55, 0xB6, -- 0x1A, 0x45, 0x65, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x56, 0xBF, -- 0x1A, 0x46, 0x66, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x57, 0xBF, -- 0x02, 0x47, 0x67, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x53, 0xBF, -- 0x1A, 0x43, 0x63, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x48, 0x58, 0xBF, -- 0x02, 0x48, 0x68, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x2A, 0x49, 0x59, 0xBF, -- 0x1A, 0x49, 0x69, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x82, 0x30, 0x57, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x83, 0x38, 0x57, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x84, 0x31, 0x5E, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x85, 0x39, 0x5E, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x87, 0x77, 0x57, 0xE9, -- 0x8B, 0x3E, 0xBF, 0xEA, -- -- 0x80, 0x30, 0x57, 0xE9, -- 0x81, 0x38, 0x57, 0xE9, -- -- 0x82, 0x31, 0x57, 0xE9, -- 0x86, 0x78, 0x57, 0xE9, -- -- 0x83, 0x39, 0x57, 0xE9, -- 0x87, 0x79, 0x57, 0xE9, -- -- 0x30, 0x1F, 0x5F, 0xE9, -- 0x8A, 0x34, 0x20, 0xE9, -- -- 0x8B, 0x3C, 0x20, 0xE9, -- 0x37, 0x50, 0x60, 0xBD, -- -- 0x57, 0x0D, 0x20, 0xE9, -- 0x35, 0x51, 0x61, 0xBD, -- -- 0x2B, 0x50, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x0E, 0x77, -- -- 0x24, 0x51, 0x20, 0xE9, -- 0x8D, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x0E, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x0B, 0x46, 0xA0, 0xE8, -- 0x1B, 0x56, 0xA0, 0xE8, -- -- 0x2B, 0x66, 0xA0, 0xE8, -- 0x0C, 0x47, 0xA0, 0xE8, -- -- 0x1C, 0x57, 0xA0, 0xE8, -- 0x2C, 0x67, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x57, 0x80, 0x57, 0xCF, -- -- 0x66, 0x33, 0x66, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x67, 0x3B, 0x67, 0xCF, -- -- 0x0B, 0x48, 0xA0, 0xE8, -- 0x1B, 0x58, 0xA0, 0xE8, -- -- 0x2B, 0x68, 0xA0, 0xE8, -- 0x0C, 0x49, 0xA0, 0xE8, -- -- 0x1C, 0x59, 0xA0, 0xE8, -- 0x2C, 0x69, 0xA0, 0xE8, -- -- 0x0B, 0x00, -- 0x1B, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x0C, 0x00, -- 0x1C, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x0B, 0x65, -- 0x1B, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x0C, 0x65, -- 0x1C, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x0B, 0x1B, 0x60, 0xEC, -- 0x34, 0xD7, 0x34, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x0C, 0x1C, 0x60, 0xEC, -- -- 0x3C, 0xD7, 0x3C, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x0B, 0x2B, 0xDE, 0xE8, -- 0x1B, 0x80, 0xDE, 0xE8, -- -- 0x34, 0x80, 0x34, 0xBD, -- 0x3C, 0x80, 0x3C, 0xBD, -- -- 0x33, 0xD7, 0x0B, 0xBD, -- 0x3B, 0xD7, 0x1B, 0xBD, -- -- 0x48, 0x80, 0x48, 0xCF, -- 0x59, 0x80, 0x59, 0xCF, -- -- 0x68, 0x33, 0x68, 0xCF, -- 0x49, 0x3B, 0x49, 0xCF, -- -- 0xAD, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x58, 0x33, 0x58, 0xCF, -- 0x69, 0x3B, 0x69, 0xCF, -- -- 0x6B, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgz[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x58, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x4A, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x1D, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x2A, 0x44, 0x4C, 0xB4, -- 0x1A, 0x44, 0x54, 0xB4, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0xAF, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xD6, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x9D, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgza[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x5C, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x4E, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x27, 0xCF, 0x74, 0xC6, -- 0x3D, 0xCF, 0x74, 0xC2, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x20, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x27, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x4C, 0xB4, -- 0x02, 0x44, 0x54, 0xB4, -- -- 0x2A, 0x44, 0x4C, 0xB6, -- 0x1A, 0x44, 0x54, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0xAB, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xD3, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x99, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzaf[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x61, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x53, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x26, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x27, 0xCF, 0x74, 0xC6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x27, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x4C, 0xB4, -- 0x02, 0x44, 0x54, 0xB4, -- -- 0x2A, 0x44, 0x4C, 0xB6, -- 0x1A, 0x44, 0x54, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x3D, 0xCF, 0x75, 0xC6, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x45, 0x4D, 0xB6, -- 0x02, 0x45, 0x55, 0xB6, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x3D, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0xA6, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xCD, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x94, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzf[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x5D, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x4F, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x34, 0x80, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x27, 0xCF, 0x75, 0xC6, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x20, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x3D, 0xCF, 0x74, 0xC2, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x31, 0x27, 0x20, 0xE9, -- -- 0x0A, 0x44, 0x4C, 0xB4, -- 0x02, 0x44, 0x54, 0xB4, -- -- 0x2A, 0x45, 0x4D, 0xB6, -- 0x1A, 0x45, 0x55, 0xB6, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x38, 0x3D, 0x20, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0xAA, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xD3, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x98, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzs[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x65, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x57, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x27, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x29, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x27, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB4, -- 0x1A, 0x44, 0x54, 0xB4, -- -- 0x0A, 0x45, 0x4D, 0xB0, -- 0x02, 0x45, 0x55, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x4D, 0xB2, -- 0x1A, 0x45, 0x55, 0xB2, -- -- 0x0A, 0x45, 0x4D, 0xB4, -- 0x02, 0x45, 0x55, 0xB4, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x20, -- 0x02, 0x20, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA7, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0xA2, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xCA, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x90, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzsa[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x6A, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x5C, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x27, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x2E, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x27, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB4, -- 0x1A, 0x44, 0x54, 0xB4, -- -- 0x0A, 0x45, 0x4D, 0xB0, -- 0x02, 0x45, 0x55, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x4D, 0xB2, -- 0x1A, 0x45, 0x55, 0xB2, -- -- 0x0A, 0x45, 0x4D, 0xB4, -- 0x02, 0x45, 0x55, 0xB4, -- -- 0x27, 0xCF, 0x74, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB6, -- 0x1A, 0x44, 0x54, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0x9D, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xC5, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x8B, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzsaf[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x6E, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x60, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x27, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x32, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x27, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB4, -- 0x1A, 0x44, 0x54, 0xB4, -- -- 0x0A, 0x45, 0x4D, 0xB0, -- 0x02, 0x45, 0x55, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x4D, 0xB2, -- 0x1A, 0x45, 0x55, 0xB2, -- -- 0x0A, 0x45, 0x4D, 0xB4, -- 0x02, 0x45, 0x55, 0xB4, -- -- 0x27, 0xCF, 0x74, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9C, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB6, -- 0x1A, 0x44, 0x54, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x45, 0x4D, 0xB6, -- 0x02, 0x45, 0x55, 0xB6, -- -- 0x3D, 0xCF, 0x75, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x3D, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x9D, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x9E, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x30, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x38, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0x99, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xC1, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x87, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -- --static unsigned char warp_g400_tgzsf[] = { -- -- 0x00, 0x88, 0x98, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- -- 0xFF, 0x80, 0xC0, 0xE9, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x22, 0x40, 0x48, 0xBF, -- 0x2A, 0x40, 0x50, 0xBF, -- -- 0x32, 0x41, 0x49, 0xBF, -- 0x3A, 0x41, 0x51, 0xBF, -- -- 0xC3, 0x6B, -- 0xCB, 0x6B, -- 0x00, 0x88, 0x98, 0xE9, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x96, 0xE2, -- 0x41, 0x04, -- -- 0x7B, 0x43, 0xA0, 0xE8, -- 0x73, 0x4B, 0xA0, 0xE8, -- -- 0xAD, 0xEE, 0x29, 0x9F, -- 0x00, 0xE0, -- 0x49, 0x04, -- -- 0x90, 0xE2, -- 0x51, 0x04, -- 0x31, 0x46, 0xB1, 0xE8, -- -- 0x49, 0x41, 0xC0, 0xEC, -- 0x39, 0x57, 0xB1, 0xE8, -- -- 0x00, 0x04, -- 0x46, 0xE2, -- 0x73, 0x53, 0xA0, 0xE8, -- -- 0x51, 0x41, 0xC0, 0xEC, -- 0x31, 0x00, -- 0x39, 0x00, -- -- 0x6A, 0x80, 0x15, 0xEA, -- 0x08, 0x04, -- 0x10, 0x04, -- -- 0x51, 0x49, 0xC0, 0xEC, -- 0x2F, 0x41, 0x60, 0xEA, -- -- 0x31, 0x20, -- 0x39, 0x20, -- 0x1F, 0x42, 0xA0, 0xE8, -- -- 0x2A, 0x42, 0x4A, 0xBF, -- 0x27, 0x4A, 0xA0, 0xE8, -- -- 0x1A, 0x42, 0x52, 0xBF, -- 0x1E, 0x49, 0x60, 0xEA, -- -- 0x73, 0x7B, 0xC8, 0xEC, -- 0x26, 0x51, 0x60, 0xEA, -- -- 0x32, 0x40, 0x48, 0xBD, -- 0x22, 0x40, 0x50, 0xBD, -- -- 0x12, 0x41, 0x49, 0xBD, -- 0x3A, 0x41, 0x51, 0xBD, -- -- 0xBF, 0x2F, 0x26, 0xBD, -- 0x00, 0xE0, -- 0x7B, 0x72, -- -- 0x32, 0x20, -- 0x22, 0x20, -- 0x12, 0x20, -- 0x3A, 0x20, -- -- 0x46, 0x31, 0x46, 0xBF, -- 0x4E, 0x31, 0x4E, 0xBF, -- -- 0xB3, 0xE2, 0x2D, 0x9F, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x56, 0x31, 0x56, 0xBF, -- 0x47, 0x39, 0x47, 0xBF, -- -- 0x4F, 0x39, 0x4F, 0xBF, -- 0x57, 0x39, 0x57, 0xBF, -- -- 0x5C, 0x80, 0x07, 0xEA, -- 0x24, 0x41, 0x20, 0xE9, -- -- 0x42, 0x73, 0xF8, 0xEC, -- 0x00, 0xE0, -- 0x2D, 0x73, -- -- 0x33, 0x72, -- 0x0C, 0xE3, -- 0xA5, 0x2F, 0x1E, 0xBD, -- -- 0x43, 0x43, 0x2D, 0xDF, -- 0x4B, 0x4B, 0x2D, 0xDF, -- -- 0xAE, 0x1E, 0x26, 0xBD, -- 0x58, 0xE3, -- 0x33, 0x66, -- -- 0x53, 0x53, 0x2D, 0xDF, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0xB8, 0x38, 0x33, 0xBF, -- 0x00, 0xE0, -- 0x59, 0xE3, -- -- 0x1E, 0x12, 0x41, 0xE9, -- 0x1A, 0x22, 0x41, 0xE9, -- -- 0x2B, 0x40, 0x3D, 0xE9, -- 0x3F, 0x4B, 0xA0, 0xE8, -- -- 0x2D, 0x73, -- 0x30, 0x76, -- 0x05, 0x80, 0x3D, 0xEA, -- -- 0x37, 0x43, 0xA0, 0xE8, -- 0x3D, 0x53, 0xA0, 0xE8, -- -- 0x48, 0x70, 0xF8, 0xEC, -- 0x2B, 0x48, 0x3C, 0xE9, -- -- 0x1F, 0x27, 0xBC, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x15, 0xC0, 0x20, 0xE9, -- 0x15, 0xC0, 0x20, 0xE9, -- -- 0x18, 0x3A, 0x41, 0xE9, -- 0x1D, 0x32, 0x41, 0xE9, -- -- 0x2A, 0x40, 0x20, 0xE9, -- 0x56, 0x3D, 0x56, 0xDF, -- -- 0x46, 0x37, 0x46, 0xDF, -- 0x4E, 0x3F, 0x4E, 0xDF, -- -- 0x16, 0x30, 0x20, 0xE9, -- 0x4F, 0x3F, 0x4F, 0xDF, -- -- 0x47, 0x37, 0x47, 0xDF, -- 0x57, 0x3D, 0x57, 0xDF, -- -- 0x32, 0x32, 0x2D, 0xDF, -- 0x22, 0x22, 0x2D, 0xDF, -- -- 0x12, 0x12, 0x2D, 0xDF, -- 0x3A, 0x3A, 0x2D, 0xDF, -- -- 0x27, 0xCF, 0x74, 0xC2, -- 0x37, 0xCF, 0x74, 0xC4, -- -- 0x0A, 0x44, 0x4C, 0xB0, -- 0x02, 0x44, 0x54, 0xB0, -- -- 0x3D, 0xCF, 0x74, 0xC0, -- 0x34, 0x37, 0x20, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x38, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3C, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB2, -- 0x1A, 0x44, 0x54, 0xB2, -- -- 0x2E, 0x80, 0x3A, 0xEA, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x27, 0xCF, 0x75, 0xC0, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x32, 0x31, 0x5F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x33, 0x39, 0x5F, 0xE9, -- -- 0x3D, 0xCF, 0x75, 0xC2, -- 0x37, 0xCF, 0x75, 0xC4, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA6, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA3, 0x3D, 0x20, 0xE9, -- -- 0x2A, 0x44, 0x4C, 0xB4, -- 0x1A, 0x44, 0x54, 0xB4, -- -- 0x0A, 0x45, 0x4D, 0xB0, -- 0x02, 0x45, 0x55, 0xB0, -- -- 0x88, 0x73, 0x5E, 0xE9, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA0, 0x37, 0x20, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x3E, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x3F, 0x38, 0x4F, 0xE9, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x3A, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x3B, 0x39, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x4D, 0xB2, -- 0x1A, 0x45, 0x55, 0xB2, -- -- 0x0A, 0x45, 0x4D, 0xB4, -- 0x02, 0x45, 0x55, 0xB4, -- -- 0x27, 0xCF, 0x75, 0xC6, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0xA7, 0x30, 0x4F, 0xE9, -- 0x0A, 0x20, -- 0x02, 0x20, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x31, 0x27, 0x20, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA8, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x45, 0x4D, 0xB6, -- 0x1A, 0x45, 0x55, 0xB6, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x36, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x37, 0x39, 0x4F, 0xE9, -- -- 0x00, 0x80, 0x00, 0xE8, -- 0x2A, 0x20, -- 0x1A, 0x20, -- -- 0x2A, 0x46, 0x4E, 0xBF, -- 0x1A, 0x46, 0x56, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA4, 0x31, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA5, 0x39, 0x4F, 0xE9, -- -- 0x0A, 0x47, 0x4F, 0xBF, -- 0x02, 0x47, 0x57, 0xBF, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0xA1, 0x30, 0x4F, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0xA2, 0x38, 0x4F, 0xE9, -- -- 0x2A, 0x43, 0x4B, 0xBF, -- 0x1A, 0x43, 0x53, 0xBF, -- -- 0x30, 0x50, 0x2E, 0x9F, -- 0x35, 0x31, 0x4F, 0xE9, -- -- 0x38, 0x21, 0x2C, 0x9F, -- 0x39, 0x39, 0x4F, 0xE9, -- -- 0x31, 0x53, 0x2F, 0x9F, -- 0x80, 0x31, 0x57, 0xE9, -- -- 0x39, 0xE5, 0x2C, 0x9F, -- 0x81, 0x39, 0x57, 0xE9, -- -- 0x37, 0x48, 0x50, 0xBD, -- 0x8A, 0x36, 0x20, 0xE9, -- -- 0x86, 0x76, 0x57, 0xE9, -- 0x8B, 0x3E, 0x20, 0xE9, -- -- 0x82, 0x30, 0x57, 0xE9, -- 0x87, 0x77, 0x57, 0xE9, -- -- 0x83, 0x38, 0x57, 0xE9, -- 0x35, 0x49, 0x51, 0xBD, -- -- 0x84, 0x31, 0x5E, 0xE9, -- 0x30, 0x1F, 0x5F, 0xE9, -- -- 0x85, 0x39, 0x5E, 0xE9, -- 0x57, 0x25, 0x20, 0xE9, -- -- 0x2B, 0x48, 0x20, 0xE9, -- 0x1D, 0x37, 0xE1, 0xEA, -- -- 0x1E, 0x35, 0xE1, 0xEA, -- 0x00, 0xE0, -- 0x26, 0x77, -- -- 0x24, 0x49, 0x20, 0xE9, -- 0x9D, 0xFF, 0x20, 0xEA, -- -- 0x16, 0x26, 0x20, 0xE9, -- 0x57, 0x2E, 0xBF, 0xEA, -- -- 0x1C, 0x46, 0xA0, 0xE8, -- 0x23, 0x4E, 0xA0, 0xE8, -- -- 0x2B, 0x56, 0xA0, 0xE8, -- 0x1D, 0x47, 0xA0, 0xE8, -- -- 0x24, 0x4F, 0xA0, 0xE8, -- 0x2C, 0x57, 0xA0, 0xE8, -- -- 0x1C, 0x00, -- 0x23, 0x00, -- 0x2B, 0x00, -- 0x00, 0xE0, -- -- 0x1D, 0x00, -- 0x24, 0x00, -- 0x2C, 0x00, -- 0x00, 0xE0, -- -- 0x1C, 0x65, -- 0x23, 0x65, -- 0x2B, 0x65, -- 0x00, 0xE0, -- -- 0x1D, 0x65, -- 0x24, 0x65, -- 0x2C, 0x65, -- 0x00, 0xE0, -- -- 0x1C, 0x23, 0x60, 0xEC, -- 0x36, 0xD7, 0x36, 0xAD, -- -- 0x2B, 0x80, 0x60, 0xEC, -- 0x1D, 0x24, 0x60, 0xEC, -- -- 0x3E, 0xD7, 0x3E, 0xAD, -- 0x2C, 0x80, 0x60, 0xEC, -- -- 0x1C, 0x2B, 0xDE, 0xE8, -- 0x23, 0x80, 0xDE, 0xE8, -- -- 0x36, 0x80, 0x36, 0xBD, -- 0x3E, 0x80, 0x3E, 0xBD, -- -- 0x33, 0xD7, 0x1C, 0xBD, -- 0x3B, 0xD7, 0x23, 0xBD, -- -- 0x46, 0x80, 0x46, 0xCF, -- 0x4F, 0x80, 0x4F, 0xCF, -- -- 0x56, 0x33, 0x56, 0xCF, -- 0x47, 0x3B, 0x47, 0xCF, -- -- 0xC5, 0xFF, 0x20, 0xEA, -- 0x00, 0x80, 0x00, 0xE8, -- -- 0x4E, 0x33, 0x4E, 0xCF, -- 0x57, 0x3B, 0x57, 0xCF, -- -- 0x8B, 0xFF, 0x20, 0xEA, -- 0x57, 0xC0, 0xBF, 0xEA, -- -- 0x00, 0x80, 0xA0, 0xE9, -- 0x00, 0x00, 0xD8, 0xEC, -- --}; -diff --git a/drivers/gpu/drm/mga/mga_warp.c b/drivers/gpu/drm/mga/mga_warp.c -index 651b93c..9aad484 100644 ---- a/drivers/gpu/drm/mga/mga_warp.c -+++ b/drivers/gpu/drm/mga/mga_warp.c -@@ -27,132 +27,108 @@ - * Gareth Hughes - */ - -+#include -+#include -+#include -+ - #include "drmP.h" - #include "drm.h" - #include "mga_drm.h" - #include "mga_drv.h" --#include "mga_ucode.h" -+ -+#define FIRMWARE_G200 "matrox/g200_warp.fw" -+#define FIRMWARE_G400 "matrox/g400_warp.fw" -+ -+MODULE_FIRMWARE(FIRMWARE_G200); -+MODULE_FIRMWARE(FIRMWARE_G400); - - #define MGA_WARP_CODE_ALIGN 256 /* in bytes */ - --#define WARP_UCODE_SIZE( which ) \ -- ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN) -- --#define WARP_UCODE_INSTALL( which, where ) \ --do { \ -- DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\ -- dev_priv->warp_pipe_phys[where] = pcbase; \ -- memcpy( vcbase, which, sizeof(which) ); \ -- pcbase += WARP_UCODE_SIZE( which ); \ -- vcbase += WARP_UCODE_SIZE( which ); \ --} while (0) -- --static const unsigned int mga_warp_g400_microcode_size = -- (WARP_UCODE_SIZE(warp_g400_tgz) + -- WARP_UCODE_SIZE(warp_g400_tgza) + -- WARP_UCODE_SIZE(warp_g400_tgzaf) + -- WARP_UCODE_SIZE(warp_g400_tgzf) + -- WARP_UCODE_SIZE(warp_g400_tgzs) + -- WARP_UCODE_SIZE(warp_g400_tgzsa) + -- WARP_UCODE_SIZE(warp_g400_tgzsaf) + -- WARP_UCODE_SIZE(warp_g400_tgzsf) + -- WARP_UCODE_SIZE(warp_g400_t2gz) + -- WARP_UCODE_SIZE(warp_g400_t2gza) + -- WARP_UCODE_SIZE(warp_g400_t2gzaf) + -- WARP_UCODE_SIZE(warp_g400_t2gzf) + -- WARP_UCODE_SIZE(warp_g400_t2gzs) + -- WARP_UCODE_SIZE(warp_g400_t2gzsa) + -- WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf)); -- --static const unsigned int mga_warp_g200_microcode_size = -- (WARP_UCODE_SIZE(warp_g200_tgz) + -- WARP_UCODE_SIZE(warp_g200_tgza) + -- WARP_UCODE_SIZE(warp_g200_tgzaf) + -- WARP_UCODE_SIZE(warp_g200_tgzf) + -- WARP_UCODE_SIZE(warp_g200_tgzs) + -- WARP_UCODE_SIZE(warp_g200_tgzsa) + -- WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf)); -- --unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv) -+#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN) -+ -+int mga_warp_install_microcode(drm_mga_private_t * dev_priv) - { -+ unsigned char *vcbase = dev_priv->warp->handle; -+ unsigned long pcbase = dev_priv->warp->offset; -+ const char *firmware_name; -+ struct platform_device *pdev; -+ const struct firmware *fw = NULL; -+ const struct ihex_binrec *rec; -+ unsigned int size; -+ int n_pipes, where; -+ int rc = 0; -+ - switch (dev_priv->chipset) { - case MGA_CARD_TYPE_G400: - case MGA_CARD_TYPE_G550: -- return PAGE_ALIGN(mga_warp_g400_microcode_size); -+ firmware_name = FIRMWARE_G400; -+ n_pipes = MGA_MAX_G400_PIPES; -+ break; - case MGA_CARD_TYPE_G200: -- return PAGE_ALIGN(mga_warp_g200_microcode_size); -+ firmware_name = FIRMWARE_G200; -+ n_pipes = MGA_MAX_G200_PIPES; -+ break; - default: -- return 0; -+ return -EINVAL; - } --} -- --static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv) --{ -- unsigned char *vcbase = dev_priv->warp->handle; -- unsigned long pcbase = dev_priv->warp->offset; -- -- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); -- -- WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ); -- WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF); -- WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA); -- WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF); -- WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS); -- WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF); -- WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA); -- WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF); -- -- WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ); -- WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF); -- WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA); -- WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF); -- WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS); -- WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF); -- WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA); -- WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF); -- -- return 0; --} -- --static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv) --{ -- unsigned char *vcbase = dev_priv->warp->handle; -- unsigned long pcbase = dev_priv->warp->offset; -- -- memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); -- -- WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ); -- WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF); -- WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA); -- WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF); -- WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS); -- WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF); -- WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA); -- WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF); - -- return 0; --} -+ pdev = platform_device_register_simple("mga_warp", 0, NULL, 0); -+ if (IS_ERR(pdev)) { -+ DRM_ERROR("mga: Failed to register microcode\n"); -+ return PTR_ERR(pdev); -+ } -+ rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); -+ platform_device_unregister(pdev); -+ if (rc) { -+ DRM_ERROR("mga: Failed to load microcode \"%s\"\n", -+ firmware_name); -+ return rc; -+ } - --int mga_warp_install_microcode(drm_mga_private_t * dev_priv) --{ -- const unsigned int size = mga_warp_microcode_size(dev_priv); -+ size = 0; -+ where = 0; -+ for (rec = (const struct ihex_binrec *)fw->data; -+ rec; -+ rec = ihex_next_binrec(rec)) { -+ size += WARP_UCODE_SIZE(be16_to_cpu(rec->len)); -+ where++; -+ } - -+ if (where != n_pipes) { -+ DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name); -+ rc = -EINVAL; -+ goto out; -+ } -+ size = PAGE_ALIGN(size); - DRM_DEBUG("MGA ucode size = %d bytes\n", size); - if (size > dev_priv->warp->size) { - DRM_ERROR("microcode too large! (%u > %lu)\n", - size, dev_priv->warp->size); -- return -ENOMEM; -+ rc = -ENOMEM; -+ goto out; - } - -- switch (dev_priv->chipset) { -- case MGA_CARD_TYPE_G400: -- case MGA_CARD_TYPE_G550: -- return mga_warp_install_g400_microcode(dev_priv); -- case MGA_CARD_TYPE_G200: -- return mga_warp_install_g200_microcode(dev_priv); -- default: -- return -EINVAL; -+ memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); -+ -+ where = 0; -+ for (rec = (const struct ihex_binrec *)fw->data; -+ rec; -+ rec = ihex_next_binrec(rec)) { -+ unsigned int src_size, dst_size; -+ -+ DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase); -+ dev_priv->warp_pipe_phys[where] = pcbase; -+ src_size = be16_to_cpu(rec->len); -+ dst_size = WARP_UCODE_SIZE(src_size); -+ memcpy(vcbase, rec->data, src_size); -+ pcbase += dst_size; -+ vcbase += dst_size; -+ where++; - } -+ -+out: -+ release_firmware(fw); -+ return rc; - } - - #define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE) -diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c -index c75fd35..4c39a40 100644 ---- a/drivers/gpu/drm/r128/r128_cce.c -+++ b/drivers/gpu/drm/r128/r128_cce.c -@@ -29,6 +29,9 @@ - * Gareth Hughes - */ - -+#include -+#include -+ - #include "drmP.h" - #include "drm.h" - #include "r128_drm.h" -@@ -36,50 +39,9 @@ - - #define R128_FIFO_DEBUG 0 - --/* CCE microcode (from ATI) */ --static u32 r128_cce_microcode[] = { -- 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0, -- 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0, -- 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1, -- 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11, -- 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28, -- 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9, -- 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656, -- 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1, -- 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071, -- 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2, -- 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1, -- 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1, -- 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1, -- 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2, -- 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1, -- 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82, -- 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729, -- 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008, -- 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0, -- 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1, -- 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1, -- 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0, -- 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370, -- 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1, -- 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793, -- 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1, -- 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1, -- 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1, -- 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1, -- 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894, -- 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14, -- 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1, -- 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1, -- 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1, -- 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 --}; -+#define FIRMWARE_NAME "r128/r128_cce.bin" -+ -+MODULE_FIRMWARE(FIRMWARE_NAME); - - static int R128_READ_PLL(struct drm_device * dev, int addr) - { -@@ -176,20 +138,50 @@ static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv) - */ - - /* Load the microcode for the CCE */ --static void r128_cce_load_microcode(drm_r128_private_t * dev_priv) -+static int r128_cce_load_microcode(drm_r128_private_t *dev_priv) - { -- int i; -+ struct platform_device *pdev; -+ const struct firmware *fw; -+ const __be32 *fw_data; -+ int rc, i; - - DRM_DEBUG("\n"); - -+ pdev = platform_device_register_simple("r128_cce", 0, NULL, 0); -+ if (IS_ERR(pdev)) { -+ printk(KERN_ERR "r128_cce: Failed to register firmware\n"); -+ return PTR_ERR(pdev); -+ } -+ rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); -+ platform_device_unregister(pdev); -+ if (rc) { -+ printk(KERN_ERR "r128_cce: Failed to load firmware \"%s\"\n", -+ FIRMWARE_NAME); -+ return rc; -+ } -+ -+ if (fw->size != 256 * 8) { -+ printk(KERN_ERR -+ "r128_cce: Bogus length %zu in firmware \"%s\"\n", -+ fw->size, FIRMWARE_NAME); -+ rc = -EINVAL; -+ goto out_release; -+ } -+ - r128_do_wait_for_idle(dev_priv); - -+ fw_data = (const __be32 *)fw->data; - R128_WRITE(R128_PM4_MICROCODE_ADDR, 0); - for (i = 0; i < 256; i++) { -- R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]); -+ R128_WRITE(R128_PM4_MICROCODE_DATAH, -+ be32_to_cpup(&fw_data[i * 2])); - R128_WRITE(R128_PM4_MICROCODE_DATAL, -- r128_cce_microcode[i * 2 + 1]); -+ be32_to_cpup(&fw_data[i * 2 + 1])); - } -+ -+out_release: -+ release_firmware(fw); -+ return rc; - } - - /* Flush any pending commands to the CCE. This should only be used just -@@ -350,9 +342,15 @@ static void r128_cce_init_ring_buffer(struct drm_device * dev, - static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) - { - drm_r128_private_t *dev_priv; -+ int rc; - - DRM_DEBUG("\n"); - -+ if (dev->dev_private) { -+ DRM_DEBUG("called when already initialized\n"); -+ return -EINVAL; -+ } -+ - dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; -@@ -575,13 +573,18 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) - #endif - - r128_cce_init_ring_buffer(dev, dev_priv); -- r128_cce_load_microcode(dev_priv); -+ rc = r128_cce_load_microcode(dev_priv); - - dev->dev_private = (void *)dev_priv; - - r128_do_engine_reset(dev); - -- return 0; -+ if (rc) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ r128_do_cleanup_cce(dev); -+ } -+ -+ return rc; - } - - int r128_do_cleanup_cce(struct drm_device * dev) -@@ -649,6 +652,8 @@ int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_pri - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) { - DRM_DEBUG("while CCE running\n"); - return 0; -@@ -671,6 +676,8 @@ int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - /* Flush any pending CCE commands. This ensures any outstanding - * commands are exectuted by the engine before we turn it off. - */ -@@ -708,10 +715,7 @@ int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_pri - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -- if (!dev_priv) { -- DRM_DEBUG("called before init done\n"); -- return -EINVAL; -- } -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); - - r128_do_cce_reset(dev_priv); - -@@ -728,6 +732,8 @@ int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - if (dev_priv->cce_running) { - r128_do_cce_flush(dev_priv); - } -@@ -741,6 +747,8 @@ int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_ - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev->dev_private); -+ - return r128_do_engine_reset(dev); - } - -diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h -index 797a26c..3c60829 100644 ---- a/drivers/gpu/drm/r128/r128_drv.h -+++ b/drivers/gpu/drm/r128/r128_drv.h -@@ -422,6 +422,14 @@ static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv) - * Misc helper macros - */ - -+#define DEV_INIT_TEST_WITH_RETURN(_dev_priv) \ -+do { \ -+ if (!_dev_priv) { \ -+ DRM_ERROR("called with no initialization\n"); \ -+ return -EINVAL; \ -+ } \ -+} while (0) -+ - #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \ - do { \ - drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \ -diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c -index 026a48c..af2665c 100644 ---- a/drivers/gpu/drm/r128/r128_state.c -+++ b/drivers/gpu/drm/r128/r128_state.c -@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple) - static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv) - { - drm_r128_private_t *dev_priv = dev->dev_private; -- drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; -+ drm_r128_sarea_t *sarea_priv; - drm_r128_clear_t *clear = data; - DRM_DEBUG("\n"); - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - RING_SPACE_TEST_WITH_RETURN(dev_priv); - -+ sarea_priv = dev_priv->sarea_priv; -+ - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - -@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *fi - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (!dev_priv->page_flipping) -@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *fi - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS) -@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file * - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -- if (!dev_priv) { -- DRM_ERROR("called with no initialization\n"); -- return -EINVAL; -- } -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n", - DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard); -@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -- if (!dev_priv) { -- DRM_ERROR("called with no initialization\n"); -- return -EINVAL; -- } -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID, - elts->idx, elts->start, elts->end, elts->discard); -@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *fi - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx); - - if (blit->idx < 0 || blit->idx >= dma->buf_count) { -@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *f - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - RING_SPACE_TEST_WITH_RETURN(dev_priv); - - ret = -EINVAL; -@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); -+ - if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32))) - return -EFAULT; - -@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file - - LOCK_TEST_WITH_RETURN(dev, file_priv); - -- if (!dev_priv) { -- DRM_ERROR("called with no initialization\n"); -- return -EINVAL; -- } -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("idx=%d s=%d e=%d d=%d\n", - indirect->idx, indirect->start, indirect->end, -@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi - drm_r128_getparam_t *param = data; - int value; - -- if (!dev_priv) { -- DRM_ERROR("called with no initialization\n"); -- return -EINVAL; -- } -+ DEV_INIT_TEST_WITH_RETURN(dev_priv); - - DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); - -diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig -index 2168d67..5982321 100644 ---- a/drivers/gpu/drm/radeon/Kconfig -+++ b/drivers/gpu/drm/radeon/Kconfig -@@ -1,7 +1,6 @@ - config DRM_RADEON_KMS - bool "Enable modesetting on radeon by default" - depends on DRM_RADEON -- select DRM_TTM - help - Choose this option if you want kernel modesetting enabled by default, - and you have a new enough userspace to support this. Running old -diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile -index 013d380..09a2892 100644 ---- a/drivers/gpu/drm/radeon/Makefile -+++ b/drivers/gpu/drm/radeon/Makefile -@@ -3,18 +3,53 @@ - # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. - - ccflags-y := -Iinclude/drm -+ -+hostprogs-y := mkregtable -+ -+quiet_cmd_mkregtable = MKREGTABLE $@ -+ cmd_mkregtable = $(obj)/mkregtable $< > $@ -+ -+$(obj)/rn50_reg_safe.h: $(src)/reg_srcs/rn50 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/r100_reg_safe.h: $(src)/reg_srcs/r100 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/r200_reg_safe.h: $(src)/reg_srcs/r200 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/rv515_reg_safe.h: $(src)/reg_srcs/rv515 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/r300_reg_safe.h: $(src)/reg_srcs/r300 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/rs600_reg_safe.h: $(src)/reg_srcs/rs600 $(obj)/mkregtable -+ $(call if_changed,mkregtable) -+ -+$(obj)/r100.o: $(obj)/r100_reg_safe.h $(obj)/rn50_reg_safe.h -+ -+$(obj)/r200.o: $(obj)/r200_reg_safe.h -+ -+$(obj)/rv515.o: $(obj)/rv515_reg_safe.h -+ -+$(obj)/r300.o: $(obj)/r300_reg_safe.h -+ -+$(obj)/rs600.o: $(obj)/rs600_reg_safe.h -+ - radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ - radeon_irq.o r300_cmdbuf.o r600_cp.o -- --radeon-$(CONFIG_DRM_RADEON_KMS) += radeon_device.o radeon_kms.o \ -+# add KMS driver -+radeon-y += radeon_device.o radeon_kms.o \ - radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \ - atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \ - radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ - radeon_encoders.o radeon_display.o radeon_cursor.o radeon_i2c.o \ - radeon_clocks.o radeon_fb.o radeon_gem.o radeon_ring.o radeon_irq_kms.o \ - radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ -- rs400.o rs600.o rs690.o rv515.o r520.o r600.o rs780.o rv770.o \ -- radeon_test.o -+ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ -+ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ -+ r600_blit_kms.o - - radeon-$(CONFIG_COMPAT) += radeon_ioc32.o - -diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h -index cf67928..5d40208 100644 ---- a/drivers/gpu/drm/radeon/atombios.h -+++ b/drivers/gpu/drm/radeon/atombios.h -@@ -2374,6 +2374,17 @@ typedef struct _ATOM_ANALOG_TV_INFO { - ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; - } ATOM_ANALOG_TV_INFO; - -+#define MAX_SUPPORTED_TV_TIMING_V1_2 3 -+ -+typedef struct _ATOM_ANALOG_TV_INFO_V1_2 { -+ ATOM_COMMON_TABLE_HEADER sHeader; -+ UCHAR ucTV_SupportedStandard; -+ UCHAR ucTV_BootUpDefaultStandard; -+ UCHAR ucExt_TV_ASIC_ID; -+ UCHAR ucExt_TV_ASIC_SlaveAddr; -+ ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; -+} ATOM_ANALOG_TV_INFO_V1_2; -+ - /**************************************************************************/ - /* VRAM usage and their defintions */ - -diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c -index 74d034f..a7edd0f 100644 ---- a/drivers/gpu/drm/radeon/atombios_crtc.c -+++ b/drivers/gpu/drm/radeon/atombios_crtc.c -@@ -31,6 +31,10 @@ - #include "atom.h" - #include "atom-bits.h" - -+/* evil but including atombios.h is much worse */ -+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, -+ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, -+ int32_t *pixel_clock); - static void atombios_overscan_setup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -@@ -89,17 +93,32 @@ static void atombios_scaler_setup(struct drm_crtc *crtc) - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - ENABLE_SCALER_PS_ALLOCATION args; - int index = GetIndexIntoMasterTable(COMMAND, EnableScaler); -+ - /* fixme - fill in enc_priv for atom dac */ - enum radeon_tv_std tv_std = TV_STD_NTSC; -+ bool is_tv = false, is_cv = false; -+ struct drm_encoder *encoder; - - if (!ASIC_IS_AVIVO(rdev) && radeon_crtc->crtc_id) - return; - -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ /* find tv std */ -+ if (encoder->crtc == crtc) { -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { -+ struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; -+ tv_std = tv_dac->tv_std; -+ is_tv = true; -+ } -+ } -+ } -+ - memset(&args, 0, sizeof(args)); - - args.ucScaler = radeon_crtc->crtc_id; - -- if (radeon_crtc->devices & (ATOM_DEVICE_TV_SUPPORT)) { -+ if (is_tv) { - switch (tv_std) { - case TV_STD_NTSC: - default: -@@ -128,7 +147,7 @@ static void atombios_scaler_setup(struct drm_crtc *crtc) - break; - } - args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; -- } else if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT)) { -+ } else if (is_cv) { - args.ucTVStandard = ATOM_TV_CV; - args.ucEnable = SCALER_ENABLE_MULTITAP_MODE; - } else { -@@ -151,9 +170,9 @@ static void atombios_scaler_setup(struct drm_crtc *crtc) - } - } - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); -- if (radeon_crtc->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT) -- && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_RV570) { -- atom_rv515_force_tv_scaler(rdev); -+ if ((is_tv || is_cv) -+ && rdev->family >= CHIP_RV515 && rdev->family <= CHIP_R580) { -+ atom_rv515_force_tv_scaler(rdev, radeon_crtc); - } - } - -@@ -370,6 +389,7 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - pll_flags |= RADEON_PLL_USE_REF_DIV; - } - radeon_encoder = to_radeon_encoder(encoder); -+ break; - } - } - -@@ -551,42 +571,68 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, - struct radeon_device *rdev = dev->dev_private; - struct drm_encoder *encoder; - SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; -+ int need_tv_timings = 0; -+ bool ret; - - /* TODO color tiling */ - memset(&crtc_timing, 0, sizeof(crtc_timing)); - -- /* TODO tv */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -- -+ /* find tv std */ -+ if (encoder->crtc == crtc) { -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ -+ if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { -+ struct radeon_encoder_atom_dac *tv_dac = radeon_encoder->enc_priv; -+ if (tv_dac) { -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M) -+ need_tv_timings = 1; -+ else -+ need_tv_timings = 2; -+ break; -+ } -+ } -+ } - } - - crtc_timing.ucCRTC = radeon_crtc->crtc_id; -- crtc_timing.usH_Total = adjusted_mode->crtc_htotal; -- crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; -- crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; -- crtc_timing.usH_SyncWidth = -- adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; -+ if (need_tv_timings) { -+ ret = radeon_atom_get_tv_timings(rdev, need_tv_timings - 1, -+ &crtc_timing, &adjusted_mode->clock); -+ if (ret == false) -+ need_tv_timings = 0; -+ } - -- crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; -- crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; -- crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; -- crtc_timing.usV_SyncWidth = -- adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; -+ if (!need_tv_timings) { -+ crtc_timing.usH_Total = adjusted_mode->crtc_htotal; -+ crtc_timing.usH_Disp = adjusted_mode->crtc_hdisplay; -+ crtc_timing.usH_SyncStart = adjusted_mode->crtc_hsync_start; -+ crtc_timing.usH_SyncWidth = -+ adjusted_mode->crtc_hsync_end - adjusted_mode->crtc_hsync_start; - -- if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) -- crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; -+ crtc_timing.usV_Total = adjusted_mode->crtc_vtotal; -+ crtc_timing.usV_Disp = adjusted_mode->crtc_vdisplay; -+ crtc_timing.usV_SyncStart = adjusted_mode->crtc_vsync_start; -+ crtc_timing.usV_SyncWidth = -+ adjusted_mode->crtc_vsync_end - adjusted_mode->crtc_vsync_start; - -- if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) -- crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; -+ if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) -+ crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; - -- if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) -- crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; -+ if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) -+ crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; - -- if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) -- crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; -+ if (adjusted_mode->flags & DRM_MODE_FLAG_CSYNC) -+ crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC; - -- if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) -- crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; -+ if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) -+ crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE; -+ -+ if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) -+ crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE; -+ } - - atombios_crtc_set_pll(crtc, adjusted_mode); - atombios_crtc_set_timing(crtc, &crtc_timing); -diff --git a/drivers/gpu/drm/radeon/avivod.h b/drivers/gpu/drm/radeon/avivod.h -new file mode 100644 -index 0000000..d4e6e6e ---- /dev/null -+++ b/drivers/gpu/drm/radeon/avivod.h -@@ -0,0 +1,60 @@ -+/* -+ * Copyright 2009 Advanced Micro Devices, Inc. -+ * Copyright 2009 Red Hat Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef AVIVOD_H -+#define AVIVOD_H -+ -+ -+#define D1CRTC_CONTROL 0x6080 -+#define CRTC_EN (1 << 0) -+#define D1CRTC_UPDATE_LOCK 0x60E8 -+#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 -+#define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 -+ -+#define D2CRTC_CONTROL 0x6880 -+#define D2CRTC_UPDATE_LOCK 0x68E8 -+#define D2GRPH_PRIMARY_SURFACE_ADDRESS 0x6910 -+#define D2GRPH_SECONDARY_SURFACE_ADDRESS 0x6918 -+ -+#define D1VGA_CONTROL 0x0330 -+#define DVGA_CONTROL_MODE_ENABLE (1 << 0) -+#define DVGA_CONTROL_TIMING_SELECT (1 << 8) -+#define DVGA_CONTROL_SYNC_POLARITY_SELECT (1 << 9) -+#define DVGA_CONTROL_OVERSCAN_TIMING_SELECT (1 << 10) -+#define DVGA_CONTROL_OVERSCAN_COLOR_EN (1 << 16) -+#define DVGA_CONTROL_ROTATE (1 << 24) -+#define D2VGA_CONTROL 0x0338 -+ -+#define VGA_HDP_CONTROL 0x328 -+#define VGA_MEM_PAGE_SELECT_EN (1 << 0) -+#define VGA_MEMORY_DISABLE (1 << 4) -+#define VGA_RBBM_LOCK_DISABLE (1 << 8) -+#define VGA_SOFT_RESET (1 << 16) -+#define VGA_MEMORY_BASE_ADDRESS 0x0310 -+#define VGA_RENDER_CONTROL 0x0300 -+#define VGA_VSTATUS_CNTL_MASK 0x00030000 -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c -new file mode 100644 -index 0000000..fb211e5 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/mkregtable.c -@@ -0,0 +1,720 @@ -+/* utility to create the register check tables -+ * this includes inlined list.h safe for userspace. -+ * -+ * Copyright 2009 Jerome Glisse -+ * Copyright 2009 Red Hat Inc. -+ * -+ * Authors: -+ * Jerome Glisse -+ * Dave Airlie -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -+/** -+ * container_of - cast a member of a structure out to the containing structure -+ * @ptr: the pointer to the member. -+ * @type: the type of the container struct this is embedded in. -+ * @member: the name of the member within the struct. -+ * -+ */ -+#define container_of(ptr, type, member) ({ \ -+ const typeof(((type *)0)->member)*__mptr = (ptr); \ -+ (type *)((char *)__mptr - offsetof(type, member)); }) -+ -+/* -+ * Simple doubly linked list implementation. -+ * -+ * Some of the internal functions ("__xxx") are useful when -+ * manipulating whole lists rather than single entries, as -+ * sometimes we already know the next/prev entries and we can -+ * generate better code by using them directly rather than -+ * using the generic single-entry routines. -+ */ -+ -+struct list_head { -+ struct list_head *next, *prev; -+}; -+ -+#define LIST_HEAD_INIT(name) { &(name), &(name) } -+ -+#define LIST_HEAD(name) \ -+ struct list_head name = LIST_HEAD_INIT(name) -+ -+static inline void INIT_LIST_HEAD(struct list_head *list) -+{ -+ list->next = list; -+ list->prev = list; -+} -+ -+/* -+ * Insert a new entry between two known consecutive entries. -+ * -+ * This is only for internal list manipulation where we know -+ * the prev/next entries already! -+ */ -+#ifndef CONFIG_DEBUG_LIST -+static inline void __list_add(struct list_head *new, -+ struct list_head *prev, struct list_head *next) -+{ -+ next->prev = new; -+ new->next = next; -+ new->prev = prev; -+ prev->next = new; -+} -+#else -+extern void __list_add(struct list_head *new, -+ struct list_head *prev, struct list_head *next); -+#endif -+ -+/** -+ * list_add - add a new entry -+ * @new: new entry to be added -+ * @head: list head to add it after -+ * -+ * Insert a new entry after the specified head. -+ * This is good for implementing stacks. -+ */ -+static inline void list_add(struct list_head *new, struct list_head *head) -+{ -+ __list_add(new, head, head->next); -+} -+ -+/** -+ * list_add_tail - add a new entry -+ * @new: new entry to be added -+ * @head: list head to add it before -+ * -+ * Insert a new entry before the specified head. -+ * This is useful for implementing queues. -+ */ -+static inline void list_add_tail(struct list_head *new, struct list_head *head) -+{ -+ __list_add(new, head->prev, head); -+} -+ -+/* -+ * Delete a list entry by making the prev/next entries -+ * point to each other. -+ * -+ * This is only for internal list manipulation where we know -+ * the prev/next entries already! -+ */ -+static inline void __list_del(struct list_head *prev, struct list_head *next) -+{ -+ next->prev = prev; -+ prev->next = next; -+} -+ -+/** -+ * list_del - deletes entry from list. -+ * @entry: the element to delete from the list. -+ * Note: list_empty() on entry does not return true after this, the entry is -+ * in an undefined state. -+ */ -+#ifndef CONFIG_DEBUG_LIST -+static inline void list_del(struct list_head *entry) -+{ -+ __list_del(entry->prev, entry->next); -+ entry->next = (void *)0xDEADBEEF; -+ entry->prev = (void *)0xBEEFDEAD; -+} -+#else -+extern void list_del(struct list_head *entry); -+#endif -+ -+/** -+ * list_replace - replace old entry by new one -+ * @old : the element to be replaced -+ * @new : the new element to insert -+ * -+ * If @old was empty, it will be overwritten. -+ */ -+static inline void list_replace(struct list_head *old, struct list_head *new) -+{ -+ new->next = old->next; -+ new->next->prev = new; -+ new->prev = old->prev; -+ new->prev->next = new; -+} -+ -+static inline void list_replace_init(struct list_head *old, -+ struct list_head *new) -+{ -+ list_replace(old, new); -+ INIT_LIST_HEAD(old); -+} -+ -+/** -+ * list_del_init - deletes entry from list and reinitialize it. -+ * @entry: the element to delete from the list. -+ */ -+static inline void list_del_init(struct list_head *entry) -+{ -+ __list_del(entry->prev, entry->next); -+ INIT_LIST_HEAD(entry); -+} -+ -+/** -+ * list_move - delete from one list and add as another's head -+ * @list: the entry to move -+ * @head: the head that will precede our entry -+ */ -+static inline void list_move(struct list_head *list, struct list_head *head) -+{ -+ __list_del(list->prev, list->next); -+ list_add(list, head); -+} -+ -+/** -+ * list_move_tail - delete from one list and add as another's tail -+ * @list: the entry to move -+ * @head: the head that will follow our entry -+ */ -+static inline void list_move_tail(struct list_head *list, -+ struct list_head *head) -+{ -+ __list_del(list->prev, list->next); -+ list_add_tail(list, head); -+} -+ -+/** -+ * list_is_last - tests whether @list is the last entry in list @head -+ * @list: the entry to test -+ * @head: the head of the list -+ */ -+static inline int list_is_last(const struct list_head *list, -+ const struct list_head *head) -+{ -+ return list->next == head; -+} -+ -+/** -+ * list_empty - tests whether a list is empty -+ * @head: the list to test. -+ */ -+static inline int list_empty(const struct list_head *head) -+{ -+ return head->next == head; -+} -+ -+/** -+ * list_empty_careful - tests whether a list is empty and not being modified -+ * @head: the list to test -+ * -+ * Description: -+ * tests whether a list is empty _and_ checks that no other CPU might be -+ * in the process of modifying either member (next or prev) -+ * -+ * NOTE: using list_empty_careful() without synchronization -+ * can only be safe if the only activity that can happen -+ * to the list entry is list_del_init(). Eg. it cannot be used -+ * if another CPU could re-list_add() it. -+ */ -+static inline int list_empty_careful(const struct list_head *head) -+{ -+ struct list_head *next = head->next; -+ return (next == head) && (next == head->prev); -+} -+ -+/** -+ * list_is_singular - tests whether a list has just one entry. -+ * @head: the list to test. -+ */ -+static inline int list_is_singular(const struct list_head *head) -+{ -+ return !list_empty(head) && (head->next == head->prev); -+} -+ -+static inline void __list_cut_position(struct list_head *list, -+ struct list_head *head, -+ struct list_head *entry) -+{ -+ struct list_head *new_first = entry->next; -+ list->next = head->next; -+ list->next->prev = list; -+ list->prev = entry; -+ entry->next = list; -+ head->next = new_first; -+ new_first->prev = head; -+} -+ -+/** -+ * list_cut_position - cut a list into two -+ * @list: a new list to add all removed entries -+ * @head: a list with entries -+ * @entry: an entry within head, could be the head itself -+ * and if so we won't cut the list -+ * -+ * This helper moves the initial part of @head, up to and -+ * including @entry, from @head to @list. You should -+ * pass on @entry an element you know is on @head. @list -+ * should be an empty list or a list you do not care about -+ * losing its data. -+ * -+ */ -+static inline void list_cut_position(struct list_head *list, -+ struct list_head *head, -+ struct list_head *entry) -+{ -+ if (list_empty(head)) -+ return; -+ if (list_is_singular(head) && (head->next != entry && head != entry)) -+ return; -+ if (entry == head) -+ INIT_LIST_HEAD(list); -+ else -+ __list_cut_position(list, head, entry); -+} -+ -+static inline void __list_splice(const struct list_head *list, -+ struct list_head *prev, struct list_head *next) -+{ -+ struct list_head *first = list->next; -+ struct list_head *last = list->prev; -+ -+ first->prev = prev; -+ prev->next = first; -+ -+ last->next = next; -+ next->prev = last; -+} -+ -+/** -+ * list_splice - join two lists, this is designed for stacks -+ * @list: the new list to add. -+ * @head: the place to add it in the first list. -+ */ -+static inline void list_splice(const struct list_head *list, -+ struct list_head *head) -+{ -+ if (!list_empty(list)) -+ __list_splice(list, head, head->next); -+} -+ -+/** -+ * list_splice_tail - join two lists, each list being a queue -+ * @list: the new list to add. -+ * @head: the place to add it in the first list. -+ */ -+static inline void list_splice_tail(struct list_head *list, -+ struct list_head *head) -+{ -+ if (!list_empty(list)) -+ __list_splice(list, head->prev, head); -+} -+ -+/** -+ * list_splice_init - join two lists and reinitialise the emptied list. -+ * @list: the new list to add. -+ * @head: the place to add it in the first list. -+ * -+ * The list at @list is reinitialised -+ */ -+static inline void list_splice_init(struct list_head *list, -+ struct list_head *head) -+{ -+ if (!list_empty(list)) { -+ __list_splice(list, head, head->next); -+ INIT_LIST_HEAD(list); -+ } -+} -+ -+/** -+ * list_splice_tail_init - join two lists and reinitialise the emptied list -+ * @list: the new list to add. -+ * @head: the place to add it in the first list. -+ * -+ * Each of the lists is a queue. -+ * The list at @list is reinitialised -+ */ -+static inline void list_splice_tail_init(struct list_head *list, -+ struct list_head *head) -+{ -+ if (!list_empty(list)) { -+ __list_splice(list, head->prev, head); -+ INIT_LIST_HEAD(list); -+ } -+} -+ -+/** -+ * list_entry - get the struct for this entry -+ * @ptr: the &struct list_head pointer. -+ * @type: the type of the struct this is embedded in. -+ * @member: the name of the list_struct within the struct. -+ */ -+#define list_entry(ptr, type, member) \ -+ container_of(ptr, type, member) -+ -+/** -+ * list_first_entry - get the first element from a list -+ * @ptr: the list head to take the element from. -+ * @type: the type of the struct this is embedded in. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Note, that list is expected to be not empty. -+ */ -+#define list_first_entry(ptr, type, member) \ -+ list_entry((ptr)->next, type, member) -+ -+/** -+ * list_for_each - iterate over a list -+ * @pos: the &struct list_head to use as a loop cursor. -+ * @head: the head for your list. -+ */ -+#define list_for_each(pos, head) \ -+ for (pos = (head)->next; prefetch(pos->next), pos != (head); \ -+ pos = pos->next) -+ -+/** -+ * __list_for_each - iterate over a list -+ * @pos: the &struct list_head to use as a loop cursor. -+ * @head: the head for your list. -+ * -+ * This variant differs from list_for_each() in that it's the -+ * simplest possible list iteration code, no prefetching is done. -+ * Use this for code that knows the list to be very short (empty -+ * or 1 entry) most of the time. -+ */ -+#define __list_for_each(pos, head) \ -+ for (pos = (head)->next; pos != (head); pos = pos->next) -+ -+/** -+ * list_for_each_prev - iterate over a list backwards -+ * @pos: the &struct list_head to use as a loop cursor. -+ * @head: the head for your list. -+ */ -+#define list_for_each_prev(pos, head) \ -+ for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ -+ pos = pos->prev) -+ -+/** -+ * list_for_each_safe - iterate over a list safe against removal of list entry -+ * @pos: the &struct list_head to use as a loop cursor. -+ * @n: another &struct list_head to use as temporary storage -+ * @head: the head for your list. -+ */ -+#define list_for_each_safe(pos, n, head) \ -+ for (pos = (head)->next, n = pos->next; pos != (head); \ -+ pos = n, n = pos->next) -+ -+/** -+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry -+ * @pos: the &struct list_head to use as a loop cursor. -+ * @n: another &struct list_head to use as temporary storage -+ * @head: the head for your list. -+ */ -+#define list_for_each_prev_safe(pos, n, head) \ -+ for (pos = (head)->prev, n = pos->prev; \ -+ prefetch(pos->prev), pos != (head); \ -+ pos = n, n = pos->prev) -+ -+/** -+ * list_for_each_entry - iterate over list of given type -+ * @pos: the type * to use as a loop cursor. -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ */ -+#define list_for_each_entry(pos, head, member) \ -+ for (pos = list_entry((head)->next, typeof(*pos), member); \ -+ &pos->member != (head); \ -+ pos = list_entry(pos->member.next, typeof(*pos), member)) -+ -+/** -+ * list_for_each_entry_reverse - iterate backwards over list of given type. -+ * @pos: the type * to use as a loop cursor. -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ */ -+#define list_for_each_entry_reverse(pos, head, member) \ -+ for (pos = list_entry((head)->prev, typeof(*pos), member); \ -+ prefetch(pos->member.prev), &pos->member != (head); \ -+ pos = list_entry(pos->member.prev, typeof(*pos), member)) -+ -+/** -+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() -+ * @pos: the type * to use as a start point -+ * @head: the head of the list -+ * @member: the name of the list_struct within the struct. -+ * -+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue(). -+ */ -+#define list_prepare_entry(pos, head, member) \ -+ ((pos) ? : list_entry(head, typeof(*pos), member)) -+ -+/** -+ * list_for_each_entry_continue - continue iteration over list of given type -+ * @pos: the type * to use as a loop cursor. -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Continue to iterate over list of given type, continuing after -+ * the current position. -+ */ -+#define list_for_each_entry_continue(pos, head, member) \ -+ for (pos = list_entry(pos->member.next, typeof(*pos), member); \ -+ prefetch(pos->member.next), &pos->member != (head); \ -+ pos = list_entry(pos->member.next, typeof(*pos), member)) -+ -+/** -+ * list_for_each_entry_continue_reverse - iterate backwards from the given point -+ * @pos: the type * to use as a loop cursor. -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Start to iterate over list of given type backwards, continuing after -+ * the current position. -+ */ -+#define list_for_each_entry_continue_reverse(pos, head, member) \ -+ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ -+ prefetch(pos->member.prev), &pos->member != (head); \ -+ pos = list_entry(pos->member.prev, typeof(*pos), member)) -+ -+/** -+ * list_for_each_entry_from - iterate over list of given type from the current point -+ * @pos: the type * to use as a loop cursor. -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Iterate over list of given type, continuing from current position. -+ */ -+#define list_for_each_entry_from(pos, head, member) \ -+ for (; prefetch(pos->member.next), &pos->member != (head); \ -+ pos = list_entry(pos->member.next, typeof(*pos), member)) -+ -+/** -+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry -+ * @pos: the type * to use as a loop cursor. -+ * @n: another type * to use as temporary storage -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ */ -+#define list_for_each_entry_safe(pos, n, head, member) \ -+ for (pos = list_entry((head)->next, typeof(*pos), member), \ -+ n = list_entry(pos->member.next, typeof(*pos), member); \ -+ &pos->member != (head); \ -+ pos = n, n = list_entry(n->member.next, typeof(*n), member)) -+ -+/** -+ * list_for_each_entry_safe_continue -+ * @pos: the type * to use as a loop cursor. -+ * @n: another type * to use as temporary storage -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Iterate over list of given type, continuing after current point, -+ * safe against removal of list entry. -+ */ -+#define list_for_each_entry_safe_continue(pos, n, head, member) \ -+ for (pos = list_entry(pos->member.next, typeof(*pos), member), \ -+ n = list_entry(pos->member.next, typeof(*pos), member); \ -+ &pos->member != (head); \ -+ pos = n, n = list_entry(n->member.next, typeof(*n), member)) -+ -+/** -+ * list_for_each_entry_safe_from -+ * @pos: the type * to use as a loop cursor. -+ * @n: another type * to use as temporary storage -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Iterate over list of given type from current point, safe against -+ * removal of list entry. -+ */ -+#define list_for_each_entry_safe_from(pos, n, head, member) \ -+ for (n = list_entry(pos->member.next, typeof(*pos), member); \ -+ &pos->member != (head); \ -+ pos = n, n = list_entry(n->member.next, typeof(*n), member)) -+ -+/** -+ * list_for_each_entry_safe_reverse -+ * @pos: the type * to use as a loop cursor. -+ * @n: another type * to use as temporary storage -+ * @head: the head for your list. -+ * @member: the name of the list_struct within the struct. -+ * -+ * Iterate backwards over list of given type, safe against removal -+ * of list entry. -+ */ -+#define list_for_each_entry_safe_reverse(pos, n, head, member) \ -+ for (pos = list_entry((head)->prev, typeof(*pos), member), \ -+ n = list_entry(pos->member.prev, typeof(*pos), member); \ -+ &pos->member != (head); \ -+ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) -+ -+struct offset { -+ struct list_head list; -+ unsigned offset; -+}; -+ -+struct table { -+ struct list_head offsets; -+ unsigned offset_max; -+ unsigned nentry; -+ unsigned *table; -+ char *gpu_prefix; -+}; -+ -+struct offset *offset_new(unsigned o) -+{ -+ struct offset *offset; -+ -+ offset = (struct offset *)malloc(sizeof(struct offset)); -+ if (offset) { -+ INIT_LIST_HEAD(&offset->list); -+ offset->offset = o; -+ } -+ return offset; -+} -+ -+void table_offset_add(struct table *t, struct offset *offset) -+{ -+ list_add_tail(&offset->list, &t->offsets); -+} -+ -+void table_init(struct table *t) -+{ -+ INIT_LIST_HEAD(&t->offsets); -+ t->offset_max = 0; -+ t->nentry = 0; -+ t->table = NULL; -+} -+ -+void table_print(struct table *t) -+{ -+ unsigned nlloop, i, j, n, c, id; -+ -+ nlloop = (t->nentry + 3) / 4; -+ c = t->nentry; -+ printf("static const unsigned %s_reg_safe_bm[%d] = {\n", t->gpu_prefix, -+ t->nentry); -+ for (i = 0, id = 0; i < nlloop; i++) { -+ n = 4; -+ if (n > c) -+ n = c; -+ c -= n; -+ for (j = 0; j < n; j++) { -+ if (j == 0) -+ printf("\t"); -+ else -+ printf(" "); -+ printf("0x%08X,", t->table[id++]); -+ } -+ printf("\n"); -+ } -+ printf("};\n"); -+} -+ -+int table_build(struct table *t) -+{ -+ struct offset *offset; -+ unsigned i, m; -+ -+ t->nentry = ((t->offset_max >> 2) + 31) / 32; -+ t->table = (unsigned *)malloc(sizeof(unsigned) * t->nentry); -+ if (t->table == NULL) -+ return -1; -+ memset(t->table, 0xff, sizeof(unsigned) * t->nentry); -+ list_for_each_entry(offset, &t->offsets, list) { -+ i = (offset->offset >> 2) / 32; -+ m = (offset->offset >> 2) & 31; -+ m = 1 << m; -+ t->table[i] ^= m; -+ } -+ return 0; -+} -+ -+static char gpu_name[10]; -+int parser_auth(struct table *t, const char *filename) -+{ -+ FILE *file; -+ regex_t mask_rex; -+ regmatch_t match[4]; -+ char buf[1024]; -+ size_t end; -+ int len; -+ int done = 0; -+ int r; -+ unsigned o; -+ struct offset *offset; -+ char last_reg_s[10]; -+ int last_reg; -+ -+ if (regcomp -+ (&mask_rex, "(0x[0-9a-fA-F]*) *([_a-zA-Z0-9]*)", REG_EXTENDED)) { -+ fprintf(stderr, "Failed to compile regular expression\n"); -+ return -1; -+ } -+ file = fopen(filename, "r"); -+ if (file == NULL) { -+ fprintf(stderr, "Failed to open: %s\n", filename); -+ return -1; -+ } -+ fseek(file, 0, SEEK_END); -+ end = ftell(file); -+ fseek(file, 0, SEEK_SET); -+ -+ /* get header */ -+ if (fgets(buf, 1024, file) == NULL) -+ return -1; -+ -+ /* first line will contain the last register -+ * and gpu name */ -+ sscanf(buf, "%s %s", gpu_name, last_reg_s); -+ t->gpu_prefix = gpu_name; -+ last_reg = strtol(last_reg_s, NULL, 16); -+ -+ do { -+ if (fgets(buf, 1024, file) == NULL) -+ return -1; -+ len = strlen(buf); -+ if (ftell(file) == end) -+ done = 1; -+ if (len) { -+ r = regexec(&mask_rex, buf, 4, match, 0); -+ if (r == REG_NOMATCH) { -+ } else if (r) { -+ fprintf(stderr, -+ "Error matching regular expression %d in %s\n", -+ r, filename); -+ return -1; -+ } else { -+ buf[match[0].rm_eo] = 0; -+ buf[match[1].rm_eo] = 0; -+ buf[match[2].rm_eo] = 0; -+ o = strtol(&buf[match[1].rm_so], NULL, 16); -+ offset = offset_new(o); -+ table_offset_add(t, offset); -+ if (o > t->offset_max) -+ t->offset_max = o; -+ } -+ } -+ } while (!done); -+ fclose(file); -+ if (t->offset_max < last_reg) -+ t->offset_max = last_reg; -+ return table_build(t); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct table t; -+ -+ if (argc != 2) { -+ fprintf(stderr, "Usage: %s \n", argv[0]); -+ exit(1); -+ } -+ table_init(&t); -+ if (parser_auth(&t, argv[1])) { -+ fprintf(stderr, "Failed to parse file %s\n", argv[1]); -+ return -1; -+ } -+ table_print(&t); -+ return 0; -+} -diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c -index 68e728e..5708c07 100644 ---- a/drivers/gpu/drm/radeon/r100.c -+++ b/drivers/gpu/drm/radeon/r100.c -@@ -29,15 +29,41 @@ - #include "drmP.h" - #include "drm.h" - #include "radeon_drm.h" --#include "radeon_microcode.h" - #include "radeon_reg.h" - #include "radeon.h" -+#include "r100d.h" -+ -+#include -+#include -+ -+#include "r100_reg_safe.h" -+#include "rn50_reg_safe.h" -+ -+/* Firmware Names */ -+#define FIRMWARE_R100 "radeon/R100_cp.bin" -+#define FIRMWARE_R200 "radeon/R200_cp.bin" -+#define FIRMWARE_R300 "radeon/R300_cp.bin" -+#define FIRMWARE_R420 "radeon/R420_cp.bin" -+#define FIRMWARE_RS690 "radeon/RS690_cp.bin" -+#define FIRMWARE_RS600 "radeon/RS600_cp.bin" -+#define FIRMWARE_R520 "radeon/R520_cp.bin" -+ -+MODULE_FIRMWARE(FIRMWARE_R100); -+MODULE_FIRMWARE(FIRMWARE_R200); -+MODULE_FIRMWARE(FIRMWARE_R300); -+MODULE_FIRMWARE(FIRMWARE_R420); -+MODULE_FIRMWARE(FIRMWARE_RS690); -+MODULE_FIRMWARE(FIRMWARE_RS600); -+MODULE_FIRMWARE(FIRMWARE_R520); -+ -+#include "r100_track.h" - - /* This files gather functions specifics to: - * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 - * - * Some of these functions might be used by newer ASICs. - */ -+int r200_init(struct radeon_device *rdev); - void r100_hdp_reset(struct radeon_device *rdev); - void r100_gpu_init(struct radeon_device *rdev); - int r100_gui_wait_for_idle(struct radeon_device *rdev); -@@ -367,9 +393,9 @@ int r100_wb_init(struct radeon_device *rdev) - return r; - } - } -- WREG32(0x774, rdev->wb.gpu_addr); -- WREG32(0x70C, rdev->wb.gpu_addr + 1024); -- WREG32(0x770, 0xff); -+ WREG32(RADEON_SCRATCH_ADDR, rdev->wb.gpu_addr); -+ WREG32(RADEON_CP_RB_RPTR_ADDR, rdev->wb.gpu_addr + 1024); -+ WREG32(RADEON_SCRATCH_UMSK, 0xff); - return 0; - } - -@@ -478,33 +504,33 @@ void r100_ring_start(struct radeon_device *rdev) - radeon_ring_unlock_commit(rdev); - } - --static void r100_cp_load_microcode(struct radeon_device *rdev) -+ -+/* Load the microcode for the CP */ -+static int r100_cp_init_microcode(struct radeon_device *rdev) - { -- int i; -+ struct platform_device *pdev; -+ const char *fw_name = NULL; -+ int err; - -- if (r100_gui_wait_for_idle(rdev)) { -- printk(KERN_WARNING "Failed to wait GUI idle while " -- "programming pipes. Bad things might happen.\n"); -- } -+ DRM_DEBUG("\n"); - -- WREG32(RADEON_CP_ME_RAM_ADDR, 0); -+ pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); -+ err = IS_ERR(pdev); -+ if (err) { -+ printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); -+ return -EINVAL; -+ } - if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || - (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) { - DRM_INFO("Loading R100 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R100; - } else if ((rdev->family == CHIP_R200) || - (rdev->family == CHIP_RV250) || - (rdev->family == CHIP_RV280) || - (rdev->family == CHIP_RS300)) { - DRM_INFO("Loading R200 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R200; - } else if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350) || - (rdev->family == CHIP_RV350) || -@@ -512,31 +538,19 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { - DRM_INFO("Loading R300 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R300; - } else if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - DRM_INFO("Loading R400 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R420; - } else if ((rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) { - DRM_INFO("Loading RS690/RS740 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_RS690; - } else if (rdev->family == CHIP_RS600) { - DRM_INFO("Loading RS600 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_RS600; - } else if ((rdev->family == CHIP_RV515) || - (rdev->family == CHIP_R520) || - (rdev->family == CHIP_RV530) || -@@ -544,9 +558,43 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) - (rdev->family == CHIP_RV560) || - (rdev->family == CHIP_RV570)) { - DRM_INFO("Loading R500 Microcode\n"); -- for (i = 0; i < 256; i++) { -- WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]); -- WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); -+ fw_name = FIRMWARE_R520; -+ } -+ -+ err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); -+ platform_device_unregister(pdev); -+ if (err) { -+ printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", -+ fw_name); -+ } else if (rdev->me_fw->size % 8) { -+ printk(KERN_ERR -+ "radeon_cp: Bogus length %zu in firmware \"%s\"\n", -+ rdev->me_fw->size, fw_name); -+ err = -EINVAL; -+ release_firmware(rdev->me_fw); -+ rdev->me_fw = NULL; -+ } -+ return err; -+} -+static void r100_cp_load_microcode(struct radeon_device *rdev) -+{ -+ const __be32 *fw_data; -+ int i, size; -+ -+ if (r100_gui_wait_for_idle(rdev)) { -+ printk(KERN_WARNING "Failed to wait GUI idle while " -+ "programming pipes. Bad things might happen.\n"); -+ } -+ -+ if (rdev->me_fw) { -+ size = rdev->me_fw->size / 4; -+ fw_data = (const __be32 *)&rdev->me_fw->data[0]; -+ WREG32(RADEON_CP_ME_RAM_ADDR, 0); -+ for (i = 0; i < size; i += 2) { -+ WREG32(RADEON_CP_ME_RAM_DATAH, -+ be32_to_cpup(&fw_data[i])); -+ WREG32(RADEON_CP_ME_RAM_DATAL, -+ be32_to_cpup(&fw_data[i + 1])); - } - } - } -@@ -585,6 +633,15 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) - } else { - DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); - } -+ -+ if (!rdev->me_fw) { -+ r = r100_cp_init_microcode(rdev); -+ if (r) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ return r; -+ } -+ } -+ - /* Align ring size */ - rb_bufsz = drm_order(ring_size / 8); - ring_size = (1 << (rb_bufsz + 1)) * 4; -@@ -710,6 +767,12 @@ int r100_cp_reset(struct radeon_device *rdev) - return -1; - } - -+void r100_cp_commit(struct radeon_device *rdev) -+{ -+ WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); -+ (void)RREG32(RADEON_CP_RB_WPTR); -+} -+ - - /* - * CS functions -@@ -968,147 +1031,356 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, - return 0; - } - -+static int r100_get_vtx_size(uint32_t vtx_fmt) -+{ -+ int vtx_size; -+ vtx_size = 2; -+ /* ordered according to bits in spec */ -+ if (vtx_fmt & RADEON_SE_VTX_FMT_W0) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR) -+ vtx_size += 3; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC) -+ vtx_size += 3; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST0) -+ vtx_size += 2; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST1) -+ vtx_size += 2; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q1) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST2) -+ vtx_size += 2; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q2) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_ST3) -+ vtx_size += 2; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q3) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Q0) -+ vtx_size++; -+ /* blend weight */ -+ if (vtx_fmt & (0x7 << 15)) -+ vtx_size += (vtx_fmt >> 15) & 0x7; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_N0) -+ vtx_size += 3; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_XY1) -+ vtx_size += 2; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Z1) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_W1) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_N1) -+ vtx_size++; -+ if (vtx_fmt & RADEON_SE_VTX_FMT_Z) -+ vtx_size++; -+ return vtx_size; -+} -+ - static int r100_packet0_check(struct radeon_cs_parser *p, -- struct radeon_cs_packet *pkt) -+ struct radeon_cs_packet *pkt, -+ unsigned idx, unsigned reg) - { - struct radeon_cs_chunk *ib_chunk; - struct radeon_cs_reloc *reloc; -+ struct r100_cs_track *track; - volatile uint32_t *ib; - uint32_t tmp; -- unsigned reg; -- unsigned i; -- unsigned idx; -- bool onereg; - int r; -+ int i, face; - u32 tile_flags = 0; - - ib = p->ib->ptr; - ib_chunk = &p->chunks[p->chunk_ib_idx]; -- idx = pkt->idx + 1; -- reg = pkt->reg; -- onereg = false; -- if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) { -- onereg = true; -- } -- for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { -- switch (reg) { -- case RADEON_CRTC_GUI_TRIG_VLINE: -- r = r100_cs_packet_parse_vline(p); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -- return r; -- } -- break; -+ track = (struct r100_cs_track *)p->track; -+ -+ switch (reg) { -+ case RADEON_CRTC_GUI_TRIG_VLINE: -+ r = r100_cs_packet_parse_vline(p); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ break; - /* FIXME: only allow PACKET3 blit? easier to check for out of - * range access */ -- case RADEON_DST_PITCH_OFFSET: -- case RADEON_SRC_PITCH_OFFSET: -- r = r100_cs_packet_next_reloc(p, &reloc); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -- return r; -- } -- tmp = ib_chunk->kdata[idx] & 0x003fffff; -- tmp += (((u32)reloc->lobj.gpu_offset) >> 10); -- -- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -- tile_flags |= RADEON_DST_TILE_MACRO; -- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { -- if (reg == RADEON_SRC_PITCH_OFFSET) { -- DRM_ERROR("Cannot src blit from microtiled surface\n"); -- r100_cs_dump_packet(p, pkt); -- return -EINVAL; -- } -- tile_flags |= RADEON_DST_TILE_MICRO; -- } -+ case RADEON_DST_PITCH_OFFSET: -+ case RADEON_SRC_PITCH_OFFSET: -+ r = r100_reloc_pitch_offset(p, pkt, idx, reg); -+ if (r) -+ return r; -+ break; -+ case RADEON_RB3D_DEPTHOFFSET: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->zb.robj = reloc->robj; -+ track->zb.offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case RADEON_RB3D_COLOROFFSET: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->cb[0].robj = reloc->robj; -+ track->cb[0].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case RADEON_PP_TXOFFSET_0: -+ case RADEON_PP_TXOFFSET_1: -+ case RADEON_PP_TXOFFSET_2: -+ i = (reg - RADEON_PP_TXOFFSET_0) / 24; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[i].robj = reloc->robj; -+ break; -+ case RADEON_PP_CUBIC_OFFSET_T0_0: -+ case RADEON_PP_CUBIC_OFFSET_T0_1: -+ case RADEON_PP_CUBIC_OFFSET_T0_2: -+ case RADEON_PP_CUBIC_OFFSET_T0_3: -+ case RADEON_PP_CUBIC_OFFSET_T0_4: -+ i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[0].cube_info[i].robj = reloc->robj; -+ break; -+ case RADEON_PP_CUBIC_OFFSET_T1_0: -+ case RADEON_PP_CUBIC_OFFSET_T1_1: -+ case RADEON_PP_CUBIC_OFFSET_T1_2: -+ case RADEON_PP_CUBIC_OFFSET_T1_3: -+ case RADEON_PP_CUBIC_OFFSET_T1_4: -+ i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[1].cube_info[i].robj = reloc->robj; -+ break; -+ case RADEON_PP_CUBIC_OFFSET_T2_0: -+ case RADEON_PP_CUBIC_OFFSET_T2_1: -+ case RADEON_PP_CUBIC_OFFSET_T2_2: -+ case RADEON_PP_CUBIC_OFFSET_T2_3: -+ case RADEON_PP_CUBIC_OFFSET_T2_4: -+ i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[2].cube_info[i].robj = reloc->robj; -+ break; -+ case RADEON_RE_WIDTH_HEIGHT: -+ track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); -+ break; -+ case RADEON_RB3D_COLORPITCH: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } - -- tmp |= tile_flags; -- ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp; -- break; -- case RADEON_RB3D_DEPTHOFFSET: -- case RADEON_RB3D_COLOROFFSET: -- case R300_RB3D_COLOROFFSET0: -- case R300_ZB_DEPTHOFFSET: -- case R200_PP_TXOFFSET_0: -- case R200_PP_TXOFFSET_1: -- case R200_PP_TXOFFSET_2: -- case R200_PP_TXOFFSET_3: -- case R200_PP_TXOFFSET_4: -- case R200_PP_TXOFFSET_5: -- case RADEON_PP_TXOFFSET_0: -- case RADEON_PP_TXOFFSET_1: -- case RADEON_PP_TXOFFSET_2: -- case R300_TX_OFFSET_0: -- case R300_TX_OFFSET_0+4: -- case R300_TX_OFFSET_0+8: -- case R300_TX_OFFSET_0+12: -- case R300_TX_OFFSET_0+16: -- case R300_TX_OFFSET_0+20: -- case R300_TX_OFFSET_0+24: -- case R300_TX_OFFSET_0+28: -- case R300_TX_OFFSET_0+32: -- case R300_TX_OFFSET_0+36: -- case R300_TX_OFFSET_0+40: -- case R300_TX_OFFSET_0+44: -- case R300_TX_OFFSET_0+48: -- case R300_TX_OFFSET_0+52: -- case R300_TX_OFFSET_0+56: -- case R300_TX_OFFSET_0+60: -- /* rn50 has no 3D engine so fail on any 3d setup */ -- if (ASIC_IS_RN50(p->rdev)) { -- DRM_ERROR("attempt to use RN50 3D engine failed\n"); -- return -EINVAL; -- } -- r = r100_cs_packet_next_reloc(p, &reloc); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -- return r; -- } -- ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -- break; -- case R300_RB3D_COLORPITCH0: -- case RADEON_RB3D_COLORPITCH: -- r = r100_cs_packet_next_reloc(p, &reloc); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -- return r; -- } -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -+ tile_flags |= RADEON_COLOR_TILE_ENABLE; -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -+ tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - -- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -- tile_flags |= RADEON_COLOR_TILE_ENABLE; -- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -- tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; -+ tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); -+ tmp |= tile_flags; -+ ib[idx] = tmp; - -- tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); -- tmp |= tile_flags; -- ib[idx] = tmp; -+ track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; -+ break; -+ case RADEON_RB3D_DEPTHPITCH: -+ track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; -+ break; -+ case RADEON_RB3D_CNTL: -+ switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { -+ case 7: -+ case 8: -+ case 9: -+ case 11: -+ case 12: -+ track->cb[0].cpp = 1; - break; -- case RADEON_RB3D_ZPASS_ADDR: -- r = r100_cs_packet_next_reloc(p, &reloc); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -- return r; -- } -- ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ case 3: -+ case 4: -+ case 15: -+ track->cb[0].cpp = 2; -+ break; -+ case 6: -+ track->cb[0].cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Invalid color buffer format (%d) !\n", -+ ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); -+ return -EINVAL; -+ } -+ track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); -+ break; -+ case RADEON_RB3D_ZSTENCILCNTL: -+ switch (ib_chunk->kdata[idx] & 0xf) { -+ case 0: -+ track->zb.cpp = 2; -+ break; -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ case 9: -+ case 11: -+ track->zb.cpp = 4; - break; - default: -- /* FIXME: we don't want to allow anyothers packet */ - break; - } -- if (onereg) { -- /* FIXME: forbid onereg write to register on relocate */ -+ break; -+ case RADEON_RB3D_ZPASS_ADDR: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case RADEON_PP_CNTL: -+ { -+ uint32_t temp = ib_chunk->kdata[idx] >> 4; -+ for (i = 0; i < track->num_texture; i++) -+ track->textures[i].enabled = !!(temp & (1 << i)); -+ } -+ break; -+ case RADEON_SE_VF_CNTL: -+ track->vap_vf_cntl = ib_chunk->kdata[idx]; -+ break; -+ case RADEON_SE_VTX_FMT: -+ track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]); -+ break; -+ case RADEON_PP_TEX_SIZE_0: -+ case RADEON_PP_TEX_SIZE_1: -+ case RADEON_PP_TEX_SIZE_2: -+ i = (reg - RADEON_PP_TEX_SIZE_0) / 8; -+ track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; -+ track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; -+ break; -+ case RADEON_PP_TEX_PITCH_0: -+ case RADEON_PP_TEX_PITCH_1: -+ case RADEON_PP_TEX_PITCH_2: -+ i = (reg - RADEON_PP_TEX_PITCH_0) / 8; -+ track->textures[i].pitch = ib_chunk->kdata[idx] + 32; -+ break; -+ case RADEON_PP_TXFILTER_0: -+ case RADEON_PP_TXFILTER_1: -+ case RADEON_PP_TXFILTER_2: -+ i = (reg - RADEON_PP_TXFILTER_0) / 24; -+ track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK) -+ >> RADEON_MAX_MIP_LEVEL_SHIFT); -+ tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; -+ if (tmp == 2 || tmp == 6) -+ track->textures[i].roundup_w = false; -+ tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; -+ if (tmp == 2 || tmp == 6) -+ track->textures[i].roundup_h = false; -+ break; -+ case RADEON_PP_TXFORMAT_0: -+ case RADEON_PP_TXFORMAT_1: -+ case RADEON_PP_TXFORMAT_2: -+ i = (reg - RADEON_PP_TXFORMAT_0) / 24; -+ if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) { -+ track->textures[i].use_pitch = 1; -+ } else { -+ track->textures[i].use_pitch = 0; -+ track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); -+ track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); -+ } -+ if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) -+ track->textures[i].tex_coord_type = 2; -+ switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { -+ case RADEON_TXFORMAT_I8: -+ case RADEON_TXFORMAT_RGB332: -+ case RADEON_TXFORMAT_Y8: -+ track->textures[i].cpp = 1; -+ break; -+ case RADEON_TXFORMAT_AI88: -+ case RADEON_TXFORMAT_ARGB1555: -+ case RADEON_TXFORMAT_RGB565: -+ case RADEON_TXFORMAT_ARGB4444: -+ case RADEON_TXFORMAT_VYUY422: -+ case RADEON_TXFORMAT_YVYU422: -+ case RADEON_TXFORMAT_DXT1: -+ case RADEON_TXFORMAT_SHADOW16: -+ case RADEON_TXFORMAT_LDUDV655: -+ case RADEON_TXFORMAT_DUDV88: -+ track->textures[i].cpp = 2; - break; -+ case RADEON_TXFORMAT_ARGB8888: -+ case RADEON_TXFORMAT_RGBA8888: -+ case RADEON_TXFORMAT_DXT23: -+ case RADEON_TXFORMAT_DXT45: -+ case RADEON_TXFORMAT_SHADOW32: -+ case RADEON_TXFORMAT_LDUDUV8888: -+ track->textures[i].cpp = 4; -+ break; -+ } -+ track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); -+ track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); -+ break; -+ case RADEON_PP_CUBIC_FACES_0: -+ case RADEON_PP_CUBIC_FACES_1: -+ case RADEON_PP_CUBIC_FACES_2: -+ tmp = ib_chunk->kdata[idx]; -+ i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; -+ for (face = 0; face < 4; face++) { -+ track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); -+ track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); - } -+ break; -+ default: -+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", -+ reg, idx); -+ return -EINVAL; - } - return 0; - } -@@ -1137,6 +1409,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - { - struct radeon_cs_chunk *ib_chunk; - struct radeon_cs_reloc *reloc; -+ struct r100_cs_track *track; - unsigned idx; - unsigned i, c; - volatile uint32_t *ib; -@@ -1145,9 +1418,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - ib = p->ib->ptr; - ib_chunk = &p->chunks[p->chunk_ib_idx]; - idx = pkt->idx + 1; -+ track = (struct r100_cs_track *)p->track; - switch (pkt->opcode) { - case PACKET3_3D_LOAD_VBPNTR: - c = ib_chunk->kdata[idx++]; -+ track->num_arrays = c; - for (i = 0; i < (c - 1); i += 2, idx += 3) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { -@@ -1157,6 +1432,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - return r; - } - ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); -+ track->arrays[i + 0].robj = reloc->robj; -+ track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; -+ track->arrays[i + 0].esize &= 0x7F; - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for packet3 %d\n", -@@ -1165,6 +1443,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - return r; - } - ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); -+ track->arrays[i + 1].robj = reloc->robj; -+ track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; -+ track->arrays[i + 1].esize &= 0x7F; - } - if (c & 1) { - r = r100_cs_packet_next_reloc(p, &reloc); -@@ -1175,6 +1456,9 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - return r; - } - ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); -+ track->arrays[i + 0].robj = reloc->robj; -+ track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; -+ track->arrays[i + 0].esize &= 0x7F; - } - break; - case PACKET3_INDX_BUFFER: -@@ -1191,7 +1475,6 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - } - break; - case 0x23: -- /* FIXME: cleanup */ - /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { -@@ -1200,18 +1483,71 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - return r; - } - ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->num_arrays = 1; -+ track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]); -+ -+ track->arrays[0].robj = reloc->robj; -+ track->arrays[0].esize = track->vtx_size; -+ -+ track->max_indx = ib_chunk->kdata[idx+1]; -+ -+ track->vap_vf_cntl = ib_chunk->kdata[idx+3]; -+ track->immd_dwords = pkt->count - 1; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; - break; - case PACKET3_3D_DRAW_IMMD: -+ if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { -+ DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); -+ return -EINVAL; -+ } -+ track->vap_vf_cntl = ib_chunk->kdata[idx+1]; -+ track->immd_dwords = pkt->count - 1; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing using in-packet vertex data */ - case PACKET3_3D_DRAW_IMMD_2: -+ if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { -+ DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); -+ return -EINVAL; -+ } -+ track->vap_vf_cntl = ib_chunk->kdata[idx]; -+ track->immd_dwords = pkt->count; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing using in-packet vertex data */ - case PACKET3_3D_DRAW_VBUF_2: -+ track->vap_vf_cntl = ib_chunk->kdata[idx]; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing of vertex buffers setup elsewhere */ - case PACKET3_3D_DRAW_INDX_2: -+ track->vap_vf_cntl = ib_chunk->kdata[idx]; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing using indices to vertex buffer */ - case PACKET3_3D_DRAW_VBUF: -+ track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing of vertex buffers setup elsewhere */ - case PACKET3_3D_DRAW_INDX: -+ track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; -+ r = r100_cs_track_check(p->rdev, track); -+ if (r) -+ return r; -+ break; - /* triggers drawing using indices to vertex buffer */ - case PACKET3_NOP: - break; -@@ -1225,8 +1561,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p, - int r100_cs_parse(struct radeon_cs_parser *p) - { - struct radeon_cs_packet pkt; -+ struct r100_cs_track track; - int r; - -+ r100_cs_track_clear(p->rdev, &track); -+ p->track = &track; - do { - r = r100_cs_packet_parse(p, &pkt, p->idx); - if (r) { -@@ -1235,7 +1574,16 @@ int r100_cs_parse(struct radeon_cs_parser *p) - p->idx += pkt.count + 2; - switch (pkt.type) { - case PACKET_TYPE0: -- r = r100_packet0_check(p, &pkt); -+ if (p->rdev->family >= CHIP_R200) -+ r = r100_cs_parse_packet0(p, &pkt, -+ p->rdev->config.r100.reg_safe_bm, -+ p->rdev->config.r100.reg_safe_bm_size, -+ &r200_packet0_check); -+ else -+ r = r100_cs_parse_packet0(p, &pkt, -+ p->rdev->config.r100.reg_safe_bm, -+ p->rdev->config.r100.reg_safe_bm_size, -+ &r100_packet0_check); - break; - case PACKET_TYPE2: - break; -@@ -1634,6 +1982,15 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) - - int r100_init(struct radeon_device *rdev) - { -+ if (ASIC_IS_RN50(rdev)) { -+ rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; -+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); -+ } else if (rdev->family < CHIP_R200) { -+ rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; -+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); -+ } else { -+ return r200_init(rdev); -+ } - return 0; - } - -@@ -2334,3 +2691,377 @@ void r100_bandwidth_update(struct radeon_device *rdev) - (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); - } - } -+ -+static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) -+{ -+ DRM_ERROR("pitch %d\n", t->pitch); -+ DRM_ERROR("width %d\n", t->width); -+ DRM_ERROR("height %d\n", t->height); -+ DRM_ERROR("num levels %d\n", t->num_levels); -+ DRM_ERROR("depth %d\n", t->txdepth); -+ DRM_ERROR("bpp %d\n", t->cpp); -+ DRM_ERROR("coordinate type %d\n", t->tex_coord_type); -+ DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); -+ DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); -+} -+ -+static int r100_cs_track_cube(struct radeon_device *rdev, -+ struct r100_cs_track *track, unsigned idx) -+{ -+ unsigned face, w, h; -+ struct radeon_object *cube_robj; -+ unsigned long size; -+ -+ for (face = 0; face < 5; face++) { -+ cube_robj = track->textures[idx].cube_info[face].robj; -+ w = track->textures[idx].cube_info[face].width; -+ h = track->textures[idx].cube_info[face].height; -+ -+ size = w * h; -+ size *= track->textures[idx].cpp; -+ -+ size += track->textures[idx].cube_info[face].offset; -+ -+ if (size > radeon_object_size(cube_robj)) { -+ DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", -+ size, radeon_object_size(cube_robj)); -+ r100_cs_track_texture_print(&track->textures[idx]); -+ return -1; -+ } -+ } -+ return 0; -+} -+ -+static int r100_cs_track_texture_check(struct radeon_device *rdev, -+ struct r100_cs_track *track) -+{ -+ struct radeon_object *robj; -+ unsigned long size; -+ unsigned u, i, w, h; -+ int ret; -+ -+ for (u = 0; u < track->num_texture; u++) { -+ if (!track->textures[u].enabled) -+ continue; -+ robj = track->textures[u].robj; -+ if (robj == NULL) { -+ DRM_ERROR("No texture bound to unit %u\n", u); -+ return -EINVAL; -+ } -+ size = 0; -+ for (i = 0; i <= track->textures[u].num_levels; i++) { -+ if (track->textures[u].use_pitch) { -+ if (rdev->family < CHIP_R300) -+ w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); -+ else -+ w = track->textures[u].pitch / (1 << i); -+ } else { -+ w = track->textures[u].width / (1 << i); -+ if (rdev->family >= CHIP_RV515) -+ w |= track->textures[u].width_11; -+ if (track->textures[u].roundup_w) -+ w = roundup_pow_of_two(w); -+ } -+ h = track->textures[u].height / (1 << i); -+ if (rdev->family >= CHIP_RV515) -+ h |= track->textures[u].height_11; -+ if (track->textures[u].roundup_h) -+ h = roundup_pow_of_two(h); -+ size += w * h; -+ } -+ size *= track->textures[u].cpp; -+ switch (track->textures[u].tex_coord_type) { -+ case 0: -+ break; -+ case 1: -+ size *= (1 << track->textures[u].txdepth); -+ break; -+ case 2: -+ if (track->separate_cube) { -+ ret = r100_cs_track_cube(rdev, track, u); -+ if (ret) -+ return ret; -+ } else -+ size *= 6; -+ break; -+ default: -+ DRM_ERROR("Invalid texture coordinate type %u for unit " -+ "%u\n", track->textures[u].tex_coord_type, u); -+ return -EINVAL; -+ } -+ if (size > radeon_object_size(robj)) { -+ DRM_ERROR("Texture of unit %u needs %lu bytes but is " -+ "%lu\n", u, size, radeon_object_size(robj)); -+ r100_cs_track_texture_print(&track->textures[u]); -+ return -EINVAL; -+ } -+ } -+ return 0; -+} -+ -+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) -+{ -+ unsigned i; -+ unsigned long size; -+ unsigned prim_walk; -+ unsigned nverts; -+ -+ for (i = 0; i < track->num_cb; i++) { -+ if (track->cb[i].robj == NULL) { -+ DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); -+ return -EINVAL; -+ } -+ size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; -+ size += track->cb[i].offset; -+ if (size > radeon_object_size(track->cb[i].robj)) { -+ DRM_ERROR("[drm] Buffer too small for color buffer %d " -+ "(need %lu have %lu) !\n", i, size, -+ radeon_object_size(track->cb[i].robj)); -+ DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", -+ i, track->cb[i].pitch, track->cb[i].cpp, -+ track->cb[i].offset, track->maxy); -+ return -EINVAL; -+ } -+ } -+ if (track->z_enabled) { -+ if (track->zb.robj == NULL) { -+ DRM_ERROR("[drm] No buffer for z buffer !\n"); -+ return -EINVAL; -+ } -+ size = track->zb.pitch * track->zb.cpp * track->maxy; -+ size += track->zb.offset; -+ if (size > radeon_object_size(track->zb.robj)) { -+ DRM_ERROR("[drm] Buffer too small for z buffer " -+ "(need %lu have %lu) !\n", size, -+ radeon_object_size(track->zb.robj)); -+ DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", -+ track->zb.pitch, track->zb.cpp, -+ track->zb.offset, track->maxy); -+ return -EINVAL; -+ } -+ } -+ prim_walk = (track->vap_vf_cntl >> 4) & 0x3; -+ nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; -+ switch (prim_walk) { -+ case 1: -+ for (i = 0; i < track->num_arrays; i++) { -+ size = track->arrays[i].esize * track->max_indx * 4; -+ if (track->arrays[i].robj == NULL) { -+ DRM_ERROR("(PW %u) Vertex array %u no buffer " -+ "bound\n", prim_walk, i); -+ return -EINVAL; -+ } -+ if (size > radeon_object_size(track->arrays[i].robj)) { -+ DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " -+ "have %lu dwords\n", prim_walk, i, -+ size >> 2, -+ radeon_object_size(track->arrays[i].robj) >> 2); -+ DRM_ERROR("Max indices %u\n", track->max_indx); -+ return -EINVAL; -+ } -+ } -+ break; -+ case 2: -+ for (i = 0; i < track->num_arrays; i++) { -+ size = track->arrays[i].esize * (nverts - 1) * 4; -+ if (track->arrays[i].robj == NULL) { -+ DRM_ERROR("(PW %u) Vertex array %u no buffer " -+ "bound\n", prim_walk, i); -+ return -EINVAL; -+ } -+ if (size > radeon_object_size(track->arrays[i].robj)) { -+ DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " -+ "have %lu dwords\n", prim_walk, i, size >> 2, -+ radeon_object_size(track->arrays[i].robj) >> 2); -+ return -EINVAL; -+ } -+ } -+ break; -+ case 3: -+ size = track->vtx_size * nverts; -+ if (size != track->immd_dwords) { -+ DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", -+ track->immd_dwords, size); -+ DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", -+ nverts, track->vtx_size); -+ return -EINVAL; -+ } -+ break; -+ default: -+ DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", -+ prim_walk); -+ return -EINVAL; -+ } -+ return r100_cs_track_texture_check(rdev, track); -+} -+ -+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) -+{ -+ unsigned i, face; -+ -+ if (rdev->family < CHIP_R300) { -+ track->num_cb = 1; -+ if (rdev->family <= CHIP_RS200) -+ track->num_texture = 3; -+ else -+ track->num_texture = 6; -+ track->maxy = 2048; -+ track->separate_cube = 1; -+ } else { -+ track->num_cb = 4; -+ track->num_texture = 16; -+ track->maxy = 4096; -+ track->separate_cube = 0; -+ } -+ -+ for (i = 0; i < track->num_cb; i++) { -+ track->cb[i].robj = NULL; -+ track->cb[i].pitch = 8192; -+ track->cb[i].cpp = 16; -+ track->cb[i].offset = 0; -+ } -+ track->z_enabled = true; -+ track->zb.robj = NULL; -+ track->zb.pitch = 8192; -+ track->zb.cpp = 4; -+ track->zb.offset = 0; -+ track->vtx_size = 0x7F; -+ track->immd_dwords = 0xFFFFFFFFUL; -+ track->num_arrays = 11; -+ track->max_indx = 0x00FFFFFFUL; -+ for (i = 0; i < track->num_arrays; i++) { -+ track->arrays[i].robj = NULL; -+ track->arrays[i].esize = 0x7F; -+ } -+ for (i = 0; i < track->num_texture; i++) { -+ track->textures[i].pitch = 16536; -+ track->textures[i].width = 16536; -+ track->textures[i].height = 16536; -+ track->textures[i].width_11 = 1 << 11; -+ track->textures[i].height_11 = 1 << 11; -+ track->textures[i].num_levels = 12; -+ if (rdev->family <= CHIP_RS200) { -+ track->textures[i].tex_coord_type = 0; -+ track->textures[i].txdepth = 0; -+ } else { -+ track->textures[i].txdepth = 16; -+ track->textures[i].tex_coord_type = 1; -+ } -+ track->textures[i].cpp = 64; -+ track->textures[i].robj = NULL; -+ /* CS IB emission code makes sure texture unit are disabled */ -+ track->textures[i].enabled = false; -+ track->textures[i].roundup_w = true; -+ track->textures[i].roundup_h = true; -+ if (track->separate_cube) -+ for (face = 0; face < 5; face++) { -+ track->textures[i].cube_info[face].robj = NULL; -+ track->textures[i].cube_info[face].width = 16536; -+ track->textures[i].cube_info[face].height = 16536; -+ track->textures[i].cube_info[face].offset = 0; -+ } -+ } -+} -+ -+int r100_ring_test(struct radeon_device *rdev) -+{ -+ uint32_t scratch; -+ uint32_t tmp = 0; -+ unsigned i; -+ int r; -+ -+ r = radeon_scratch_get(rdev, &scratch); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); -+ return r; -+ } -+ WREG32(scratch, 0xCAFEDEAD); -+ r = radeon_ring_lock(rdev, 2); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ radeon_scratch_free(rdev, scratch); -+ return r; -+ } -+ radeon_ring_write(rdev, PACKET0(scratch, 0)); -+ radeon_ring_write(rdev, 0xDEADBEEF); -+ radeon_ring_unlock_commit(rdev); -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ tmp = RREG32(scratch); -+ if (tmp == 0xDEADBEEF) { -+ break; -+ } -+ DRM_UDELAY(1); -+ } -+ if (i < rdev->usec_timeout) { -+ DRM_INFO("ring test succeeded in %d usecs\n", i); -+ } else { -+ DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", -+ scratch, tmp); -+ r = -EINVAL; -+ } -+ radeon_scratch_free(rdev, scratch); -+ return r; -+} -+ -+void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -+{ -+ radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); -+ radeon_ring_write(rdev, ib->gpu_addr); -+ radeon_ring_write(rdev, ib->length_dw); -+} -+ -+int r100_ib_test(struct radeon_device *rdev) -+{ -+ struct radeon_ib *ib; -+ uint32_t scratch; -+ uint32_t tmp = 0; -+ unsigned i; -+ int r; -+ -+ r = radeon_scratch_get(rdev, &scratch); -+ if (r) { -+ DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); -+ return r; -+ } -+ WREG32(scratch, 0xCAFEDEAD); -+ r = radeon_ib_get(rdev, &ib); -+ if (r) { -+ return r; -+ } -+ ib->ptr[0] = PACKET0(scratch, 0); -+ ib->ptr[1] = 0xDEADBEEF; -+ ib->ptr[2] = PACKET2(0); -+ ib->ptr[3] = PACKET2(0); -+ ib->ptr[4] = PACKET2(0); -+ ib->ptr[5] = PACKET2(0); -+ ib->ptr[6] = PACKET2(0); -+ ib->ptr[7] = PACKET2(0); -+ ib->length_dw = 8; -+ r = radeon_ib_schedule(rdev, ib); -+ if (r) { -+ radeon_scratch_free(rdev, scratch); -+ radeon_ib_free(rdev, &ib); -+ return r; -+ } -+ r = radeon_fence_wait(ib->fence, false); -+ if (r) { -+ return r; -+ } -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ tmp = RREG32(scratch); -+ if (tmp == 0xDEADBEEF) { -+ break; -+ } -+ DRM_UDELAY(1); -+ } -+ if (i < rdev->usec_timeout) { -+ DRM_INFO("ib test succeeded in %u usecs\n", i); -+ } else { -+ DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", -+ scratch, tmp); -+ r = -EINVAL; -+ } -+ radeon_scratch_free(rdev, scratch); -+ radeon_ib_free(rdev, &ib); -+ return r; -+} -diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h -new file mode 100644 -index 0000000..70a82ed ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r100_track.h -@@ -0,0 +1,124 @@ -+ -+#define R100_TRACK_MAX_TEXTURE 3 -+#define R200_TRACK_MAX_TEXTURE 6 -+#define R300_TRACK_MAX_TEXTURE 16 -+ -+#define R100_MAX_CB 1 -+#define R300_MAX_CB 4 -+ -+/* -+ * CS functions -+ */ -+struct r100_cs_track_cb { -+ struct radeon_object *robj; -+ unsigned pitch; -+ unsigned cpp; -+ unsigned offset; -+}; -+ -+struct r100_cs_track_array { -+ struct radeon_object *robj; -+ unsigned esize; -+}; -+ -+struct r100_cs_cube_info { -+ struct radeon_object *robj; -+ unsigned offset; -+ unsigned width; -+ unsigned height; -+}; -+ -+struct r100_cs_track_texture { -+ struct radeon_object *robj; -+ struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ -+ unsigned pitch; -+ unsigned width; -+ unsigned height; -+ unsigned num_levels; -+ unsigned cpp; -+ unsigned tex_coord_type; -+ unsigned txdepth; -+ unsigned width_11; -+ unsigned height_11; -+ bool use_pitch; -+ bool enabled; -+ bool roundup_w; -+ bool roundup_h; -+}; -+ -+struct r100_cs_track_limits { -+ unsigned num_cb; -+ unsigned num_texture; -+ unsigned max_levels; -+}; -+ -+struct r100_cs_track { -+ struct radeon_device *rdev; -+ unsigned num_cb; -+ unsigned num_texture; -+ unsigned maxy; -+ unsigned vtx_size; -+ unsigned vap_vf_cntl; -+ unsigned immd_dwords; -+ unsigned num_arrays; -+ unsigned max_indx; -+ struct r100_cs_track_array arrays[11]; -+ struct r100_cs_track_cb cb[R300_MAX_CB]; -+ struct r100_cs_track_cb zb; -+ struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; -+ bool z_enabled; -+ bool separate_cube; -+ -+}; -+ -+int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); -+void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track); -+int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, -+ struct radeon_cs_reloc **cs_reloc); -+void r100_cs_dump_packet(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt); -+ -+int r100_cs_packet_parse_vline(struct radeon_cs_parser *p); -+ -+int r200_packet0_check(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt, -+ unsigned idx, unsigned reg); -+ -+static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt, -+ unsigned idx, -+ unsigned reg) -+{ -+ int r; -+ u32 tile_flags = 0; -+ u32 tmp; -+ struct radeon_cs_reloc *reloc; -+ struct radeon_cs_chunk *ib_chunk; -+ -+ ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ tmp = ib_chunk->kdata[idx] & 0x003fffff; -+ tmp += (((u32)reloc->lobj.gpu_offset) >> 10); -+ -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -+ tile_flags |= RADEON_DST_TILE_MACRO; -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { -+ if (reg == RADEON_SRC_PITCH_OFFSET) { -+ DRM_ERROR("Cannot src blit from microtiled surface\n"); -+ r100_cs_dump_packet(p, pkt); -+ return -EINVAL; -+ } -+ tile_flags |= RADEON_DST_TILE_MICRO; -+ } -+ -+ tmp |= tile_flags; -+ p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp; -+ return 0; -+} -diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h -new file mode 100644 -index 0000000..6da7d92 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r100d.h -@@ -0,0 +1,76 @@ -+/* -+ * Copyright 2008 Advanced Micro Devices, Inc. -+ * Copyright 2008 Red Hat Inc. -+ * Copyright 2009 Jerome Glisse. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef __R100D_H__ -+#define __R100D_H__ -+ -+#define CP_PACKET0 0x00000000 -+#define PACKET0_BASE_INDEX_SHIFT 0 -+#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -+#define PACKET0_COUNT_SHIFT 16 -+#define PACKET0_COUNT_MASK (0x3fff << 16) -+#define CP_PACKET1 0x40000000 -+#define CP_PACKET2 0x80000000 -+#define PACKET2_PAD_SHIFT 0 -+#define PACKET2_PAD_MASK (0x3fffffff << 0) -+#define CP_PACKET3 0xC0000000 -+#define PACKET3_IT_OPCODE_SHIFT 8 -+#define PACKET3_IT_OPCODE_MASK (0xff << 8) -+#define PACKET3_COUNT_SHIFT 16 -+#define PACKET3_COUNT_MASK (0x3fff << 16) -+/* PACKET3 op code */ -+#define PACKET3_NOP 0x10 -+#define PACKET3_3D_DRAW_VBUF 0x28 -+#define PACKET3_3D_DRAW_IMMD 0x29 -+#define PACKET3_3D_DRAW_INDX 0x2A -+#define PACKET3_3D_LOAD_VBPNTR 0x2F -+#define PACKET3_INDX_BUFFER 0x33 -+#define PACKET3_3D_DRAW_VBUF_2 0x34 -+#define PACKET3_3D_DRAW_IMMD_2 0x35 -+#define PACKET3_3D_DRAW_INDX_2 0x36 -+#define PACKET3_BITBLT_MULTI 0x9B -+ -+#define PACKET0(reg, n) (CP_PACKET0 | \ -+ REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ -+ REG_SET(PACKET0_COUNT, (n))) -+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -+#define PACKET3(op, n) (CP_PACKET3 | \ -+ REG_SET(PACKET3_IT_OPCODE, (op)) | \ -+ REG_SET(PACKET3_COUNT, (n))) -+ -+#define PACKET_TYPE0 0 -+#define PACKET_TYPE1 1 -+#define PACKET_TYPE2 2 -+#define PACKET_TYPE3 3 -+ -+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c -new file mode 100644 -index 0000000..568c74b ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r200.c -@@ -0,0 +1,456 @@ -+/* -+ * Copyright 2008 Advanced Micro Devices, Inc. -+ * Copyright 2008 Red Hat Inc. -+ * Copyright 2009 Jerome Glisse. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#include "drmP.h" -+#include "drm.h" -+#include "radeon_drm.h" -+#include "radeon_reg.h" -+#include "radeon.h" -+ -+#include "r200_reg_safe.h" -+ -+#include "r100_track.h" -+ -+static int r200_get_vtx_size_0(uint32_t vtx_fmt_0) -+{ -+ int vtx_size, i; -+ vtx_size = 2; -+ -+ if (vtx_fmt_0 & R200_VTX_Z0) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_W0) -+ vtx_size++; -+ /* blend weight */ -+ if (vtx_fmt_0 & (0x7 << R200_VTX_WEIGHT_COUNT_SHIFT)) -+ vtx_size += (vtx_fmt_0 >> R200_VTX_WEIGHT_COUNT_SHIFT) & 0x7; -+ if (vtx_fmt_0 & R200_VTX_PV_MATRIX_SEL) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_N0) -+ vtx_size += 3; -+ if (vtx_fmt_0 & R200_VTX_POINT_SIZE) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_DISCRETE_FOG) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_SHININESS_0) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_SHININESS_1) -+ vtx_size++; -+ for (i = 0; i < 8; i++) { -+ int color_size = (vtx_fmt_0 >> (11 + 2*i)) & 0x3; -+ switch (color_size) { -+ case 0: break; -+ case 1: vtx_size++; break; -+ case 2: vtx_size += 3; break; -+ case 3: vtx_size += 4; break; -+ } -+ } -+ if (vtx_fmt_0 & R200_VTX_XY1) -+ vtx_size += 2; -+ if (vtx_fmt_0 & R200_VTX_Z1) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_W1) -+ vtx_size++; -+ if (vtx_fmt_0 & R200_VTX_N1) -+ vtx_size += 3; -+ return vtx_size; -+} -+ -+static int r200_get_vtx_size_1(uint32_t vtx_fmt_1) -+{ -+ int vtx_size, i, tex_size; -+ vtx_size = 0; -+ for (i = 0; i < 6; i++) { -+ tex_size = (vtx_fmt_1 >> (i * 3)) & 0x7; -+ if (tex_size > 4) -+ continue; -+ vtx_size += tex_size; -+ } -+ return vtx_size; -+} -+ -+int r200_packet0_check(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt, -+ unsigned idx, unsigned reg) -+{ -+ struct radeon_cs_chunk *ib_chunk; -+ struct radeon_cs_reloc *reloc; -+ struct r100_cs_track *track; -+ volatile uint32_t *ib; -+ uint32_t tmp; -+ int r; -+ int i; -+ int face; -+ u32 tile_flags = 0; -+ -+ ib = p->ib->ptr; -+ ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ track = (struct r100_cs_track *)p->track; -+ -+ switch (reg) { -+ case RADEON_CRTC_GUI_TRIG_VLINE: -+ r = r100_cs_packet_parse_vline(p); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ break; -+ /* FIXME: only allow PACKET3 blit? easier to check for out of -+ * range access */ -+ case RADEON_DST_PITCH_OFFSET: -+ case RADEON_SRC_PITCH_OFFSET: -+ r = r100_reloc_pitch_offset(p, pkt, idx, reg); -+ if (r) -+ return r; -+ break; -+ case RADEON_RB3D_DEPTHOFFSET: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->zb.robj = reloc->robj; -+ track->zb.offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case RADEON_RB3D_COLOROFFSET: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->cb[0].robj = reloc->robj; -+ track->cb[0].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case R200_PP_TXOFFSET_0: -+ case R200_PP_TXOFFSET_1: -+ case R200_PP_TXOFFSET_2: -+ case R200_PP_TXOFFSET_3: -+ case R200_PP_TXOFFSET_4: -+ case R200_PP_TXOFFSET_5: -+ i = (reg - R200_PP_TXOFFSET_0) / 24; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[i].robj = reloc->robj; -+ break; -+ case R200_PP_CUBIC_OFFSET_F1_0: -+ case R200_PP_CUBIC_OFFSET_F2_0: -+ case R200_PP_CUBIC_OFFSET_F3_0: -+ case R200_PP_CUBIC_OFFSET_F4_0: -+ case R200_PP_CUBIC_OFFSET_F5_0: -+ case R200_PP_CUBIC_OFFSET_F1_1: -+ case R200_PP_CUBIC_OFFSET_F2_1: -+ case R200_PP_CUBIC_OFFSET_F3_1: -+ case R200_PP_CUBIC_OFFSET_F4_1: -+ case R200_PP_CUBIC_OFFSET_F5_1: -+ case R200_PP_CUBIC_OFFSET_F1_2: -+ case R200_PP_CUBIC_OFFSET_F2_2: -+ case R200_PP_CUBIC_OFFSET_F3_2: -+ case R200_PP_CUBIC_OFFSET_F4_2: -+ case R200_PP_CUBIC_OFFSET_F5_2: -+ case R200_PP_CUBIC_OFFSET_F1_3: -+ case R200_PP_CUBIC_OFFSET_F2_3: -+ case R200_PP_CUBIC_OFFSET_F3_3: -+ case R200_PP_CUBIC_OFFSET_F4_3: -+ case R200_PP_CUBIC_OFFSET_F5_3: -+ case R200_PP_CUBIC_OFFSET_F1_4: -+ case R200_PP_CUBIC_OFFSET_F2_4: -+ case R200_PP_CUBIC_OFFSET_F3_4: -+ case R200_PP_CUBIC_OFFSET_F4_4: -+ case R200_PP_CUBIC_OFFSET_F5_4: -+ case R200_PP_CUBIC_OFFSET_F1_5: -+ case R200_PP_CUBIC_OFFSET_F2_5: -+ case R200_PP_CUBIC_OFFSET_F3_5: -+ case R200_PP_CUBIC_OFFSET_F4_5: -+ case R200_PP_CUBIC_OFFSET_F5_5: -+ i = (reg - R200_PP_TXOFFSET_0) / 24; -+ face = (reg - ((i * 24) + R200_PP_TXOFFSET_0)) / 4; -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ track->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx]; -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ track->textures[i].cube_info[face - 1].robj = reloc->robj; -+ break; -+ case RADEON_RE_WIDTH_HEIGHT: -+ track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); -+ break; -+ case RADEON_RB3D_COLORPITCH: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -+ tile_flags |= RADEON_COLOR_TILE_ENABLE; -+ if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) -+ tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; -+ -+ tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); -+ tmp |= tile_flags; -+ ib[idx] = tmp; -+ -+ track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; -+ break; -+ case RADEON_RB3D_DEPTHPITCH: -+ track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; -+ break; -+ case RADEON_RB3D_CNTL: -+ switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { -+ case 7: -+ case 8: -+ case 9: -+ case 11: -+ case 12: -+ track->cb[0].cpp = 1; -+ break; -+ case 3: -+ case 4: -+ case 15: -+ track->cb[0].cpp = 2; -+ break; -+ case 6: -+ track->cb[0].cpp = 4; -+ break; -+ default: -+ DRM_ERROR("Invalid color buffer format (%d) !\n", -+ ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); -+ return -EINVAL; -+ } -+ if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) { -+ DRM_ERROR("No support for depth xy offset in kms\n"); -+ return -EINVAL; -+ } -+ -+ track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); -+ break; -+ case RADEON_RB3D_ZSTENCILCNTL: -+ switch (ib_chunk->kdata[idx] & 0xf) { -+ case 0: -+ track->zb.cpp = 2; -+ break; -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ case 9: -+ case 11: -+ track->zb.cpp = 4; -+ break; -+ default: -+ break; -+ } -+ break; -+ case RADEON_RB3D_ZPASS_ADDR: -+ r = r100_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -+ idx, reg); -+ r100_cs_dump_packet(p, pkt); -+ return r; -+ } -+ ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); -+ break; -+ case RADEON_PP_CNTL: -+ { -+ uint32_t temp = ib_chunk->kdata[idx] >> 4; -+ for (i = 0; i < track->num_texture; i++) -+ track->textures[i].enabled = !!(temp & (1 << i)); -+ } -+ break; -+ case RADEON_SE_VF_CNTL: -+ track->vap_vf_cntl = ib_chunk->kdata[idx]; -+ break; -+ case 0x210c: -+ /* VAP_VF_MAX_VTX_INDX */ -+ track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL; -+ break; -+ case R200_SE_VTX_FMT_0: -+ track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]); -+ break; -+ case R200_SE_VTX_FMT_1: -+ track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]); -+ break; -+ case R200_PP_TXSIZE_0: -+ case R200_PP_TXSIZE_1: -+ case R200_PP_TXSIZE_2: -+ case R200_PP_TXSIZE_3: -+ case R200_PP_TXSIZE_4: -+ case R200_PP_TXSIZE_5: -+ i = (reg - R200_PP_TXSIZE_0) / 32; -+ track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; -+ track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; -+ break; -+ case R200_PP_TXPITCH_0: -+ case R200_PP_TXPITCH_1: -+ case R200_PP_TXPITCH_2: -+ case R200_PP_TXPITCH_3: -+ case R200_PP_TXPITCH_4: -+ case R200_PP_TXPITCH_5: -+ i = (reg - R200_PP_TXPITCH_0) / 32; -+ track->textures[i].pitch = ib_chunk->kdata[idx] + 32; -+ break; -+ case R200_PP_TXFILTER_0: -+ case R200_PP_TXFILTER_1: -+ case R200_PP_TXFILTER_2: -+ case R200_PP_TXFILTER_3: -+ case R200_PP_TXFILTER_4: -+ case R200_PP_TXFILTER_5: -+ i = (reg - R200_PP_TXFILTER_0) / 32; -+ track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK) -+ >> R200_MAX_MIP_LEVEL_SHIFT); -+ tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; -+ if (tmp == 2 || tmp == 6) -+ track->textures[i].roundup_w = false; -+ tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; -+ if (tmp == 2 || tmp == 6) -+ track->textures[i].roundup_h = false; -+ break; -+ case R200_PP_TXMULTI_CTL_0: -+ case R200_PP_TXMULTI_CTL_1: -+ case R200_PP_TXMULTI_CTL_2: -+ case R200_PP_TXMULTI_CTL_3: -+ case R200_PP_TXMULTI_CTL_4: -+ case R200_PP_TXMULTI_CTL_5: -+ i = (reg - R200_PP_TXMULTI_CTL_0) / 32; -+ break; -+ case R200_PP_TXFORMAT_X_0: -+ case R200_PP_TXFORMAT_X_1: -+ case R200_PP_TXFORMAT_X_2: -+ case R200_PP_TXFORMAT_X_3: -+ case R200_PP_TXFORMAT_X_4: -+ case R200_PP_TXFORMAT_X_5: -+ i = (reg - R200_PP_TXFORMAT_X_0) / 32; -+ track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7; -+ tmp = (ib_chunk->kdata[idx] >> 16) & 0x3; -+ /* 2D, 3D, CUBE */ -+ switch (tmp) { -+ case 0: -+ case 5: -+ case 6: -+ case 7: -+ track->textures[i].tex_coord_type = 0; -+ break; -+ case 1: -+ track->textures[i].tex_coord_type = 1; -+ break; -+ case 2: -+ track->textures[i].tex_coord_type = 2; -+ break; -+ } -+ break; -+ case R200_PP_TXFORMAT_0: -+ case R200_PP_TXFORMAT_1: -+ case R200_PP_TXFORMAT_2: -+ case R200_PP_TXFORMAT_3: -+ case R200_PP_TXFORMAT_4: -+ case R200_PP_TXFORMAT_5: -+ i = (reg - R200_PP_TXFORMAT_0) / 32; -+ if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) { -+ track->textures[i].use_pitch = 1; -+ } else { -+ track->textures[i].use_pitch = 0; -+ track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); -+ track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); -+ } -+ switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { -+ case R200_TXFORMAT_I8: -+ case R200_TXFORMAT_RGB332: -+ case R200_TXFORMAT_Y8: -+ track->textures[i].cpp = 1; -+ break; -+ case R200_TXFORMAT_DXT1: -+ case R200_TXFORMAT_AI88: -+ case R200_TXFORMAT_ARGB1555: -+ case R200_TXFORMAT_RGB565: -+ case R200_TXFORMAT_ARGB4444: -+ case R200_TXFORMAT_VYUY422: -+ case R200_TXFORMAT_YVYU422: -+ case R200_TXFORMAT_LDVDU655: -+ case R200_TXFORMAT_DVDU88: -+ case R200_TXFORMAT_AVYU4444: -+ track->textures[i].cpp = 2; -+ break; -+ case R200_TXFORMAT_ARGB8888: -+ case R200_TXFORMAT_RGBA8888: -+ case R200_TXFORMAT_ABGR8888: -+ case R200_TXFORMAT_BGR111110: -+ case R200_TXFORMAT_LDVDU8888: -+ case R200_TXFORMAT_DXT23: -+ case R200_TXFORMAT_DXT45: -+ track->textures[i].cpp = 4; -+ break; -+ } -+ track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); -+ track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); -+ break; -+ case R200_PP_CUBIC_FACES_0: -+ case R200_PP_CUBIC_FACES_1: -+ case R200_PP_CUBIC_FACES_2: -+ case R200_PP_CUBIC_FACES_3: -+ case R200_PP_CUBIC_FACES_4: -+ case R200_PP_CUBIC_FACES_5: -+ tmp = ib_chunk->kdata[idx]; -+ i = (reg - R200_PP_CUBIC_FACES_0) / 32; -+ for (face = 0; face < 4; face++) { -+ track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); -+ track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); -+ } -+ break; -+ default: -+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", -+ reg, idx); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int r200_init(struct radeon_device *rdev) -+{ -+ rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; -+ rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); -+ return 0; -+} -diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c -index 051bca6..a5f82f7 100644 ---- a/drivers/gpu/drm/radeon/r300.c -+++ b/drivers/gpu/drm/radeon/r300.c -@@ -32,6 +32,10 @@ - #include "radeon.h" - #include "radeon_drm.h" - #include "radeon_share.h" -+#include "r100_track.h" -+#include "r300d.h" -+ -+#include "r300_reg_safe.h" - - /* r300,r350,rv350,rv370,rv380 depends on : */ - void r100_hdp_reset(struct radeon_device *rdev); -@@ -47,14 +51,10 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx); - int r100_cs_packet_parse_vline(struct radeon_cs_parser *p); --int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, -- struct radeon_cs_reloc **cs_reloc); - int r100_cs_parse_packet0(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - const unsigned *auth, unsigned n, - radeon_packet0_check_t check); --void r100_cs_dump_packet(struct radeon_cs_parser *p, -- struct radeon_cs_packet *pkt); - int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - struct radeon_object *robj); -@@ -128,7 +128,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev) - WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); - rv370_pcie_gart_tlb_flush(rdev); - DRM_INFO("PCIE GART of %uM enabled (table at 0x%08X).\n", -- rdev->mc.gtt_size >> 20, table_addr); -+ (unsigned)(rdev->mc.gtt_size >> 20), table_addr); - rdev->gart.ready = true; - return 0; - } -@@ -704,307 +704,13 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev) - /* - * CS functions - */ --struct r300_cs_track_cb { -- struct radeon_object *robj; -- unsigned pitch; -- unsigned cpp; -- unsigned offset; --}; -- --struct r300_cs_track_array { -- struct radeon_object *robj; -- unsigned esize; --}; -- --struct r300_cs_track_texture { -- struct radeon_object *robj; -- unsigned pitch; -- unsigned width; -- unsigned height; -- unsigned num_levels; -- unsigned cpp; -- unsigned tex_coord_type; -- unsigned txdepth; -- unsigned width_11; -- unsigned height_11; -- bool use_pitch; -- bool enabled; -- bool roundup_w; -- bool roundup_h; --}; -- --struct r300_cs_track { -- unsigned num_cb; -- unsigned maxy; -- unsigned vtx_size; -- unsigned vap_vf_cntl; -- unsigned immd_dwords; -- unsigned num_arrays; -- unsigned max_indx; -- struct r300_cs_track_array arrays[11]; -- struct r300_cs_track_cb cb[4]; -- struct r300_cs_track_cb zb; -- struct r300_cs_track_texture textures[16]; -- bool z_enabled; --}; -- --static inline void r300_cs_track_texture_print(struct r300_cs_track_texture *t) --{ -- DRM_ERROR("pitch %d\n", t->pitch); -- DRM_ERROR("width %d\n", t->width); -- DRM_ERROR("height %d\n", t->height); -- DRM_ERROR("num levels %d\n", t->num_levels); -- DRM_ERROR("depth %d\n", t->txdepth); -- DRM_ERROR("bpp %d\n", t->cpp); -- DRM_ERROR("coordinate type %d\n", t->tex_coord_type); -- DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); -- DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); --} -- --static inline int r300_cs_track_texture_check(struct radeon_device *rdev, -- struct r300_cs_track *track) --{ -- struct radeon_object *robj; -- unsigned long size; -- unsigned u, i, w, h; -- -- for (u = 0; u < 16; u++) { -- if (!track->textures[u].enabled) -- continue; -- robj = track->textures[u].robj; -- if (robj == NULL) { -- DRM_ERROR("No texture bound to unit %u\n", u); -- return -EINVAL; -- } -- size = 0; -- for (i = 0; i <= track->textures[u].num_levels; i++) { -- if (track->textures[u].use_pitch) { -- w = track->textures[u].pitch / (1 << i); -- } else { -- w = track->textures[u].width / (1 << i); -- if (rdev->family >= CHIP_RV515) -- w |= track->textures[u].width_11; -- if (track->textures[u].roundup_w) -- w = roundup_pow_of_two(w); -- } -- h = track->textures[u].height / (1 << i); -- if (rdev->family >= CHIP_RV515) -- h |= track->textures[u].height_11; -- if (track->textures[u].roundup_h) -- h = roundup_pow_of_two(h); -- size += w * h; -- } -- size *= track->textures[u].cpp; -- switch (track->textures[u].tex_coord_type) { -- case 0: -- break; -- case 1: -- size *= (1 << track->textures[u].txdepth); -- break; -- case 2: -- size *= 6; -- break; -- default: -- DRM_ERROR("Invalid texture coordinate type %u for unit " -- "%u\n", track->textures[u].tex_coord_type, u); -- return -EINVAL; -- } -- if (size > radeon_object_size(robj)) { -- DRM_ERROR("Texture of unit %u needs %lu bytes but is " -- "%lu\n", u, size, radeon_object_size(robj)); -- r300_cs_track_texture_print(&track->textures[u]); -- return -EINVAL; -- } -- } -- return 0; --} -- --int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track) --{ -- unsigned i; -- unsigned long size; -- unsigned prim_walk; -- unsigned nverts; -- -- for (i = 0; i < track->num_cb; i++) { -- if (track->cb[i].robj == NULL) { -- DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); -- return -EINVAL; -- } -- size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; -- size += track->cb[i].offset; -- if (size > radeon_object_size(track->cb[i].robj)) { -- DRM_ERROR("[drm] Buffer too small for color buffer %d " -- "(need %lu have %lu) !\n", i, size, -- radeon_object_size(track->cb[i].robj)); -- DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", -- i, track->cb[i].pitch, track->cb[i].cpp, -- track->cb[i].offset, track->maxy); -- return -EINVAL; -- } -- } -- if (track->z_enabled) { -- if (track->zb.robj == NULL) { -- DRM_ERROR("[drm] No buffer for z buffer !\n"); -- return -EINVAL; -- } -- size = track->zb.pitch * track->zb.cpp * track->maxy; -- size += track->zb.offset; -- if (size > radeon_object_size(track->zb.robj)) { -- DRM_ERROR("[drm] Buffer too small for z buffer " -- "(need %lu have %lu) !\n", size, -- radeon_object_size(track->zb.robj)); -- return -EINVAL; -- } -- } -- prim_walk = (track->vap_vf_cntl >> 4) & 0x3; -- nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; -- switch (prim_walk) { -- case 1: -- for (i = 0; i < track->num_arrays; i++) { -- size = track->arrays[i].esize * track->max_indx * 4; -- if (track->arrays[i].robj == NULL) { -- DRM_ERROR("(PW %u) Vertex array %u no buffer " -- "bound\n", prim_walk, i); -- return -EINVAL; -- } -- if (size > radeon_object_size(track->arrays[i].robj)) { -- DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " -- "have %lu dwords\n", prim_walk, i, -- size >> 2, -- radeon_object_size(track->arrays[i].robj) >> 2); -- DRM_ERROR("Max indices %u\n", track->max_indx); -- return -EINVAL; -- } -- } -- break; -- case 2: -- for (i = 0; i < track->num_arrays; i++) { -- size = track->arrays[i].esize * (nverts - 1) * 4; -- if (track->arrays[i].robj == NULL) { -- DRM_ERROR("(PW %u) Vertex array %u no buffer " -- "bound\n", prim_walk, i); -- return -EINVAL; -- } -- if (size > radeon_object_size(track->arrays[i].robj)) { -- DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " -- "have %lu dwords\n", prim_walk, i, size >> 2, -- radeon_object_size(track->arrays[i].robj) >> 2); -- return -EINVAL; -- } -- } -- break; -- case 3: -- size = track->vtx_size * nverts; -- if (size != track->immd_dwords) { -- DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", -- track->immd_dwords, size); -- DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", -- nverts, track->vtx_size); -- return -EINVAL; -- } -- break; -- default: -- DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", -- prim_walk); -- return -EINVAL; -- } -- return r300_cs_track_texture_check(rdev, track); --} -- --static inline void r300_cs_track_clear(struct r300_cs_track *track) --{ -- unsigned i; -- -- track->num_cb = 4; -- track->maxy = 4096; -- for (i = 0; i < track->num_cb; i++) { -- track->cb[i].robj = NULL; -- track->cb[i].pitch = 8192; -- track->cb[i].cpp = 16; -- track->cb[i].offset = 0; -- } -- track->z_enabled = true; -- track->zb.robj = NULL; -- track->zb.pitch = 8192; -- track->zb.cpp = 4; -- track->zb.offset = 0; -- track->vtx_size = 0x7F; -- track->immd_dwords = 0xFFFFFFFFUL; -- track->num_arrays = 11; -- track->max_indx = 0x00FFFFFFUL; -- for (i = 0; i < track->num_arrays; i++) { -- track->arrays[i].robj = NULL; -- track->arrays[i].esize = 0x7F; -- } -- for (i = 0; i < 16; i++) { -- track->textures[i].pitch = 16536; -- track->textures[i].width = 16536; -- track->textures[i].height = 16536; -- track->textures[i].width_11 = 1 << 11; -- track->textures[i].height_11 = 1 << 11; -- track->textures[i].num_levels = 12; -- track->textures[i].txdepth = 16; -- track->textures[i].cpp = 64; -- track->textures[i].tex_coord_type = 1; -- track->textures[i].robj = NULL; -- /* CS IB emission code makes sure texture unit are disabled */ -- track->textures[i].enabled = false; -- track->textures[i].roundup_w = true; -- track->textures[i].roundup_h = true; -- } --} -- --static const unsigned r300_reg_safe_bm[159] = { -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF, -- 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, -- 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, -- 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF, -- 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -- 0x00000000, 0x0000C100, 0x00000000, 0x00000000, -- 0x00000000, 0x00000000, 0x00000000, 0x00000000, -- 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, -- 0x00000000, 0x00000000, 0x00000000, 0x00000000, -- 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, --}; -- - static int r300_packet0_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt, - unsigned idx, unsigned reg) - { - struct radeon_cs_chunk *ib_chunk; - struct radeon_cs_reloc *reloc; -- struct r300_cs_track *track; -+ struct r100_cs_track *track; - volatile uint32_t *ib; - uint32_t tmp, tile_flags = 0; - unsigned i; -@@ -1012,7 +718,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, - - ib = p->ib->ptr; - ib_chunk = &p->chunks[p->chunk_ib_idx]; -- track = (struct r300_cs_track*)p->track; -+ track = (struct r100_cs_track *)p->track; - switch(reg) { - case AVIVO_D1MODE_VLINE_START_END: - case RADEON_CRTC_GUI_TRIG_VLINE: -@@ -1026,28 +732,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p, - break; - case RADEON_DST_PITCH_OFFSET: - case RADEON_SRC_PITCH_OFFSET: -- r = r100_cs_packet_next_reloc(p, &reloc); -- if (r) { -- DRM_ERROR("No reloc for ib[%d]=0x%04X\n", -- idx, reg); -- r100_cs_dump_packet(p, pkt); -+ r = r100_reloc_pitch_offset(p, pkt, idx, reg); -+ if (r) - return r; -- } -- tmp = ib_chunk->kdata[idx] & 0x003fffff; -- tmp += (((u32)reloc->lobj.gpu_offset) >> 10); -- -- if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) -- tile_flags |= RADEON_DST_TILE_MACRO; -- if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { -- if (reg == RADEON_SRC_PITCH_OFFSET) { -- DRM_ERROR("Cannot src blit from microtiled surface\n"); -- r100_cs_dump_packet(p, pkt); -- return -EINVAL; -- } -- tile_flags |= RADEON_DST_TILE_MICRO; -- } -- tmp |= tile_flags; -- ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp; - break; - case R300_RB3D_COLOROFFSET0: - case R300_RB3D_COLOROFFSET1: -@@ -1256,42 +943,41 @@ static int r300_packet0_check(struct radeon_cs_parser *p, - tmp = (ib_chunk->kdata[idx] >> 25) & 0x3; - track->textures[i].tex_coord_type = tmp; - switch ((ib_chunk->kdata[idx] & 0x1F)) { -- case 0: -- case 2: -- case 5: -- case 18: -- case 20: -- case 21: -+ case R300_TX_FORMAT_X8: -+ case R300_TX_FORMAT_Y4X4: -+ case R300_TX_FORMAT_Z3Y3X2: - track->textures[i].cpp = 1; - break; -- case 1: -- case 3: -- case 6: -- case 7: -- case 10: -- case 11: -- case 19: -- case 22: -- case 24: -+ case R300_TX_FORMAT_X16: -+ case R300_TX_FORMAT_Y8X8: -+ case R300_TX_FORMAT_Z5Y6X5: -+ case R300_TX_FORMAT_Z6Y5X5: -+ case R300_TX_FORMAT_W4Z4Y4X4: -+ case R300_TX_FORMAT_W1Z5Y5X5: -+ case R300_TX_FORMAT_DXT1: -+ case R300_TX_FORMAT_D3DMFT_CxV8U8: -+ case R300_TX_FORMAT_B8G8_B8G8: -+ case R300_TX_FORMAT_G8R8_G8B8: - track->textures[i].cpp = 2; - break; -- case 4: -- case 8: -- case 9: -- case 12: -- case 13: -- case 23: -- case 25: -- case 27: -- case 30: -+ case R300_TX_FORMAT_Y16X16: -+ case R300_TX_FORMAT_Z11Y11X10: -+ case R300_TX_FORMAT_Z10Y11X11: -+ case R300_TX_FORMAT_W8Z8Y8X8: -+ case R300_TX_FORMAT_W2Z10Y10X10: -+ case 0x17: -+ case R300_TX_FORMAT_FL_I32: -+ case 0x1e: -+ case R300_TX_FORMAT_DXT3: -+ case R300_TX_FORMAT_DXT5: - track->textures[i].cpp = 4; - break; -- case 14: -- case 26: -- case 28: -+ case R300_TX_FORMAT_W16Z16Y16X16: -+ case R300_TX_FORMAT_FL_R16G16B16A16: -+ case R300_TX_FORMAT_FL_I32A32: - track->textures[i].cpp = 8; - break; -- case 29: -+ case R300_TX_FORMAT_FL_R32G32B32A32: - track->textures[i].cpp = 16; - break; - default: -@@ -1319,11 +1005,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p, - case 0x443C: - /* TX_FILTER0_[0-15] */ - i = (reg - 0x4400) >> 2; -- tmp = ib_chunk->kdata[idx] & 0x7;; -+ tmp = ib_chunk->kdata[idx] & 0x7; - if (tmp == 2 || tmp == 4 || tmp == 6) { - track->textures[i].roundup_w = false; - } -- tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;; -+ tmp = (ib_chunk->kdata[idx] >> 3) & 0x7; - if (tmp == 2 || tmp == 4 || tmp == 6) { - track->textures[i].roundup_h = false; - } -@@ -1411,8 +1097,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p, - struct radeon_cs_packet *pkt) - { - struct radeon_cs_chunk *ib_chunk; -+ - struct radeon_cs_reloc *reloc; -- struct r300_cs_track *track; -+ struct r100_cs_track *track; - volatile uint32_t *ib; - unsigned idx; - unsigned i, c; -@@ -1421,7 +1108,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, - ib = p->ib->ptr; - ib_chunk = &p->chunks[p->chunk_ib_idx]; - idx = pkt->idx + 1; -- track = (struct r300_cs_track*)p->track; -+ track = (struct r100_cs_track *)p->track; - switch(pkt->opcode) { - case PACKET3_3D_LOAD_VBPNTR: - c = ib_chunk->kdata[idx++] & 0x1F; -@@ -1488,7 +1175,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, - } - track->vap_vf_cntl = ib_chunk->kdata[idx+1]; - track->immd_dwords = pkt->count - 1; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } -@@ -1503,35 +1190,35 @@ static int r300_packet3_check(struct radeon_cs_parser *p, - } - track->vap_vf_cntl = ib_chunk->kdata[idx]; - track->immd_dwords = pkt->count; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_VBUF: - track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_VBUF_2: - track->vap_vf_cntl = ib_chunk->kdata[idx]; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_INDX: - track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } - break; - case PACKET3_3D_DRAW_INDX_2: - track->vap_vf_cntl = ib_chunk->kdata[idx]; -- r = r300_cs_track_check(p->rdev, track); -+ r = r100_cs_track_check(p->rdev, track); - if (r) { - return r; - } -@@ -1548,10 +1235,10 @@ static int r300_packet3_check(struct radeon_cs_parser *p, - int r300_cs_parse(struct radeon_cs_parser *p) - { - struct radeon_cs_packet pkt; -- struct r300_cs_track track; -+ struct r100_cs_track track; - int r; - -- r300_cs_track_clear(&track); -+ r100_cs_track_clear(p->rdev, &track); - p->track = &track; - do { - r = r100_cs_packet_parse(p, &pkt, p->idx); -diff --git a/drivers/gpu/drm/radeon/r300.h b/drivers/gpu/drm/radeon/r300.h -deleted file mode 100644 -index 8486b4d..0000000 ---- a/drivers/gpu/drm/radeon/r300.h -+++ /dev/null -@@ -1,36 +0,0 @@ --/* -- * Copyright 2008 Advanced Micro Devices, Inc. -- * Copyright 2008 Red Hat Inc. -- * Copyright 2009 Jerome Glisse. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -- * -- * Authors: Dave Airlie -- * Alex Deucher -- * Jerome Glisse -- */ --#ifndef R300_H --#define R300_H -- --struct r300_asic { -- const unsigned *reg_safe_bm; -- unsigned reg_safe_bm_size; --}; -- --#endif -diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h -new file mode 100644 -index 0000000..63ec076 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r300d.h -@@ -0,0 +1,76 @@ -+/* -+ * Copyright 2008 Advanced Micro Devices, Inc. -+ * Copyright 2008 Red Hat Inc. -+ * Copyright 2009 Jerome Glisse. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef __R300D_H__ -+#define __R300D_H__ -+ -+#define CP_PACKET0 0x00000000 -+#define PACKET0_BASE_INDEX_SHIFT 0 -+#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -+#define PACKET0_COUNT_SHIFT 16 -+#define PACKET0_COUNT_MASK (0x3fff << 16) -+#define CP_PACKET1 0x40000000 -+#define CP_PACKET2 0x80000000 -+#define PACKET2_PAD_SHIFT 0 -+#define PACKET2_PAD_MASK (0x3fffffff << 0) -+#define CP_PACKET3 0xC0000000 -+#define PACKET3_IT_OPCODE_SHIFT 8 -+#define PACKET3_IT_OPCODE_MASK (0xff << 8) -+#define PACKET3_COUNT_SHIFT 16 -+#define PACKET3_COUNT_MASK (0x3fff << 16) -+/* PACKET3 op code */ -+#define PACKET3_NOP 0x10 -+#define PACKET3_3D_DRAW_VBUF 0x28 -+#define PACKET3_3D_DRAW_IMMD 0x29 -+#define PACKET3_3D_DRAW_INDX 0x2A -+#define PACKET3_3D_LOAD_VBPNTR 0x2F -+#define PACKET3_INDX_BUFFER 0x33 -+#define PACKET3_3D_DRAW_VBUF_2 0x34 -+#define PACKET3_3D_DRAW_IMMD_2 0x35 -+#define PACKET3_3D_DRAW_INDX_2 0x36 -+#define PACKET3_BITBLT_MULTI 0x9B -+ -+#define PACKET0(reg, n) (CP_PACKET0 | \ -+ REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ -+ REG_SET(PACKET0_COUNT, (n))) -+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -+#define PACKET3(op, n) (CP_PACKET3 | \ -+ REG_SET(PACKET3_IT_OPCODE, (op)) | \ -+ REG_SET(PACKET3_COUNT, (n))) -+ -+#define PACKET_TYPE0 0 -+#define PACKET_TYPE1 1 -+#define PACKET_TYPE2 2 -+#define PACKET_TYPE3 3 -+ -+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c -index 538cd90..d8fcef4 100644 ---- a/drivers/gpu/drm/radeon/r600.c -+++ b/drivers/gpu/drm/radeon/r600.c -@@ -25,12 +25,46 @@ - * Alex Deucher - * Jerome Glisse - */ -+#include -+#include -+#include - #include "drmP.h" --#include "radeon_reg.h" -+#include "radeon_drm.h" - #include "radeon.h" -+#include "radeon_mode.h" -+#include "radeon_share.h" -+#include "r600d.h" -+#include "avivod.h" -+#include "atom.h" - --/* r600,rv610,rv630,rv620,rv635,rv670 depends on : */ --void rs600_mc_disable_clients(struct radeon_device *rdev); -+#define PFP_UCODE_SIZE 576 -+#define PM4_UCODE_SIZE 1792 -+#define R700_PFP_UCODE_SIZE 848 -+#define R700_PM4_UCODE_SIZE 1360 -+ -+/* Firmware Names */ -+MODULE_FIRMWARE("radeon/R600_pfp.bin"); -+MODULE_FIRMWARE("radeon/R600_me.bin"); -+MODULE_FIRMWARE("radeon/RV610_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV610_me.bin"); -+MODULE_FIRMWARE("radeon/RV630_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV630_me.bin"); -+MODULE_FIRMWARE("radeon/RV620_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV620_me.bin"); -+MODULE_FIRMWARE("radeon/RV635_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV635_me.bin"); -+MODULE_FIRMWARE("radeon/RV670_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV670_me.bin"); -+MODULE_FIRMWARE("radeon/RS780_pfp.bin"); -+MODULE_FIRMWARE("radeon/RS780_me.bin"); -+MODULE_FIRMWARE("radeon/RV770_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV770_me.bin"); -+MODULE_FIRMWARE("radeon/RV730_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV730_me.bin"); -+MODULE_FIRMWARE("radeon/RV710_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV710_me.bin"); -+ -+int r600_debugfs_mc_info_init(struct radeon_device *rdev); - - /* This files gather functions specifics to: - * r600,rv610,rv630,rv620,rv635,rv670 -@@ -39,87 +73,270 @@ void rs600_mc_disable_clients(struct radeon_device *rdev); - */ - int r600_mc_wait_for_idle(struct radeon_device *rdev); - void r600_gpu_init(struct radeon_device *rdev); -+void r600_fini(struct radeon_device *rdev); - - - /* -- * MC -+ * R600 PCIE GART - */ --int r600_mc_init(struct radeon_device *rdev) -+int r600_gart_clear_page(struct radeon_device *rdev, int i) - { -- uint32_t tmp; -+ void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; -+ u64 pte; - -- r600_gpu_init(rdev); -+ if (i < 0 || i > rdev->gart.num_gpu_pages) -+ return -EINVAL; -+ pte = 0; -+ writeq(pte, ((void __iomem *)ptr) + (i * 8)); -+ return 0; -+} - -- /* setup the gart before changing location so we can ask to -- * discard unmapped mc request -- */ -- /* FIXME: disable out of gart access */ -- tmp = rdev->mc.gtt_location / 4096; -- tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); -- WREG32(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp); -- tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096; -- tmp = REG_SET(R600_LOGICAL_PAGE_NUMBER, tmp); -- WREG32(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp); -- -- rs600_mc_disable_clients(rdev); -- if (r600_mc_wait_for_idle(rdev)) { -- printk(KERN_WARNING "Failed to wait MC idle while " -- "programming pipes. Bad things might happen.\n"); -+void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) -+{ -+ unsigned i; -+ u32 tmp; -+ -+ WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); -+ WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); -+ WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ /* read MC_STATUS */ -+ tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE); -+ tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT; -+ if (tmp == 2) { -+ printk(KERN_WARNING "[drm] r600 flush TLB failed\n"); -+ return; -+ } -+ if (tmp) { -+ return; -+ } -+ udelay(1); -+ } -+} -+ -+int r600_pcie_gart_enable(struct radeon_device *rdev) -+{ -+ u32 tmp; -+ int r, i; -+ -+ /* Initialize common gart structure */ -+ r = radeon_gart_init(rdev); -+ if (r) { -+ return r; -+ } -+ rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; -+ r = radeon_gart_table_vram_alloc(rdev); -+ if (r) { -+ return r; - } -+ for (i = 0; i < rdev->gart.num_gpu_pages; i++) -+ r600_gart_clear_page(rdev, i); -+ /* Setup L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | -+ ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | -+ EFFECTIVE_L2_QUEUE_SIZE(7)); -+ WREG32(VM_L2_CNTL2, 0); -+ WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); -+ /* Setup TLB control */ -+ tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | -+ SYSTEM_ACCESS_MODE_NOT_IN_SYS | -+ EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | -+ ENABLE_WAIT_L2_QUERY; -+ WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING); -+ WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); -+ WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); -+ WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | -+ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); -+ WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, -+ (u32)(rdev->dummy_page.addr >> 12)); -+ for (i = 1; i < 7; i++) -+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - -- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; -- tmp = REG_SET(R600_MC_FB_TOP, tmp >> 24); -- tmp |= REG_SET(R600_MC_FB_BASE, rdev->mc.vram_location >> 24); -- WREG32(R600_MC_VM_FB_LOCATION, tmp); -- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; -- tmp = REG_SET(R600_MC_AGP_TOP, tmp >> 22); -- WREG32(R600_MC_VM_AGP_TOP, tmp); -- tmp = REG_SET(R600_MC_AGP_BOT, rdev->mc.gtt_location >> 22); -- WREG32(R600_MC_VM_AGP_BOT, tmp); -+ r600_pcie_gart_tlb_flush(rdev); -+ rdev->gart.ready = true; - return 0; - } - --void r600_mc_fini(struct radeon_device *rdev) -+void r600_pcie_gart_disable(struct radeon_device *rdev) - { -- /* FIXME: implement */ --} -+ u32 tmp; -+ int i; - -+ /* Clear ptes*/ -+ for (i = 0; i < rdev->gart.num_gpu_pages; i++) -+ r600_gart_clear_page(rdev, i); -+ r600_pcie_gart_tlb_flush(rdev); -+ /* Disable all tables */ -+ for (i = 0; i < 7; i++) -+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - --/* -- * Global GPU functions -- */ --void r600_errata(struct radeon_device *rdev) --{ -- rdev->pll_errata = 0; -+ /* Disable L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | -+ EFFECTIVE_L2_QUEUE_SIZE(7)); -+ WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1)); -+ /* Setup L1 TLB control */ -+ tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) | -+ ENABLE_WAIT_L2_QUERY; -+ WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); -+ WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); - } - - int r600_mc_wait_for_idle(struct radeon_device *rdev) - { -- /* FIXME: implement */ -- return 0; -+ unsigned i; -+ u32 tmp; -+ -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ /* read MC_STATUS */ -+ tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00; -+ if (!tmp) -+ return 0; -+ udelay(1); -+ } -+ return -1; - } - --void r600_gpu_init(struct radeon_device *rdev) -+static void r600_mc_resume(struct radeon_device *rdev) - { -- /* FIXME: implement */ --} -+ u32 d1vga_control, d2vga_control; -+ u32 vga_render_control, vga_hdp_control; -+ u32 d1crtc_control, d2crtc_control; -+ u32 new_d1grph_primary, new_d1grph_secondary; -+ u32 new_d2grph_primary, new_d2grph_secondary; -+ u64 old_vram_start; -+ u32 tmp; -+ int i, j; - -+ /* Initialize HDP */ -+ for (i = 0, j = 0; i < 32; i++, j += 0x18) { -+ WREG32((0x2c14 + j), 0x00000000); -+ WREG32((0x2c18 + j), 0x00000000); -+ WREG32((0x2c1c + j), 0x00000000); -+ WREG32((0x2c20 + j), 0x00000000); -+ WREG32((0x2c24 + j), 0x00000000); -+ } -+ WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); - --/* -- * VRAM info -- */ --void r600_vram_get_type(struct radeon_device *rdev) -+ d1vga_control = RREG32(D1VGA_CONTROL); -+ d2vga_control = RREG32(D2VGA_CONTROL); -+ vga_render_control = RREG32(VGA_RENDER_CONTROL); -+ vga_hdp_control = RREG32(VGA_HDP_CONTROL); -+ d1crtc_control = RREG32(D1CRTC_CONTROL); -+ d2crtc_control = RREG32(D2CRTC_CONTROL); -+ old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; -+ new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS); -+ new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS); -+ new_d1grph_primary += rdev->mc.vram_start - old_vram_start; -+ new_d1grph_secondary += rdev->mc.vram_start - old_vram_start; -+ new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS); -+ new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS); -+ new_d2grph_primary += rdev->mc.vram_start - old_vram_start; -+ new_d2grph_secondary += rdev->mc.vram_start - old_vram_start; -+ -+ /* Stop all video */ -+ WREG32(D1VGA_CONTROL, 0); -+ WREG32(D2VGA_CONTROL, 0); -+ WREG32(VGA_RENDER_CONTROL, 0); -+ WREG32(D1CRTC_UPDATE_LOCK, 1); -+ WREG32(D2CRTC_UPDATE_LOCK, 1); -+ WREG32(D1CRTC_CONTROL, 0); -+ WREG32(D2CRTC_CONTROL, 0); -+ WREG32(D1CRTC_UPDATE_LOCK, 0); -+ WREG32(D2CRTC_UPDATE_LOCK, 0); -+ -+ mdelay(1); -+ if (r600_mc_wait_for_idle(rdev)) { -+ printk(KERN_WARNING "[drm] MC not idle !\n"); -+ } -+ -+ /* Lockout access through VGA aperture*/ -+ WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); -+ -+ /* Update configuration */ -+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); -+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); -+ WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); -+ tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; -+ tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); -+ WREG32(MC_VM_FB_LOCATION, tmp); -+ WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); -+ WREG32(HDP_NONSURFACE_INFO, (2 << 7)); -+ WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); -+ if (rdev->flags & RADEON_IS_AGP) { -+ WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); -+ WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); -+ WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); -+ } else { -+ WREG32(MC_VM_AGP_BASE, 0); -+ WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); -+ WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); -+ } -+ WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary); -+ WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary); -+ WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary); -+ WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary); -+ WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); -+ -+ /* Unlock host access */ -+ WREG32(VGA_HDP_CONTROL, vga_hdp_control); -+ -+ mdelay(1); -+ if (r600_mc_wait_for_idle(rdev)) { -+ printk(KERN_WARNING "[drm] MC not idle !\n"); -+ } -+ -+ /* Restore video state */ -+ WREG32(D1CRTC_UPDATE_LOCK, 1); -+ WREG32(D2CRTC_UPDATE_LOCK, 1); -+ WREG32(D1CRTC_CONTROL, d1crtc_control); -+ WREG32(D2CRTC_CONTROL, d2crtc_control); -+ WREG32(D1CRTC_UPDATE_LOCK, 0); -+ WREG32(D2CRTC_UPDATE_LOCK, 0); -+ WREG32(D1VGA_CONTROL, d1vga_control); -+ WREG32(D2VGA_CONTROL, d2vga_control); -+ WREG32(VGA_RENDER_CONTROL, vga_render_control); -+} -+ -+int r600_mc_init(struct radeon_device *rdev) - { -- uint32_t tmp; -+ fixed20_12 a; -+ u32 tmp; - int chansize; -+ int r; - -+ /* Get VRAM informations */ - rdev->mc.vram_width = 128; - rdev->mc.vram_is_ddr = true; -- -- tmp = RREG32(R600_RAMCFG); -- if (tmp & R600_CHANSIZE_OVERRIDE) { -+ tmp = RREG32(RAMCFG); -+ if (tmp & CHANSIZE_OVERRIDE) { - chansize = 16; -- } else if (tmp & R600_CHANSIZE) { -+ } else if (tmp & CHANSIZE_MASK) { - chansize = 64; - } else { - chansize = 32; -@@ -135,36 +352,1391 @@ void r600_vram_get_type(struct radeon_device *rdev) - (rdev->family == CHIP_RV635)) { - rdev->mc.vram_width = 2 * chansize; - } -+ /* Could aper size report 0 ? */ -+ rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); -+ rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); -+ /* Setup GPU memory space */ -+ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); -+ rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); -+ if (rdev->flags & RADEON_IS_AGP) { -+ r = radeon_agp_init(rdev); -+ if (r) -+ return r; -+ /* gtt_size is setup by radeon_agp_init */ -+ rdev->mc.gtt_location = rdev->mc.agp_base; -+ tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; -+ /* Try to put vram before or after AGP because we -+ * we want SYSTEM_APERTURE to cover both VRAM and -+ * AGP so that GPU can catch out of VRAM/AGP access -+ */ -+ if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { -+ /* Enought place before */ -+ rdev->mc.vram_location = rdev->mc.gtt_location - -+ rdev->mc.mc_vram_size; -+ } else if (tmp > rdev->mc.mc_vram_size) { -+ /* Enought place after */ -+ rdev->mc.vram_location = rdev->mc.gtt_location + -+ rdev->mc.gtt_size; -+ } else { -+ /* Try to setup VRAM then AGP might not -+ * not work on some card -+ */ -+ rdev->mc.vram_location = 0x00000000UL; -+ rdev->mc.gtt_location = rdev->mc.mc_vram_size; -+ } -+ } else { -+ if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { -+ rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & -+ 0xFFFF) << 24; -+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -+ tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; -+ if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { -+ /* Enough place after vram */ -+ rdev->mc.gtt_location = tmp; -+ } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { -+ /* Enough place before vram */ -+ rdev->mc.gtt_location = 0; -+ } else { -+ /* Not enough place after or before shrink -+ * gart size -+ */ -+ if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { -+ rdev->mc.gtt_location = 0; -+ rdev->mc.gtt_size = rdev->mc.vram_location; -+ } else { -+ rdev->mc.gtt_location = tmp; -+ rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; -+ } -+ } -+ rdev->mc.gtt_location = rdev->mc.mc_vram_size; -+ } else { -+ rdev->mc.vram_location = 0x00000000UL; -+ rdev->mc.gtt_location = rdev->mc.mc_vram_size; -+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -+ } -+ } -+ rdev->mc.vram_start = rdev->mc.vram_location; -+ rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; -+ rdev->mc.gtt_start = rdev->mc.gtt_location; -+ rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; -+ /* FIXME: we should enforce default clock in case GPU is not in -+ * default setup -+ */ -+ a.full = rfixed_const(100); -+ rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -+ rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); -+ return 0; - } - --void r600_vram_info(struct radeon_device *rdev) -+/* We doesn't check that the GPU really needs a reset we simply do the -+ * reset, it's up to the caller to determine if the GPU needs one. We -+ * might add an helper function to check that. -+ */ -+int r600_gpu_soft_reset(struct radeon_device *rdev) - { -- r600_vram_get_type(rdev); -- rdev->mc.real_vram_size = RREG32(R600_CONFIG_MEMSIZE); -- rdev->mc.mc_vram_size = rdev->mc.real_vram_size; -+ u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | -+ S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | -+ S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | -+ S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) | -+ S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) | -+ S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) | -+ S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) | -+ S_008010_GUI_ACTIVE(1); -+ u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) | -+ S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) | -+ S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) | -+ S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) | -+ S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) | -+ S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) | -+ S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | -+ S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); -+ u32 srbm_reset = 0; - -- /* Could aper size report 0 ? */ -- rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); -- rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); -+ /* Disable CP parsing/prefetching */ -+ WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); -+ /* Check if any of the rendering block is busy and reset it */ -+ if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || -+ (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { -+ WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) | -+ S_008020_SOFT_RESET_DB(1) | -+ S_008020_SOFT_RESET_CB(1) | -+ S_008020_SOFT_RESET_PA(1) | -+ S_008020_SOFT_RESET_SC(1) | -+ S_008020_SOFT_RESET_SMX(1) | -+ S_008020_SOFT_RESET_SPI(1) | -+ S_008020_SOFT_RESET_SX(1) | -+ S_008020_SOFT_RESET_SH(1) | -+ S_008020_SOFT_RESET_TC(1) | -+ S_008020_SOFT_RESET_TA(1) | -+ S_008020_SOFT_RESET_VC(1) | -+ S_008020_SOFT_RESET_VGT(1)); -+ (void)RREG32(R_008020_GRBM_SOFT_RESET); -+ udelay(50); -+ WREG32(R_008020_GRBM_SOFT_RESET, 0); -+ (void)RREG32(R_008020_GRBM_SOFT_RESET); -+ } -+ /* Reset CP (we always reset CP) */ -+ WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1)); -+ (void)RREG32(R_008020_GRBM_SOFT_RESET); -+ udelay(50); -+ WREG32(R_008020_GRBM_SOFT_RESET, 0); -+ (void)RREG32(R_008020_GRBM_SOFT_RESET); -+ /* Reset others GPU block if necessary */ -+ if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_RLC(1); -+ if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_GRBM(1); -+ if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_IH(1); -+ if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_VMC(1); -+ if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_MC(1); -+ if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_MC(1); -+ if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_MC(1); -+ if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_MC(1); -+ if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_MC(1); -+ if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_RLC(1); -+ if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) -+ srbm_reset |= S_000E60_SOFT_RESET_SEM(1); -+ WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); -+ (void)RREG32(R_000E60_SRBM_SOFT_RESET); -+ udelay(50); -+ WREG32(R_000E60_SRBM_SOFT_RESET, 0); -+ (void)RREG32(R_000E60_SRBM_SOFT_RESET); -+ /* Wait a little for things to settle down */ -+ udelay(50); -+ return 0; -+} -+ -+int r600_gpu_reset(struct radeon_device *rdev) -+{ -+ return r600_gpu_soft_reset(rdev); -+} -+ -+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, -+ u32 num_backends, -+ u32 backend_disable_mask) -+{ -+ u32 backend_map = 0; -+ u32 enabled_backends_mask; -+ u32 enabled_backends_count; -+ u32 cur_pipe; -+ u32 swizzle_pipe[R6XX_MAX_PIPES]; -+ u32 cur_backend; -+ u32 i; -+ -+ if (num_tile_pipes > R6XX_MAX_PIPES) -+ num_tile_pipes = R6XX_MAX_PIPES; -+ if (num_tile_pipes < 1) -+ num_tile_pipes = 1; -+ if (num_backends > R6XX_MAX_BACKENDS) -+ num_backends = R6XX_MAX_BACKENDS; -+ if (num_backends < 1) -+ num_backends = 1; -+ -+ enabled_backends_mask = 0; -+ enabled_backends_count = 0; -+ for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { -+ if (((backend_disable_mask >> i) & 1) == 0) { -+ enabled_backends_mask |= (1 << i); -+ ++enabled_backends_count; -+ } -+ if (enabled_backends_count == num_backends) -+ break; -+ } -+ -+ if (enabled_backends_count == 0) { -+ enabled_backends_mask = 1; -+ enabled_backends_count = 1; -+ } -+ -+ if (enabled_backends_count != num_backends) -+ num_backends = enabled_backends_count; -+ -+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); -+ switch (num_tile_pipes) { -+ case 1: -+ swizzle_pipe[0] = 0; -+ break; -+ case 2: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ break; -+ case 3: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ break; -+ case 4: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ swizzle_pipe[3] = 3; -+ break; -+ case 5: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ swizzle_pipe[2] = 2; -+ swizzle_pipe[3] = 3; -+ swizzle_pipe[4] = 4; -+ break; -+ case 6: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 5; -+ swizzle_pipe[4] = 1; -+ swizzle_pipe[5] = 3; -+ break; -+ case 7: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 6; -+ swizzle_pipe[4] = 1; -+ swizzle_pipe[5] = 3; -+ swizzle_pipe[6] = 5; -+ break; -+ case 8: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 6; -+ swizzle_pipe[4] = 1; -+ swizzle_pipe[5] = 3; -+ swizzle_pipe[6] = 5; -+ swizzle_pipe[7] = 7; -+ break; -+ } -+ -+ cur_backend = 0; -+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { -+ while (((1 << cur_backend) & enabled_backends_mask) == 0) -+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; -+ -+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); -+ -+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; -+ } -+ -+ return backend_map; -+} -+ -+int r600_count_pipe_bits(uint32_t val) -+{ -+ int i, ret = 0; -+ -+ for (i = 0; i < 32; i++) { -+ ret += val & 1; -+ val >>= 1; -+ } -+ return ret; - } - -+void r600_gpu_init(struct radeon_device *rdev) -+{ -+ u32 tiling_config; -+ u32 ramcfg; -+ u32 tmp; -+ int i, j; -+ u32 sq_config; -+ u32 sq_gpr_resource_mgmt_1 = 0; -+ u32 sq_gpr_resource_mgmt_2 = 0; -+ u32 sq_thread_resource_mgmt = 0; -+ u32 sq_stack_resource_mgmt_1 = 0; -+ u32 sq_stack_resource_mgmt_2 = 0; -+ -+ /* FIXME: implement */ -+ switch (rdev->family) { -+ case CHIP_R600: -+ rdev->config.r600.max_pipes = 4; -+ rdev->config.r600.max_tile_pipes = 8; -+ rdev->config.r600.max_simds = 4; -+ rdev->config.r600.max_backends = 4; -+ rdev->config.r600.max_gprs = 256; -+ rdev->config.r600.max_threads = 192; -+ rdev->config.r600.max_stack_entries = 256; -+ rdev->config.r600.max_hw_contexts = 8; -+ rdev->config.r600.max_gs_threads = 16; -+ rdev->config.r600.sx_max_export_size = 128; -+ rdev->config.r600.sx_max_export_pos_size = 16; -+ rdev->config.r600.sx_max_export_smx_size = 128; -+ rdev->config.r600.sq_num_cf_insts = 2; -+ break; -+ case CHIP_RV630: -+ case CHIP_RV635: -+ rdev->config.r600.max_pipes = 2; -+ rdev->config.r600.max_tile_pipes = 2; -+ rdev->config.r600.max_simds = 3; -+ rdev->config.r600.max_backends = 1; -+ rdev->config.r600.max_gprs = 128; -+ rdev->config.r600.max_threads = 192; -+ rdev->config.r600.max_stack_entries = 128; -+ rdev->config.r600.max_hw_contexts = 8; -+ rdev->config.r600.max_gs_threads = 4; -+ rdev->config.r600.sx_max_export_size = 128; -+ rdev->config.r600.sx_max_export_pos_size = 16; -+ rdev->config.r600.sx_max_export_smx_size = 128; -+ rdev->config.r600.sq_num_cf_insts = 2; -+ break; -+ case CHIP_RV610: -+ case CHIP_RV620: -+ case CHIP_RS780: -+ case CHIP_RS880: -+ rdev->config.r600.max_pipes = 1; -+ rdev->config.r600.max_tile_pipes = 1; -+ rdev->config.r600.max_simds = 2; -+ rdev->config.r600.max_backends = 1; -+ rdev->config.r600.max_gprs = 128; -+ rdev->config.r600.max_threads = 192; -+ rdev->config.r600.max_stack_entries = 128; -+ rdev->config.r600.max_hw_contexts = 4; -+ rdev->config.r600.max_gs_threads = 4; -+ rdev->config.r600.sx_max_export_size = 128; -+ rdev->config.r600.sx_max_export_pos_size = 16; -+ rdev->config.r600.sx_max_export_smx_size = 128; -+ rdev->config.r600.sq_num_cf_insts = 1; -+ break; -+ case CHIP_RV670: -+ rdev->config.r600.max_pipes = 4; -+ rdev->config.r600.max_tile_pipes = 4; -+ rdev->config.r600.max_simds = 4; -+ rdev->config.r600.max_backends = 4; -+ rdev->config.r600.max_gprs = 192; -+ rdev->config.r600.max_threads = 192; -+ rdev->config.r600.max_stack_entries = 256; -+ rdev->config.r600.max_hw_contexts = 8; -+ rdev->config.r600.max_gs_threads = 16; -+ rdev->config.r600.sx_max_export_size = 128; -+ rdev->config.r600.sx_max_export_pos_size = 16; -+ rdev->config.r600.sx_max_export_smx_size = 128; -+ rdev->config.r600.sq_num_cf_insts = 2; -+ break; -+ default: -+ break; -+ } -+ -+ /* Initialize HDP */ -+ for (i = 0, j = 0; i < 32; i++, j += 0x18) { -+ WREG32((0x2c14 + j), 0x00000000); -+ WREG32((0x2c18 + j), 0x00000000); -+ WREG32((0x2c1c + j), 0x00000000); -+ WREG32((0x2c20 + j), 0x00000000); -+ WREG32((0x2c24 + j), 0x00000000); -+ } -+ -+ WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); -+ -+ /* Setup tiling */ -+ tiling_config = 0; -+ ramcfg = RREG32(RAMCFG); -+ switch (rdev->config.r600.max_tile_pipes) { -+ case 1: -+ tiling_config |= PIPE_TILING(0); -+ break; -+ case 2: -+ tiling_config |= PIPE_TILING(1); -+ break; -+ case 4: -+ tiling_config |= PIPE_TILING(2); -+ break; -+ case 8: -+ tiling_config |= PIPE_TILING(3); -+ break; -+ default: -+ break; -+ } -+ tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); -+ tiling_config |= GROUP_SIZE(0); -+ tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; -+ if (tmp > 3) { -+ tiling_config |= ROW_TILING(3); -+ tiling_config |= SAMPLE_SPLIT(3); -+ } else { -+ tiling_config |= ROW_TILING(tmp); -+ tiling_config |= SAMPLE_SPLIT(tmp); -+ } -+ tiling_config |= BANK_SWAPS(1); -+ tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, -+ rdev->config.r600.max_backends, -+ (0xff << rdev->config.r600.max_backends) & 0xff); -+ tiling_config |= BACKEND_MAP(tmp); -+ WREG32(GB_TILING_CONFIG, tiling_config); -+ WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); -+ WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); -+ -+ tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); -+ WREG32(CC_RB_BACKEND_DISABLE, tmp); -+ -+ /* Setup pipes */ -+ tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); -+ tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); -+ WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp); -+ WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp); -+ -+ tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK); -+ WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); -+ WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); -+ -+ /* Setup some CP states */ -+ WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b))); -+ WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40))); -+ -+ WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT | -+ SYNC_WALKER | SYNC_ALIGNER)); -+ /* Setup various GPU states */ -+ if (rdev->family == CHIP_RV670) -+ WREG32(ARB_GDEC_RD_CNTL, 0x00000021); -+ -+ tmp = RREG32(SX_DEBUG_1); -+ tmp |= SMX_EVENT_RELEASE; -+ if ((rdev->family > CHIP_R600)) -+ tmp |= ENABLE_NEW_SMX_ADDRESS; -+ WREG32(SX_DEBUG_1, tmp); -+ -+ if (((rdev->family) == CHIP_R600) || -+ ((rdev->family) == CHIP_RV630) || -+ ((rdev->family) == CHIP_RV610) || -+ ((rdev->family) == CHIP_RV620) || -+ ((rdev->family) == CHIP_RS780)) { -+ WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE); -+ } else { -+ WREG32(DB_DEBUG, 0); -+ } -+ WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) | -+ DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4))); -+ -+ WREG32(PA_SC_MULTI_CHIP_CNTL, 0); -+ WREG32(VGT_NUM_INSTANCES, 0); -+ -+ WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); -+ WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0)); -+ -+ tmp = RREG32(SQ_MS_FIFO_SIZES); -+ if (((rdev->family) == CHIP_RV610) || -+ ((rdev->family) == CHIP_RV620) || -+ ((rdev->family) == CHIP_RS780)) { -+ tmp = (CACHE_FIFO_SIZE(0xa) | -+ FETCH_FIFO_HIWATER(0xa) | -+ DONE_FIFO_HIWATER(0xe0) | -+ ALU_UPDATE_FIFO_HIWATER(0x8)); -+ } else if (((rdev->family) == CHIP_R600) || -+ ((rdev->family) == CHIP_RV630)) { -+ tmp &= ~DONE_FIFO_HIWATER(0xff); -+ tmp |= DONE_FIFO_HIWATER(0x4); -+ } -+ WREG32(SQ_MS_FIFO_SIZES, tmp); -+ -+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT -+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values -+ */ -+ sq_config = RREG32(SQ_CONFIG); -+ sq_config &= ~(PS_PRIO(3) | -+ VS_PRIO(3) | -+ GS_PRIO(3) | -+ ES_PRIO(3)); -+ sq_config |= (DX9_CONSTS | -+ VC_ENABLE | -+ PS_PRIO(0) | -+ VS_PRIO(1) | -+ GS_PRIO(2) | -+ ES_PRIO(3)); -+ -+ if ((rdev->family) == CHIP_R600) { -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) | -+ NUM_VS_GPRS(124) | -+ NUM_CLAUSE_TEMP_GPRS(4)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) | -+ NUM_ES_GPRS(0)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(136) | -+ NUM_VS_THREADS(48) | -+ NUM_GS_THREADS(4) | -+ NUM_ES_THREADS(4)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) | -+ NUM_VS_STACK_ENTRIES(128)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) | -+ NUM_ES_STACK_ENTRIES(0)); -+ } else if (((rdev->family) == CHIP_RV610) || -+ ((rdev->family) == CHIP_RV620) || -+ ((rdev->family) == CHIP_RS780)) { -+ /* no vertex cache */ -+ sq_config &= ~VC_ENABLE; -+ -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | -+ NUM_VS_GPRS(44) | -+ NUM_CLAUSE_TEMP_GPRS(2)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | -+ NUM_ES_GPRS(17)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | -+ NUM_VS_THREADS(78) | -+ NUM_GS_THREADS(4) | -+ NUM_ES_THREADS(31)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | -+ NUM_VS_STACK_ENTRIES(40)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | -+ NUM_ES_STACK_ENTRIES(16)); -+ } else if (((rdev->family) == CHIP_RV630) || -+ ((rdev->family) == CHIP_RV635)) { -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | -+ NUM_VS_GPRS(44) | -+ NUM_CLAUSE_TEMP_GPRS(2)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) | -+ NUM_ES_GPRS(18)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | -+ NUM_VS_THREADS(78) | -+ NUM_GS_THREADS(4) | -+ NUM_ES_THREADS(31)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) | -+ NUM_VS_STACK_ENTRIES(40)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) | -+ NUM_ES_STACK_ENTRIES(16)); -+ } else if ((rdev->family) == CHIP_RV670) { -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) | -+ NUM_VS_GPRS(44) | -+ NUM_CLAUSE_TEMP_GPRS(2)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) | -+ NUM_ES_GPRS(17)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(79) | -+ NUM_VS_THREADS(78) | -+ NUM_GS_THREADS(4) | -+ NUM_ES_THREADS(31)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) | -+ NUM_VS_STACK_ENTRIES(64)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) | -+ NUM_ES_STACK_ENTRIES(64)); -+ } -+ -+ WREG32(SQ_CONFIG, sq_config); -+ WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); -+ WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); -+ WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); -+ WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); -+ WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); -+ -+ if (((rdev->family) == CHIP_RV610) || -+ ((rdev->family) == CHIP_RV620) || -+ ((rdev->family) == CHIP_RS780)) { -+ WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY)); -+ } else { -+ WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC)); -+ } -+ -+ /* More default values. 2D/3D driver should adjust as needed */ -+ WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) | -+ S1_X(0x4) | S1_Y(0xc))); -+ WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) | -+ S1_X(0x2) | S1_Y(0x2) | -+ S2_X(0xa) | S2_Y(0x6) | -+ S3_X(0x6) | S3_Y(0xa))); -+ WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) | -+ S1_X(0x4) | S1_Y(0xc) | -+ S2_X(0x1) | S2_Y(0x6) | -+ S3_X(0xa) | S3_Y(0xe))); -+ WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) | -+ S5_X(0x0) | S5_Y(0x0) | -+ S6_X(0xb) | S6_Y(0x4) | -+ S7_X(0x7) | S7_Y(0x8))); -+ -+ WREG32(VGT_STRMOUT_EN, 0); -+ tmp = rdev->config.r600.max_pipes * 16; -+ switch (rdev->family) { -+ case CHIP_RV610: -+ case CHIP_RS780: -+ case CHIP_RV620: -+ tmp += 32; -+ break; -+ case CHIP_RV670: -+ tmp += 128; -+ break; -+ default: -+ break; -+ } -+ if (tmp > 256) { -+ tmp = 256; -+ } -+ WREG32(VGT_ES_PER_GS, 128); -+ WREG32(VGT_GS_PER_ES, tmp); -+ WREG32(VGT_GS_PER_VS, 2); -+ WREG32(VGT_GS_VERTEX_REUSE, 16); -+ -+ /* more default values. 2D/3D driver should adjust as needed */ -+ WREG32(PA_SC_LINE_STIPPLE_STATE, 0); -+ WREG32(VGT_STRMOUT_EN, 0); -+ WREG32(SX_MISC, 0); -+ WREG32(PA_SC_MODE_CNTL, 0); -+ WREG32(PA_SC_AA_CONFIG, 0); -+ WREG32(PA_SC_LINE_STIPPLE, 0); -+ WREG32(SPI_INPUT_Z, 0); -+ WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); -+ WREG32(CB_COLOR7_FRAG, 0); -+ -+ /* Clear render buffer base addresses */ -+ WREG32(CB_COLOR0_BASE, 0); -+ WREG32(CB_COLOR1_BASE, 0); -+ WREG32(CB_COLOR2_BASE, 0); -+ WREG32(CB_COLOR3_BASE, 0); -+ WREG32(CB_COLOR4_BASE, 0); -+ WREG32(CB_COLOR5_BASE, 0); -+ WREG32(CB_COLOR6_BASE, 0); -+ WREG32(CB_COLOR7_BASE, 0); -+ WREG32(CB_COLOR7_FRAG, 0); -+ -+ switch (rdev->family) { -+ case CHIP_RV610: -+ case CHIP_RS780: -+ case CHIP_RV620: -+ tmp = TC_L2_SIZE(8); -+ break; -+ case CHIP_RV630: -+ case CHIP_RV635: -+ tmp = TC_L2_SIZE(4); -+ break; -+ case CHIP_R600: -+ tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT; -+ break; -+ default: -+ tmp = TC_L2_SIZE(0); -+ break; -+ } -+ WREG32(TC_CNTL, tmp); -+ -+ tmp = RREG32(HDP_HOST_PATH_CNTL); -+ WREG32(HDP_HOST_PATH_CNTL, tmp); -+ -+ tmp = RREG32(ARB_POP); -+ tmp |= ENABLE_TC128; -+ WREG32(ARB_POP, tmp); -+ -+ WREG32(PA_SC_MULTI_CHIP_CNTL, 0); -+ WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | -+ NUM_CLIP_SEQ(3))); -+ WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); -+} -+ -+ - /* - * Indirect registers accessor - */ --uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg) -+u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg) -+{ -+ u32 r; -+ -+ WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); -+ (void)RREG32(PCIE_PORT_INDEX); -+ r = RREG32(PCIE_PORT_DATA); -+ return r; -+} -+ -+void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) -+{ -+ WREG32(PCIE_PORT_INDEX, ((reg) & 0xff)); -+ (void)RREG32(PCIE_PORT_INDEX); -+ WREG32(PCIE_PORT_DATA, (v)); -+ (void)RREG32(PCIE_PORT_DATA); -+} -+ -+ -+/* -+ * CP & Ring -+ */ -+void r600_cp_stop(struct radeon_device *rdev) -+{ -+ WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); -+} -+ -+int r600_cp_init_microcode(struct radeon_device *rdev) -+{ -+ struct platform_device *pdev; -+ const char *chip_name; -+ size_t pfp_req_size, me_req_size; -+ char fw_name[30]; -+ int err; -+ -+ DRM_DEBUG("\n"); -+ -+ pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); -+ err = IS_ERR(pdev); -+ if (err) { -+ printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); -+ return -EINVAL; -+ } -+ -+ switch (rdev->family) { -+ case CHIP_R600: chip_name = "R600"; break; -+ case CHIP_RV610: chip_name = "RV610"; break; -+ case CHIP_RV630: chip_name = "RV630"; break; -+ case CHIP_RV620: chip_name = "RV620"; break; -+ case CHIP_RV635: chip_name = "RV635"; break; -+ case CHIP_RV670: chip_name = "RV670"; break; -+ case CHIP_RS780: -+ case CHIP_RS880: chip_name = "RS780"; break; -+ case CHIP_RV770: chip_name = "RV770"; break; -+ case CHIP_RV730: -+ case CHIP_RV740: chip_name = "RV730"; break; -+ case CHIP_RV710: chip_name = "RV710"; break; -+ default: BUG(); -+ } -+ -+ if (rdev->family >= CHIP_RV770) { -+ pfp_req_size = R700_PFP_UCODE_SIZE * 4; -+ me_req_size = R700_PM4_UCODE_SIZE * 4; -+ } else { -+ pfp_req_size = PFP_UCODE_SIZE * 4; -+ me_req_size = PM4_UCODE_SIZE * 12; -+ } -+ -+ DRM_INFO("Loading %s CP Microcode\n", chip_name); -+ -+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); -+ err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); -+ if (err) -+ goto out; -+ if (rdev->pfp_fw->size != pfp_req_size) { -+ printk(KERN_ERR -+ "r600_cp: Bogus length %zu in firmware \"%s\"\n", -+ rdev->pfp_fw->size, fw_name); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); -+ err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); -+ if (err) -+ goto out; -+ if (rdev->me_fw->size != me_req_size) { -+ printk(KERN_ERR -+ "r600_cp: Bogus length %zu in firmware \"%s\"\n", -+ rdev->me_fw->size, fw_name); -+ err = -EINVAL; -+ } -+out: -+ platform_device_unregister(pdev); -+ -+ if (err) { -+ if (err != -EINVAL) -+ printk(KERN_ERR -+ "r600_cp: Failed to load firmware \"%s\"\n", -+ fw_name); -+ release_firmware(rdev->pfp_fw); -+ rdev->pfp_fw = NULL; -+ release_firmware(rdev->me_fw); -+ rdev->me_fw = NULL; -+ } -+ return err; -+} -+ -+static int r600_cp_load_microcode(struct radeon_device *rdev) -+{ -+ const __be32 *fw_data; -+ int i; -+ -+ if (!rdev->me_fw || !rdev->pfp_fw) -+ return -EINVAL; -+ -+ r600_cp_stop(rdev); -+ -+ WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); -+ -+ /* Reset cp */ -+ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); -+ RREG32(GRBM_SOFT_RESET); -+ mdelay(15); -+ WREG32(GRBM_SOFT_RESET, 0); -+ -+ WREG32(CP_ME_RAM_WADDR, 0); -+ -+ fw_data = (const __be32 *)rdev->me_fw->data; -+ WREG32(CP_ME_RAM_WADDR, 0); -+ for (i = 0; i < PM4_UCODE_SIZE * 3; i++) -+ WREG32(CP_ME_RAM_DATA, -+ be32_to_cpup(fw_data++)); -+ -+ fw_data = (const __be32 *)rdev->pfp_fw->data; -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ for (i = 0; i < PFP_UCODE_SIZE; i++) -+ WREG32(CP_PFP_UCODE_DATA, -+ be32_to_cpup(fw_data++)); -+ -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ WREG32(CP_ME_RAM_WADDR, 0); -+ WREG32(CP_ME_RAM_RADDR, 0); -+ return 0; -+} -+ -+int r600_cp_start(struct radeon_device *rdev) -+{ -+ int r; -+ uint32_t cp_me; -+ -+ r = radeon_ring_lock(rdev, 7); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ return r; -+ } -+ radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); -+ radeon_ring_write(rdev, 0x1); -+ if (rdev->family < CHIP_RV770) { -+ radeon_ring_write(rdev, 0x3); -+ radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1); -+ } else { -+ radeon_ring_write(rdev, 0x0); -+ radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); -+ } -+ radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_unlock_commit(rdev); -+ -+ cp_me = 0xff; -+ WREG32(R_0086D8_CP_ME_CNTL, cp_me); -+ return 0; -+} -+ -+int r600_cp_resume(struct radeon_device *rdev) -+{ -+ u32 tmp; -+ u32 rb_bufsz; -+ int r; -+ -+ /* Reset cp */ -+ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); -+ RREG32(GRBM_SOFT_RESET); -+ mdelay(15); -+ WREG32(GRBM_SOFT_RESET, 0); -+ -+ /* Set ring buffer size */ -+ rb_bufsz = drm_order(rdev->cp.ring_size / 8); -+#ifdef __BIG_ENDIAN -+ WREG32(CP_RB_CNTL, BUF_SWAP_32BIT | RB_NO_UPDATE | -+ (drm_order(4096/8) << 8) | rb_bufsz); -+#else -+ WREG32(CP_RB_CNTL, RB_NO_UPDATE | (drm_order(4096/8) << 8) | rb_bufsz); -+#endif -+ WREG32(CP_SEM_WAIT_TIMER, 0x4); -+ -+ /* Set the write pointer delay */ -+ WREG32(CP_RB_WPTR_DELAY, 0); -+ -+ /* Initialize the ring buffer's read and write pointers */ -+ tmp = RREG32(CP_RB_CNTL); -+ WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); -+ WREG32(CP_RB_RPTR_WR, 0); -+ WREG32(CP_RB_WPTR, 0); -+ WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF); -+ WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr)); -+ mdelay(1); -+ WREG32(CP_RB_CNTL, tmp); -+ -+ WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8); -+ WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); -+ -+ rdev->cp.rptr = RREG32(CP_RB_RPTR); -+ rdev->cp.wptr = RREG32(CP_RB_WPTR); -+ -+ r600_cp_start(rdev); -+ rdev->cp.ready = true; -+ r = radeon_ring_test(rdev); -+ if (r) { -+ rdev->cp.ready = false; -+ return r; -+ } -+ return 0; -+} -+ -+void r600_cp_commit(struct radeon_device *rdev) -+{ -+ WREG32(CP_RB_WPTR, rdev->cp.wptr); -+ (void)RREG32(CP_RB_WPTR); -+} -+ -+void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) -+{ -+ u32 rb_bufsz; -+ -+ /* Align ring size */ -+ rb_bufsz = drm_order(ring_size / 8); -+ ring_size = (1 << (rb_bufsz + 1)) * 4; -+ rdev->cp.ring_size = ring_size; -+ rdev->cp.align_mask = 16 - 1; -+} -+ -+ -+/* -+ * GPU scratch registers helpers function. -+ */ -+void r600_scratch_init(struct radeon_device *rdev) -+{ -+ int i; -+ -+ rdev->scratch.num_reg = 7; -+ for (i = 0; i < rdev->scratch.num_reg; i++) { -+ rdev->scratch.free[i] = true; -+ rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4); -+ } -+} -+ -+int r600_ring_test(struct radeon_device *rdev) -+{ -+ uint32_t scratch; -+ uint32_t tmp = 0; -+ unsigned i; -+ int r; -+ -+ r = radeon_scratch_get(rdev, &scratch); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); -+ return r; -+ } -+ WREG32(scratch, 0xCAFEDEAD); -+ r = radeon_ring_lock(rdev, 3); -+ if (r) { -+ DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -+ radeon_scratch_free(rdev, scratch); -+ return r; -+ } -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -+ radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); -+ radeon_ring_write(rdev, 0xDEADBEEF); -+ radeon_ring_unlock_commit(rdev); -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ tmp = RREG32(scratch); -+ if (tmp == 0xDEADBEEF) -+ break; -+ DRM_UDELAY(1); -+ } -+ if (i < rdev->usec_timeout) { -+ DRM_INFO("ring test succeeded in %d usecs\n", i); -+ } else { -+ DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", -+ scratch, tmp); -+ r = -EINVAL; -+ } -+ radeon_scratch_free(rdev, scratch); -+ return r; -+} -+ -+/* -+ * Writeback -+ */ -+int r600_wb_init(struct radeon_device *rdev) -+{ -+ int r; -+ -+ if (rdev->wb.wb_obj == NULL) { -+ r = radeon_object_create(rdev, NULL, 4096, -+ true, -+ RADEON_GEM_DOMAIN_GTT, -+ false, &rdev->wb.wb_obj); -+ if (r) { -+ DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); -+ return r; -+ } -+ r = radeon_object_pin(rdev->wb.wb_obj, -+ RADEON_GEM_DOMAIN_GTT, -+ &rdev->wb.gpu_addr); -+ if (r) { -+ DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); -+ return r; -+ } -+ r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); -+ if (r) { -+ DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); -+ return r; -+ } -+ } -+ WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF); -+ WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC); -+ WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF); -+ WREG32(SCRATCH_UMSK, 0xff); -+ return 0; -+} -+ -+void r600_wb_fini(struct radeon_device *rdev) -+{ -+ if (rdev->wb.wb_obj) { -+ radeon_object_kunmap(rdev->wb.wb_obj); -+ radeon_object_unpin(rdev->wb.wb_obj); -+ radeon_object_unref(&rdev->wb.wb_obj); -+ rdev->wb.wb = NULL; -+ rdev->wb.wb_obj = NULL; -+ } -+} -+ -+ -+/* -+ * CS -+ */ -+void r600_fence_ring_emit(struct radeon_device *rdev, -+ struct radeon_fence *fence) -+{ -+ /* Emit fence sequence & fire IRQ */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -+ radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); -+ radeon_ring_write(rdev, fence->seq); -+} -+ -+int r600_copy_dma(struct radeon_device *rdev, -+ uint64_t src_offset, -+ uint64_t dst_offset, -+ unsigned num_pages, -+ struct radeon_fence *fence) -+{ -+ /* FIXME: implement */ -+ return 0; -+} -+ -+int r600_copy_blit(struct radeon_device *rdev, -+ uint64_t src_offset, uint64_t dst_offset, -+ unsigned num_pages, struct radeon_fence *fence) -+{ -+ r600_blit_prepare_copy(rdev, num_pages * 4096); -+ r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * 4096); -+ r600_blit_done_copy(rdev, fence); -+ return 0; -+} -+ -+int r600_irq_process(struct radeon_device *rdev) -+{ -+ /* FIXME: implement */ -+ return 0; -+} -+ -+int r600_irq_set(struct radeon_device *rdev) -+{ -+ /* FIXME: implement */ -+ return 0; -+} -+ -+int r600_set_surface_reg(struct radeon_device *rdev, int reg, -+ uint32_t tiling_flags, uint32_t pitch, -+ uint32_t offset, uint32_t obj_size) -+{ -+ /* FIXME: implement */ -+ return 0; -+} -+ -+void r600_clear_surface_reg(struct radeon_device *rdev, int reg) -+{ -+ /* FIXME: implement */ -+} -+ -+ -+bool r600_card_posted(struct radeon_device *rdev) -+{ -+ uint32_t reg; -+ -+ /* first check CRTCs */ -+ reg = RREG32(D1CRTC_CONTROL) | -+ RREG32(D2CRTC_CONTROL); -+ if (reg & CRTC_EN) -+ return true; -+ -+ /* then check MEM_SIZE, in case the crtcs are off */ -+ if (RREG32(CONFIG_MEMSIZE)) -+ return true; -+ -+ return false; -+} -+ -+int r600_resume(struct radeon_device *rdev) -+{ -+ int r; -+ -+ r600_gpu_reset(rdev); -+ r600_mc_resume(rdev); -+ r = r600_pcie_gart_enable(rdev); -+ if (r) -+ return r; -+ r600_gpu_init(rdev); -+ r = radeon_ring_init(rdev, rdev->cp.ring_size); -+ if (r) -+ return r; -+ r = r600_cp_load_microcode(rdev); -+ if (r) -+ return r; -+ r = r600_cp_resume(rdev); -+ if (r) -+ return r; -+ r = r600_wb_init(rdev); -+ if (r) -+ return r; -+ return 0; -+} -+ -+int r600_suspend(struct radeon_device *rdev) -+{ -+ /* FIXME: we should wait for ring to be empty */ -+ r600_cp_stop(rdev); -+ return 0; -+} -+ -+/* Plan is to move initialization in that function and use -+ * helper function so that radeon_device_init pretty much -+ * do nothing more than calling asic specific function. This -+ * should also allow to remove a bunch of callback function -+ * like vram_info. -+ */ -+int r600_init(struct radeon_device *rdev) - { -- uint32_t r; -+ int r; - -- WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); -- (void)RREG32(R600_PCIE_PORT_INDEX); -- r = RREG32(R600_PCIE_PORT_DATA); -+ rdev->new_init_path = true; -+ r = radeon_dummy_page_init(rdev); -+ if (r) -+ return r; -+ if (r600_debugfs_mc_info_init(rdev)) { -+ DRM_ERROR("Failed to register debugfs file for mc !\n"); -+ } -+ /* This don't do much */ -+ r = radeon_gem_init(rdev); -+ if (r) -+ return r; -+ /* Read BIOS */ -+ if (!radeon_get_bios(rdev)) { -+ if (ASIC_IS_AVIVO(rdev)) -+ return -EINVAL; -+ } -+ /* Must be an ATOMBIOS */ -+ if (!rdev->is_atom_bios) -+ return -EINVAL; -+ r = radeon_atombios_init(rdev); -+ if (r) -+ return r; -+ /* Post card if necessary */ -+ if (!r600_card_posted(rdev) && rdev->bios) { -+ DRM_INFO("GPU not posted. posting now...\n"); -+ atom_asic_init(rdev->mode_info.atom_context); -+ } -+ /* Initialize scratch registers */ -+ r600_scratch_init(rdev); -+ /* Initialize surface registers */ -+ radeon_surface_init(rdev); -+ r = radeon_clocks_init(rdev); -+ if (r) -+ return r; -+ /* Fence driver */ -+ r = radeon_fence_driver_init(rdev); -+ if (r) -+ return r; -+ r = r600_mc_init(rdev); -+ if (r) { -+ if (rdev->flags & RADEON_IS_AGP) { -+ /* Retry with disabling AGP */ -+ r600_fini(rdev); -+ rdev->flags &= ~RADEON_IS_AGP; -+ return r600_init(rdev); -+ } -+ return r; -+ } -+ /* Memory manager */ -+ r = radeon_object_init(rdev); -+ if (r) -+ return r; -+ rdev->cp.ring_obj = NULL; -+ r600_ring_init(rdev, 1024 * 1024); -+ -+ if (!rdev->me_fw || !rdev->pfp_fw) { -+ r = r600_cp_init_microcode(rdev); -+ if (r) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ return r; -+ } -+ } -+ -+ r = r600_resume(rdev); -+ if (r) { -+ if (rdev->flags & RADEON_IS_AGP) { -+ /* Retry with disabling AGP */ -+ r600_fini(rdev); -+ rdev->flags &= ~RADEON_IS_AGP; -+ return r600_init(rdev); -+ } -+ return r; -+ } -+ r = radeon_ib_pool_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); -+ return r; -+ } -+ r = r600_blit_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled blitter (%d).\n", r); -+ return r; -+ } -+ r = radeon_ib_test(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled testing IB (%d).\n", r); -+ return r; -+ } -+ return 0; -+} -+ -+void r600_fini(struct radeon_device *rdev) -+{ -+ /* Suspend operations */ -+ r600_suspend(rdev); -+ -+ r600_blit_fini(rdev); -+ radeon_ring_fini(rdev); -+ r600_pcie_gart_disable(rdev); -+ radeon_gart_table_vram_free(rdev); -+ radeon_gart_fini(rdev); -+ radeon_gem_fini(rdev); -+ radeon_fence_driver_fini(rdev); -+ radeon_clocks_fini(rdev); -+#if __OS_HAS_AGP -+ if (rdev->flags & RADEON_IS_AGP) -+ radeon_agp_fini(rdev); -+#endif -+ radeon_object_fini(rdev); -+ if (rdev->is_atom_bios) -+ radeon_atombios_fini(rdev); -+ else -+ radeon_combios_fini(rdev); -+ kfree(rdev->bios); -+ rdev->bios = NULL; -+ radeon_dummy_page_fini(rdev); -+} -+ -+ -+/* -+ * CS stuff -+ */ -+void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) -+{ -+ /* FIXME: implement */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); -+ radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC); -+ radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); -+ radeon_ring_write(rdev, ib->length_dw); -+} -+ -+int r600_ib_test(struct radeon_device *rdev) -+{ -+ struct radeon_ib *ib; -+ uint32_t scratch; -+ uint32_t tmp = 0; -+ unsigned i; -+ int r; -+ -+ r = radeon_scratch_get(rdev, &scratch); -+ if (r) { -+ DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); -+ return r; -+ } -+ WREG32(scratch, 0xCAFEDEAD); -+ r = radeon_ib_get(rdev, &ib); -+ if (r) { -+ DRM_ERROR("radeon: failed to get ib (%d).\n", r); -+ return r; -+ } -+ ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); -+ ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); -+ ib->ptr[2] = 0xDEADBEEF; -+ ib->ptr[3] = PACKET2(0); -+ ib->ptr[4] = PACKET2(0); -+ ib->ptr[5] = PACKET2(0); -+ ib->ptr[6] = PACKET2(0); -+ ib->ptr[7] = PACKET2(0); -+ ib->ptr[8] = PACKET2(0); -+ ib->ptr[9] = PACKET2(0); -+ ib->ptr[10] = PACKET2(0); -+ ib->ptr[11] = PACKET2(0); -+ ib->ptr[12] = PACKET2(0); -+ ib->ptr[13] = PACKET2(0); -+ ib->ptr[14] = PACKET2(0); -+ ib->ptr[15] = PACKET2(0); -+ ib->length_dw = 16; -+ r = radeon_ib_schedule(rdev, ib); -+ if (r) { -+ radeon_scratch_free(rdev, scratch); -+ radeon_ib_free(rdev, &ib); -+ DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); -+ return r; -+ } -+ r = radeon_fence_wait(ib->fence, false); -+ if (r) { -+ DRM_ERROR("radeon: fence wait failed (%d).\n", r); -+ return r; -+ } -+ for (i = 0; i < rdev->usec_timeout; i++) { -+ tmp = RREG32(scratch); -+ if (tmp == 0xDEADBEEF) -+ break; -+ DRM_UDELAY(1); -+ } -+ if (i < rdev->usec_timeout) { -+ DRM_INFO("ib test succeeded in %u usecs\n", i); -+ } else { -+ DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", -+ scratch, tmp); -+ r = -EINVAL; -+ } -+ radeon_scratch_free(rdev, scratch); -+ radeon_ib_free(rdev, &ib); - return r; - } - --void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) -+ -+ -+ -+/* -+ * Debugfs info -+ */ -+#if defined(CONFIG_DEBUG_FS) -+ -+static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) - { -- WREG32(R600_PCIE_PORT_INDEX, ((reg) & 0xff)); -- (void)RREG32(R600_PCIE_PORT_INDEX); -- WREG32(R600_PCIE_PORT_DATA, (v)); -- (void)RREG32(R600_PCIE_PORT_DATA); -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t rdp, wdp; -+ unsigned count, i, j; -+ -+ radeon_ring_free_size(rdev); -+ rdp = RREG32(CP_RB_RPTR); -+ wdp = RREG32(CP_RB_WPTR); -+ count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; -+ seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); -+ seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); -+ seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); -+ seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); -+ seq_printf(m, "%u dwords in ring\n", count); -+ for (j = 0; j <= count; j++) { -+ i = (rdp + j) & rdev->cp.ptr_mask; -+ seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); -+ } -+ return 0; -+} -+ -+static int r600_debugfs_mc_info(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *) m->private; -+ struct drm_device *dev = node->minor->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ -+ DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS); -+ DREG32_SYS(m, rdev, VM_L2_STATUS); -+ return 0; -+} -+ -+static struct drm_info_list r600_mc_info_list[] = { -+ {"r600_mc_info", r600_debugfs_mc_info, 0, NULL}, -+ {"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL}, -+}; -+#endif -+ -+int r600_debugfs_mc_info_init(struct radeon_device *rdev) -+{ -+#if defined(CONFIG_DEBUG_FS) -+ return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list)); -+#else -+ return 0; -+#endif - } -diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c -new file mode 100644 -index 0000000..c51402e ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600_blit.c -@@ -0,0 +1,855 @@ -+/* -+ * Copyright 2009 Advanced Micro Devices, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: -+ * Alex Deucher -+ */ -+#include "drmP.h" -+#include "drm.h" -+#include "radeon_drm.h" -+#include "radeon_drv.h" -+ -+#include "r600_blit_shaders.h" -+ -+#define DI_PT_RECTLIST 0x11 -+#define DI_INDEX_SIZE_16_BIT 0x0 -+#define DI_SRC_SEL_AUTO_INDEX 0x2 -+ -+#define FMT_8 0x1 -+#define FMT_5_6_5 0x8 -+#define FMT_8_8_8_8 0x1a -+#define COLOR_8 0x1 -+#define COLOR_5_6_5 0x8 -+#define COLOR_8_8_8_8 0x1a -+ -+static inline void -+set_render_target(drm_radeon_private_t *dev_priv, int format, int w, int h, u64 gpu_addr) -+{ -+ u32 cb_color_info; -+ int pitch, slice; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ h = (h + 7) & ~7; -+ if (h < 8) -+ h = 8; -+ -+ cb_color_info = ((format << 2) | (1 << 27)); -+ pitch = (w / 8) - 1; -+ slice = ((w * h) / 64) - 1; -+ -+ if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600) && -+ ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) { -+ BEGIN_RING(21 + 2); -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(gpu_addr >> 8); -+ OUT_RING(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0)); -+ OUT_RING(2 << 0); -+ } else { -+ BEGIN_RING(21); -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_BASE - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(gpu_addr >> 8); -+ } -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_SIZE - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING((pitch << 0) | (slice << 10)); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_VIEW - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_INFO - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(cb_color_info); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_TILE - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_FRAG - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_CB_COLOR0_MASK - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ -+ ADVANCE_RING(); -+} -+ -+static inline void -+cp_set_surface_sync(drm_radeon_private_t *dev_priv, -+ u32 sync_type, u32 size, u64 mc_addr) -+{ -+ u32 cp_coher_size; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ if (size == 0xffffffff) -+ cp_coher_size = 0xffffffff; -+ else -+ cp_coher_size = ((size + 255) >> 8); -+ -+ BEGIN_RING(5); -+ OUT_RING(CP_PACKET3(R600_IT_SURFACE_SYNC, 3)); -+ OUT_RING(sync_type); -+ OUT_RING(cp_coher_size); -+ OUT_RING((mc_addr >> 8)); -+ OUT_RING(10); /* poll interval */ -+ ADVANCE_RING(); -+} -+ -+static inline void -+set_shaders(struct drm_device *dev) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ u64 gpu_addr; -+ int shader_size, i; -+ u32 *vs, *ps; -+ uint32_t sq_pgm_resources; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ /* load shaders */ -+ vs = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset); -+ ps = (u32 *) ((char *)dev->agp_buffer_map->handle + dev_priv->blit_vb->offset + 256); -+ -+ shader_size = r6xx_vs_size; -+ for (i = 0; i < shader_size; i++) -+ vs[i] = r6xx_vs[i]; -+ shader_size = r6xx_ps_size; -+ for (i = 0; i < shader_size; i++) -+ ps[i] = r6xx_ps[i]; -+ -+ dev_priv->blit_vb->used = 512; -+ -+ gpu_addr = dev_priv->gart_buffers_offset + dev_priv->blit_vb->offset; -+ -+ /* setup shader regs */ -+ sq_pgm_resources = (1 << 0); -+ -+ BEGIN_RING(9 + 12); -+ /* VS */ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_START_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(gpu_addr >> 8); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_RESOURCES_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(sq_pgm_resources); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_CF_OFFSET_VS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ -+ /* PS */ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_START_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING((gpu_addr + 256) >> 8); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_RESOURCES_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(sq_pgm_resources | (1 << 28)); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_EXPORTS_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(2); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 1)); -+ OUT_RING((R600_SQ_PGM_CF_OFFSET_PS - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING(0); -+ ADVANCE_RING(); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_SH_ACTION_ENA, 512, gpu_addr); -+} -+ -+static inline void -+set_vtx_resource(drm_radeon_private_t *dev_priv, u64 gpu_addr) -+{ -+ uint32_t sq_vtx_constant_word2; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ sq_vtx_constant_word2 = (((gpu_addr >> 32) & 0xff) | (16 << 8)); -+ -+ BEGIN_RING(9); -+ OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); -+ OUT_RING(0x460); -+ OUT_RING(gpu_addr & 0xffffffff); -+ OUT_RING(48 - 1); -+ OUT_RING(sq_vtx_constant_word2); -+ OUT_RING(1 << 0); -+ OUT_RING(0); -+ OUT_RING(0); -+ OUT_RING(R600_SQ_TEX_VTX_VALID_BUFFER << 30); -+ ADVANCE_RING(); -+ -+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) -+ cp_set_surface_sync(dev_priv, -+ R600_TC_ACTION_ENA, 48, gpu_addr); -+ else -+ cp_set_surface_sync(dev_priv, -+ R600_VC_ACTION_ENA, 48, gpu_addr); -+} -+ -+static inline void -+set_tex_resource(drm_radeon_private_t *dev_priv, -+ int format, int w, int h, int pitch, u64 gpu_addr) -+{ -+ uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ if (h < 1) -+ h = 1; -+ -+ sq_tex_resource_word0 = (1 << 0); -+ sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | -+ ((w - 1) << 19)); -+ -+ sq_tex_resource_word1 = (format << 26); -+ sq_tex_resource_word1 |= ((h - 1) << 0); -+ -+ sq_tex_resource_word4 = ((1 << 14) | -+ (0 << 16) | -+ (1 << 19) | -+ (2 << 22) | -+ (3 << 25)); -+ -+ BEGIN_RING(9); -+ OUT_RING(CP_PACKET3(R600_IT_SET_RESOURCE, 7)); -+ OUT_RING(0); -+ OUT_RING(sq_tex_resource_word0); -+ OUT_RING(sq_tex_resource_word1); -+ OUT_RING(gpu_addr >> 8); -+ OUT_RING(gpu_addr >> 8); -+ OUT_RING(sq_tex_resource_word4); -+ OUT_RING(0); -+ OUT_RING(R600_SQ_TEX_VTX_VALID_TEXTURE << 30); -+ ADVANCE_RING(); -+ -+} -+ -+static inline void -+set_scissors(drm_radeon_private_t *dev_priv, int x1, int y1, int x2, int y2) -+{ -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ BEGIN_RING(12); -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); -+ OUT_RING((R600_PA_SC_SCREEN_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING((x1 << 0) | (y1 << 16)); -+ OUT_RING((x2 << 0) | (y2 << 16)); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); -+ OUT_RING((R600_PA_SC_GENERIC_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); -+ OUT_RING((x2 << 0) | (y2 << 16)); -+ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONTEXT_REG, 2)); -+ OUT_RING((R600_PA_SC_WINDOW_SCISSOR_TL - R600_SET_CONTEXT_REG_OFFSET) >> 2); -+ OUT_RING((x1 << 0) | (y1 << 16) | (1 << 31)); -+ OUT_RING((x2 << 0) | (y2 << 16)); -+ ADVANCE_RING(); -+} -+ -+static inline void -+draw_auto(drm_radeon_private_t *dev_priv) -+{ -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ BEGIN_RING(10); -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); -+ OUT_RING((R600_VGT_PRIMITIVE_TYPE - R600_SET_CONFIG_REG_OFFSET) >> 2); -+ OUT_RING(DI_PT_RECTLIST); -+ -+ OUT_RING(CP_PACKET3(R600_IT_INDEX_TYPE, 0)); -+ OUT_RING(DI_INDEX_SIZE_16_BIT); -+ -+ OUT_RING(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); -+ OUT_RING(1); -+ -+ OUT_RING(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1)); -+ OUT_RING(3); -+ OUT_RING(DI_SRC_SEL_AUTO_INDEX); -+ -+ ADVANCE_RING(); -+ COMMIT_RING(); -+} -+ -+static inline void -+set_default_state(drm_radeon_private_t *dev_priv) -+{ -+ int default_state_dw, i; -+ u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; -+ u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; -+ int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; -+ int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; -+ int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; -+ RING_LOCALS; -+ -+ switch ((dev_priv->flags & RADEON_FAMILY_MASK)) { -+ case CHIP_R600: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV630: -+ case CHIP_RV635: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 144; -+ num_vs_threads = 40; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV610: -+ case CHIP_RV620: -+ case CHIP_RS780: -+ case CHIP_RS880: -+ default: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV670: -+ num_ps_gprs = 144; -+ num_vs_gprs = 40; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV770: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 188; -+ num_vs_threads = 60; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 256; -+ num_vs_stack_entries = 256; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV730: -+ case CHIP_RV740: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 188; -+ num_vs_threads = 60; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV710: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 144; -+ num_vs_threads = 48; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ } -+ -+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880) || -+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) -+ sq_config = 0; -+ else -+ sq_config = R600_VC_ENABLE; -+ -+ sq_config |= (R600_DX9_CONSTS | -+ R600_ALU_INST_PREFER_VECTOR | -+ R600_PS_PRIO(0) | -+ R600_VS_PRIO(1) | -+ R600_GS_PRIO(2) | -+ R600_ES_PRIO(3)); -+ -+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(num_ps_gprs) | -+ R600_NUM_VS_GPRS(num_vs_gprs) | -+ R600_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); -+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(num_gs_gprs) | -+ R600_NUM_ES_GPRS(num_es_gprs)); -+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(num_ps_threads) | -+ R600_NUM_VS_THREADS(num_vs_threads) | -+ R600_NUM_GS_THREADS(num_gs_threads) | -+ R600_NUM_ES_THREADS(num_es_threads)); -+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | -+ R600_NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); -+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | -+ R600_NUM_ES_STACK_ENTRIES(num_es_stack_entries)); -+ -+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { -+ default_state_dw = r7xx_default_size * 4; -+ BEGIN_RING(default_state_dw + 10); -+ for (i = 0; i < default_state_dw; i++) -+ OUT_RING(r7xx_default_state[i]); -+ } else { -+ default_state_dw = r6xx_default_size * 4; -+ BEGIN_RING(default_state_dw + 10); -+ for (i = 0; i < default_state_dw; i++) -+ OUT_RING(r6xx_default_state[i]); -+ } -+ OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); -+ OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); -+ /* SQ config */ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 6)); -+ OUT_RING((R600_SQ_CONFIG - R600_SET_CONFIG_REG_OFFSET) >> 2); -+ OUT_RING(sq_config); -+ OUT_RING(sq_gpr_resource_mgmt_1); -+ OUT_RING(sq_gpr_resource_mgmt_2); -+ OUT_RING(sq_thread_resource_mgmt); -+ OUT_RING(sq_stack_resource_mgmt_1); -+ OUT_RING(sq_stack_resource_mgmt_2); -+ ADVANCE_RING(); -+} -+ -+static inline uint32_t i2f(uint32_t input) -+{ -+ u32 result, i, exponent, fraction; -+ -+ if ((input & 0x3fff) == 0) -+ result = 0; /* 0 is a special case */ -+ else { -+ exponent = 140; /* exponent biased by 127; */ -+ fraction = (input & 0x3fff) << 10; /* cheat and only -+ handle numbers below 2^^15 */ -+ for (i = 0; i < 14; i++) { -+ if (fraction & 0x800000) -+ break; -+ else { -+ fraction = fraction << 1; /* keep -+ shifting left until top bit = 1 */ -+ exponent = exponent - 1; -+ } -+ } -+ result = exponent << 23 | (fraction & 0x7fffff); /* mask -+ off top bit; assumed 1 */ -+ } -+ return result; -+} -+ -+ -+int r600_nomm_get_vb(struct drm_device *dev) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ dev_priv->blit_vb = radeon_freelist_get(dev); -+ if (!dev_priv->blit_vb) { -+ DRM_ERROR("Unable to allocate vertex buffer for blit\n"); -+ return -EAGAIN; -+ } -+ return 0; -+} -+ -+void r600_nomm_put_vb(struct drm_device *dev) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ -+ dev_priv->blit_vb->used = 0; -+ radeon_cp_discard_buffer(dev, dev_priv->blit_vb->file_priv->master, dev_priv->blit_vb); -+} -+ -+void *r600_nomm_get_vb_ptr(struct drm_device *dev) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ return (((char *)dev->agp_buffer_map->handle + -+ dev_priv->blit_vb->offset + dev_priv->blit_vb->used)); -+} -+ -+int -+r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ DRM_DEBUG("\n"); -+ -+ r600_nomm_get_vb(dev); -+ -+ dev_priv->blit_vb->file_priv = file_priv; -+ -+ set_default_state(dev_priv); -+ set_shaders(dev); -+ -+ return 0; -+} -+ -+ -+void -+r600_done_blit_copy(struct drm_device *dev) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ BEGIN_RING(5); -+ OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); -+ OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); -+ /* wait for 3D idle clean */ -+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); -+ OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); -+ OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); -+ -+ ADVANCE_RING(); -+ COMMIT_RING(); -+ -+ r600_nomm_put_vb(dev); -+} -+ -+void -+r600_blit_copy(struct drm_device *dev, -+ uint64_t src_gpu_addr, uint64_t dst_gpu_addr, -+ int size_bytes) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ int max_bytes; -+ u64 vb_addr; -+ u32 *vb; -+ -+ vb = r600_nomm_get_vb_ptr(dev); -+ -+ if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { -+ max_bytes = 8192; -+ -+ while (size_bytes) { -+ int cur_size = size_bytes; -+ int src_x = src_gpu_addr & 255; -+ int dst_x = dst_gpu_addr & 255; -+ int h = 1; -+ src_gpu_addr = src_gpu_addr & ~255; -+ dst_gpu_addr = dst_gpu_addr & ~255; -+ -+ if (!src_x && !dst_x) { -+ h = (cur_size / max_bytes); -+ if (h > 8192) -+ h = 8192; -+ if (h == 0) -+ h = 1; -+ else -+ cur_size = max_bytes; -+ } else { -+ if (cur_size > max_bytes) -+ cur_size = max_bytes; -+ if (cur_size > (max_bytes - dst_x)) -+ cur_size = (max_bytes - dst_x); -+ if (cur_size > (max_bytes - src_x)) -+ cur_size = (max_bytes - src_x); -+ } -+ -+ if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { -+ -+ r600_nomm_put_vb(dev); -+ r600_nomm_get_vb(dev); -+ if (!dev_priv->blit_vb) -+ return; -+ set_shaders(dev); -+ vb = r600_nomm_get_vb_ptr(dev); -+ } -+ -+ vb[0] = i2f(dst_x); -+ vb[1] = 0; -+ vb[2] = i2f(src_x); -+ vb[3] = 0; -+ -+ vb[4] = i2f(dst_x); -+ vb[5] = i2f(h); -+ vb[6] = i2f(src_x); -+ vb[7] = i2f(h); -+ -+ vb[8] = i2f(dst_x + cur_size); -+ vb[9] = i2f(h); -+ vb[10] = i2f(src_x + cur_size); -+ vb[11] = i2f(h); -+ -+ /* src */ -+ set_tex_resource(dev_priv, FMT_8, -+ src_x + cur_size, h, src_x + cur_size, -+ src_gpu_addr); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); -+ -+ /* dst */ -+ set_render_target(dev_priv, COLOR_8, -+ dst_x + cur_size, h, -+ dst_gpu_addr); -+ -+ /* scissors */ -+ set_scissors(dev_priv, dst_x, 0, dst_x + cur_size, h); -+ -+ /* Vertex buffer setup */ -+ vb_addr = dev_priv->gart_buffers_offset + -+ dev_priv->blit_vb->offset + -+ dev_priv->blit_vb->used; -+ set_vtx_resource(dev_priv, vb_addr); -+ -+ /* draw */ -+ draw_auto(dev_priv); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, -+ cur_size * h, dst_gpu_addr); -+ -+ vb += 12; -+ dev_priv->blit_vb->used += 12 * 4; -+ -+ src_gpu_addr += cur_size * h; -+ dst_gpu_addr += cur_size * h; -+ size_bytes -= cur_size * h; -+ } -+ } else { -+ max_bytes = 8192 * 4; -+ -+ while (size_bytes) { -+ int cur_size = size_bytes; -+ int src_x = (src_gpu_addr & 255); -+ int dst_x = (dst_gpu_addr & 255); -+ int h = 1; -+ src_gpu_addr = src_gpu_addr & ~255; -+ dst_gpu_addr = dst_gpu_addr & ~255; -+ -+ if (!src_x && !dst_x) { -+ h = (cur_size / max_bytes); -+ if (h > 8192) -+ h = 8192; -+ if (h == 0) -+ h = 1; -+ else -+ cur_size = max_bytes; -+ } else { -+ if (cur_size > max_bytes) -+ cur_size = max_bytes; -+ if (cur_size > (max_bytes - dst_x)) -+ cur_size = (max_bytes - dst_x); -+ if (cur_size > (max_bytes - src_x)) -+ cur_size = (max_bytes - src_x); -+ } -+ -+ if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { -+ r600_nomm_put_vb(dev); -+ r600_nomm_get_vb(dev); -+ if (!dev_priv->blit_vb) -+ return; -+ -+ set_shaders(dev); -+ vb = r600_nomm_get_vb_ptr(dev); -+ } -+ -+ vb[0] = i2f(dst_x / 4); -+ vb[1] = 0; -+ vb[2] = i2f(src_x / 4); -+ vb[3] = 0; -+ -+ vb[4] = i2f(dst_x / 4); -+ vb[5] = i2f(h); -+ vb[6] = i2f(src_x / 4); -+ vb[7] = i2f(h); -+ -+ vb[8] = i2f((dst_x + cur_size) / 4); -+ vb[9] = i2f(h); -+ vb[10] = i2f((src_x + cur_size) / 4); -+ vb[11] = i2f(h); -+ -+ /* src */ -+ set_tex_resource(dev_priv, FMT_8_8_8_8, -+ (src_x + cur_size) / 4, -+ h, (src_x + cur_size) / 4, -+ src_gpu_addr); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); -+ -+ /* dst */ -+ set_render_target(dev_priv, COLOR_8_8_8_8, -+ dst_x + cur_size, h, -+ dst_gpu_addr); -+ -+ /* scissors */ -+ set_scissors(dev_priv, (dst_x / 4), 0, (dst_x + cur_size / 4), h); -+ -+ /* Vertex buffer setup */ -+ vb_addr = dev_priv->gart_buffers_offset + -+ dev_priv->blit_vb->offset + -+ dev_priv->blit_vb->used; -+ set_vtx_resource(dev_priv, vb_addr); -+ -+ /* draw */ -+ draw_auto(dev_priv); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, -+ cur_size * h, dst_gpu_addr); -+ -+ vb += 12; -+ dev_priv->blit_vb->used += 12 * 4; -+ -+ src_gpu_addr += cur_size * h; -+ dst_gpu_addr += cur_size * h; -+ size_bytes -= cur_size * h; -+ } -+ } -+} -+ -+void -+r600_blit_swap(struct drm_device *dev, -+ uint64_t src_gpu_addr, uint64_t dst_gpu_addr, -+ int sx, int sy, int dx, int dy, -+ int w, int h, int src_pitch, int dst_pitch, int cpp) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ int cb_format, tex_format; -+ u64 vb_addr; -+ u32 *vb; -+ -+ vb = (u32 *) ((char *)dev->agp_buffer_map->handle + -+ dev_priv->blit_vb->offset + dev_priv->blit_vb->used); -+ -+ if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { -+ -+ r600_nomm_put_vb(dev); -+ r600_nomm_get_vb(dev); -+ if (!dev_priv->blit_vb) -+ return; -+ -+ set_shaders(dev); -+ vb = r600_nomm_get_vb_ptr(dev); -+ } -+ -+ if (cpp == 4) { -+ cb_format = COLOR_8_8_8_8; -+ tex_format = FMT_8_8_8_8; -+ } else if (cpp == 2) { -+ cb_format = COLOR_5_6_5; -+ tex_format = FMT_5_6_5; -+ } else { -+ cb_format = COLOR_8; -+ tex_format = FMT_8; -+ } -+ -+ vb[0] = i2f(dx); -+ vb[1] = i2f(dy); -+ vb[2] = i2f(sx); -+ vb[3] = i2f(sy); -+ -+ vb[4] = i2f(dx); -+ vb[5] = i2f(dy + h); -+ vb[6] = i2f(sx); -+ vb[7] = i2f(sy + h); -+ -+ vb[8] = i2f(dx + w); -+ vb[9] = i2f(dy + h); -+ vb[10] = i2f(sx + w); -+ vb[11] = i2f(sy + h); -+ -+ /* src */ -+ set_tex_resource(dev_priv, tex_format, -+ src_pitch / cpp, -+ sy + h, src_pitch / cpp, -+ src_gpu_addr); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_TC_ACTION_ENA, (src_pitch * (sy + h)), src_gpu_addr); -+ -+ /* dst */ -+ set_render_target(dev_priv, cb_format, -+ dst_pitch / cpp, dy + h, -+ dst_gpu_addr); -+ -+ /* scissors */ -+ set_scissors(dev_priv, dx, dy, dx + w, dy + h); -+ -+ /* Vertex buffer setup */ -+ vb_addr = dev_priv->gart_buffers_offset + -+ dev_priv->blit_vb->offset + -+ dev_priv->blit_vb->used; -+ set_vtx_resource(dev_priv, vb_addr); -+ -+ /* draw */ -+ draw_auto(dev_priv); -+ -+ cp_set_surface_sync(dev_priv, -+ R600_CB_ACTION_ENA | R600_CB0_DEST_BASE_ENA, -+ dst_pitch * (dy + h), dst_gpu_addr); -+ -+ dev_priv->blit_vb->used += 12 * 4; -+} -diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c -new file mode 100644 -index 0000000..5755647 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c -@@ -0,0 +1,777 @@ -+#include "drmP.h" -+#include "drm.h" -+#include "radeon_drm.h" -+#include "radeon.h" -+ -+#include "r600d.h" -+#include "r600_blit_shaders.h" -+ -+#define DI_PT_RECTLIST 0x11 -+#define DI_INDEX_SIZE_16_BIT 0x0 -+#define DI_SRC_SEL_AUTO_INDEX 0x2 -+ -+#define FMT_8 0x1 -+#define FMT_5_6_5 0x8 -+#define FMT_8_8_8_8 0x1a -+#define COLOR_8 0x1 -+#define COLOR_5_6_5 0x8 -+#define COLOR_8_8_8_8 0x1a -+ -+/* emits 21 on rv770+, 23 on r600 */ -+static void -+set_render_target(struct radeon_device *rdev, int format, -+ int w, int h, u64 gpu_addr) -+{ -+ u32 cb_color_info; -+ int pitch, slice; -+ -+ h = (h + 7) & ~7; -+ if (h < 8) -+ h = 8; -+ -+ cb_color_info = ((format << 2) | (1 << 27)); -+ pitch = (w / 8) - 1; -+ slice = ((w * h) / 64) - 1; -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, gpu_addr >> 8); -+ -+ if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) { -+ radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); -+ radeon_ring_write(rdev, 2 << 0); -+ } -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, (pitch << 0) | (slice << 10)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, cb_color_info); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+} -+ -+/* emits 5dw */ -+static void -+cp_set_surface_sync(struct radeon_device *rdev, -+ u32 sync_type, u32 size, -+ u64 mc_addr) -+{ -+ u32 cp_coher_size; -+ -+ if (size == 0xffffffff) -+ cp_coher_size = 0xffffffff; -+ else -+ cp_coher_size = ((size + 255) >> 8); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); -+ radeon_ring_write(rdev, sync_type); -+ radeon_ring_write(rdev, cp_coher_size); -+ radeon_ring_write(rdev, mc_addr >> 8); -+ radeon_ring_write(rdev, 10); /* poll interval */ -+} -+ -+/* emits 21dw + 1 surface sync = 26dw */ -+static void -+set_shaders(struct radeon_device *rdev) -+{ -+ u64 gpu_addr; -+ u32 sq_pgm_resources; -+ -+ /* setup shader regs */ -+ sq_pgm_resources = (1 << 0); -+ -+ /* VS */ -+ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, gpu_addr >> 8); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, sq_pgm_resources); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ /* PS */ -+ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, gpu_addr >> 8); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, sq_pgm_resources | (1 << 28)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 2); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); -+ radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, 0); -+ -+ cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); -+} -+ -+/* emits 9 + 1 sync (5) = 14*/ -+static void -+set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) -+{ -+ u32 sq_vtx_constant_word2; -+ -+ sq_vtx_constant_word2 = ((upper_32_bits(gpu_addr) & 0xff) | (16 << 8)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); -+ radeon_ring_write(rdev, 0x460); -+ radeon_ring_write(rdev, gpu_addr & 0xffffffff); -+ radeon_ring_write(rdev, 48 - 1); -+ radeon_ring_write(rdev, sq_vtx_constant_word2); -+ radeon_ring_write(rdev, 1 << 0); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); -+ -+ if ((rdev->family == CHIP_RV610) || -+ (rdev->family == CHIP_RV620) || -+ (rdev->family == CHIP_RS780) || -+ (rdev->family == CHIP_RS880) || -+ (rdev->family == CHIP_RV710)) -+ cp_set_surface_sync(rdev, -+ PACKET3_TC_ACTION_ENA, 48, gpu_addr); -+ else -+ cp_set_surface_sync(rdev, -+ PACKET3_VC_ACTION_ENA, 48, gpu_addr); -+} -+ -+/* emits 9 */ -+static void -+set_tex_resource(struct radeon_device *rdev, -+ int format, int w, int h, int pitch, -+ u64 gpu_addr) -+{ -+ uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; -+ -+ if (h < 1) -+ h = 1; -+ -+ sq_tex_resource_word0 = (1 << 0); -+ sq_tex_resource_word0 |= ((((pitch >> 3) - 1) << 8) | -+ ((w - 1) << 19)); -+ -+ sq_tex_resource_word1 = (format << 26); -+ sq_tex_resource_word1 |= ((h - 1) << 0); -+ -+ sq_tex_resource_word4 = ((1 << 14) | -+ (0 << 16) | -+ (1 << 19) | -+ (2 << 22) | -+ (3 << 25)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, sq_tex_resource_word0); -+ radeon_ring_write(rdev, sq_tex_resource_word1); -+ radeon_ring_write(rdev, gpu_addr >> 8); -+ radeon_ring_write(rdev, gpu_addr >> 8); -+ radeon_ring_write(rdev, sq_tex_resource_word4); -+ radeon_ring_write(rdev, 0); -+ radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30); -+} -+ -+/* emits 12 */ -+static void -+set_scissors(struct radeon_device *rdev, int x1, int y1, -+ int x2, int y2) -+{ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); -+ radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); -+ radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); -+ radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); -+ radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); -+ radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); -+ radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); -+} -+ -+/* emits 10 */ -+static void -+draw_auto(struct radeon_device *rdev) -+{ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -+ radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, DI_PT_RECTLIST); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); -+ radeon_ring_write(rdev, DI_INDEX_SIZE_16_BIT); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); -+ radeon_ring_write(rdev, 1); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); -+ radeon_ring_write(rdev, 3); -+ radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX); -+ -+} -+ -+/* emits 14 */ -+static void -+set_default_state(struct radeon_device *rdev) -+{ -+ u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; -+ u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; -+ int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; -+ int num_ps_threads, num_vs_threads, num_gs_threads, num_es_threads; -+ int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; -+ u64 gpu_addr; -+ -+ switch (rdev->family) { -+ case CHIP_R600: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV630: -+ case CHIP_RV635: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 144; -+ num_vs_threads = 40; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV610: -+ case CHIP_RV620: -+ case CHIP_RS780: -+ case CHIP_RS880: -+ default: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV670: -+ num_ps_gprs = 144; -+ num_vs_gprs = 40; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 136; -+ num_vs_threads = 48; -+ num_gs_threads = 4; -+ num_es_threads = 4; -+ num_ps_stack_entries = 40; -+ num_vs_stack_entries = 40; -+ num_gs_stack_entries = 32; -+ num_es_stack_entries = 16; -+ break; -+ case CHIP_RV770: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 188; -+ num_vs_threads = 60; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 256; -+ num_vs_stack_entries = 256; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV730: -+ case CHIP_RV740: -+ num_ps_gprs = 84; -+ num_vs_gprs = 36; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 188; -+ num_vs_threads = 60; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ case CHIP_RV710: -+ num_ps_gprs = 192; -+ num_vs_gprs = 56; -+ num_temp_gprs = 4; -+ num_gs_gprs = 0; -+ num_es_gprs = 0; -+ num_ps_threads = 144; -+ num_vs_threads = 48; -+ num_gs_threads = 0; -+ num_es_threads = 0; -+ num_ps_stack_entries = 128; -+ num_vs_stack_entries = 128; -+ num_gs_stack_entries = 0; -+ num_es_stack_entries = 0; -+ break; -+ } -+ -+ if ((rdev->family == CHIP_RV610) || -+ (rdev->family == CHIP_RV620) || -+ (rdev->family == CHIP_RS780) || -+ (rdev->family == CHIP_RS780) || -+ (rdev->family == CHIP_RV710)) -+ sq_config = 0; -+ else -+ sq_config = VC_ENABLE; -+ -+ sq_config |= (DX9_CONSTS | -+ ALU_INST_PREFER_VECTOR | -+ PS_PRIO(0) | -+ VS_PRIO(1) | -+ GS_PRIO(2) | -+ ES_PRIO(3)); -+ -+ sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) | -+ NUM_VS_GPRS(num_vs_gprs) | -+ NUM_CLAUSE_TEMP_GPRS(num_temp_gprs)); -+ sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) | -+ NUM_ES_GPRS(num_es_gprs)); -+ sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) | -+ NUM_VS_THREADS(num_vs_threads) | -+ NUM_GS_THREADS(num_gs_threads) | -+ NUM_ES_THREADS(num_es_threads)); -+ sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) | -+ NUM_VS_STACK_ENTRIES(num_vs_stack_entries)); -+ sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) | -+ NUM_ES_STACK_ENTRIES(num_es_stack_entries)); -+ -+ /* emit an IB pointing at default state */ -+ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; -+ radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); -+ radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); -+ radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); -+ radeon_ring_write(rdev, (rdev->r600_blit.state_len / 4)); -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); -+ radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); -+ /* SQ config */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6)); -+ radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, sq_config); -+ radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); -+ radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); -+ radeon_ring_write(rdev, sq_thread_resource_mgmt); -+ radeon_ring_write(rdev, sq_stack_resource_mgmt_1); -+ radeon_ring_write(rdev, sq_stack_resource_mgmt_2); -+} -+ -+static inline uint32_t i2f(uint32_t input) -+{ -+ u32 result, i, exponent, fraction; -+ -+ if ((input & 0x3fff) == 0) -+ result = 0; /* 0 is a special case */ -+ else { -+ exponent = 140; /* exponent biased by 127; */ -+ fraction = (input & 0x3fff) << 10; /* cheat and only -+ handle numbers below 2^^15 */ -+ for (i = 0; i < 14; i++) { -+ if (fraction & 0x800000) -+ break; -+ else { -+ fraction = fraction << 1; /* keep -+ shifting left until top bit = 1 */ -+ exponent = exponent - 1; -+ } -+ } -+ result = exponent << 23 | (fraction & 0x7fffff); /* mask -+ off top bit; assumed 1 */ -+ } -+ return result; -+} -+ -+int r600_blit_init(struct radeon_device *rdev) -+{ -+ u32 obj_size; -+ int r; -+ void *ptr; -+ -+ rdev->r600_blit.state_offset = 0; -+ -+ if (rdev->family >= CHIP_RV770) -+ rdev->r600_blit.state_len = r7xx_default_size * 4; -+ else -+ rdev->r600_blit.state_len = r6xx_default_size * 4; -+ -+ obj_size = rdev->r600_blit.state_len; -+ obj_size = ALIGN(obj_size, 256); -+ -+ rdev->r600_blit.vs_offset = obj_size; -+ obj_size += r6xx_vs_size * 4; -+ obj_size = ALIGN(obj_size, 256); -+ -+ rdev->r600_blit.ps_offset = obj_size; -+ obj_size += r6xx_ps_size * 4; -+ obj_size = ALIGN(obj_size, 256); -+ -+ r = radeon_object_create(rdev, NULL, obj_size, -+ true, RADEON_GEM_DOMAIN_VRAM, -+ false, &rdev->r600_blit.shader_obj); -+ if (r) { -+ DRM_ERROR("r600 failed to allocate shader\n"); -+ return r; -+ } -+ -+ r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, -+ &rdev->r600_blit.shader_gpu_addr); -+ if (r) { -+ DRM_ERROR("failed to pin blit object %d\n", r); -+ return r; -+ } -+ -+ DRM_DEBUG("r6xx blit allocated bo @ 0x%16llx %08x vs %08x ps %08x\n", -+ rdev->r600_blit.shader_gpu_addr, obj_size, -+ rdev->r600_blit.vs_offset, rdev->r600_blit.ps_offset); -+ -+ r = radeon_object_kmap(rdev->r600_blit.shader_obj, &ptr); -+ if (r) { -+ DRM_ERROR("failed to map blit object %d\n", r); -+ return r; -+ } -+ -+ if (rdev->family >= CHIP_RV770) -+ memcpy_toio(ptr + rdev->r600_blit.state_offset, r7xx_default_state, rdev->r600_blit.state_len); -+ else -+ memcpy_toio(ptr + rdev->r600_blit.state_offset, r6xx_default_state, rdev->r600_blit.state_len); -+ -+ memcpy(ptr + rdev->r600_blit.vs_offset, r6xx_vs, r6xx_vs_size * 4); -+ memcpy(ptr + rdev->r600_blit.ps_offset, r6xx_ps, r6xx_ps_size * 4); -+ -+ radeon_object_kunmap(rdev->r600_blit.shader_obj); -+ return 0; -+} -+ -+void r600_blit_fini(struct radeon_device *rdev) -+{ -+ radeon_object_unpin(rdev->r600_blit.shader_obj); -+ radeon_object_unref(&rdev->r600_blit.shader_obj); -+} -+ -+int r600_vb_ib_get(struct radeon_device *rdev) -+{ -+ int r; -+ r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib); -+ if (r) { -+ DRM_ERROR("failed to get IB for vertex buffer\n"); -+ return r; -+ } -+ -+ rdev->r600_blit.vb_total = 64*1024; -+ rdev->r600_blit.vb_used = 0; -+ return 0; -+} -+ -+void r600_vb_ib_put(struct radeon_device *rdev) -+{ -+ mutex_lock(&rdev->ib_pool.mutex); -+ radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); -+ list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs); -+ mutex_unlock(&rdev->ib_pool.mutex); -+ radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); -+} -+ -+int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) -+{ -+ int r; -+ int ring_size; -+ const int max_size = 8192*8192; -+ -+ r = r600_vb_ib_get(rdev); -+ WARN_ON(r); -+ -+ /* loops of emits 64 + fence emit possible */ -+ ring_size = ((size_bytes + max_size) / max_size) * 78; -+ /* set default + shaders */ -+ ring_size += 40; /* shaders + def state */ -+ ring_size += 3; /* fence emit for VB IB */ -+ ring_size += 5; /* done copy */ -+ ring_size += 3; /* fence emit for done copy */ -+ r = radeon_ring_lock(rdev, ring_size); -+ WARN_ON(r); -+ -+ set_default_state(rdev); /* 14 */ -+ set_shaders(rdev); /* 26 */ -+ return 0; -+} -+ -+void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) -+{ -+ int r; -+ -+ radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); -+ radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); -+ /* wait for 3D idle clean */ -+ radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); -+ radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); -+ radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); -+ -+ if (rdev->r600_blit.vb_ib) -+ r600_vb_ib_put(rdev); -+ -+ if (fence) -+ r = radeon_fence_emit(rdev, fence); -+ -+ radeon_ring_unlock_commit(rdev); -+} -+ -+void r600_kms_blit_copy(struct radeon_device *rdev, -+ u64 src_gpu_addr, u64 dst_gpu_addr, -+ int size_bytes) -+{ -+ int max_bytes; -+ u64 vb_gpu_addr; -+ u32 *vb; -+ -+ DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, -+ size_bytes, rdev->r600_blit.vb_used); -+ vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); -+ if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { -+ max_bytes = 8192; -+ -+ while (size_bytes) { -+ int cur_size = size_bytes; -+ int src_x = src_gpu_addr & 255; -+ int dst_x = dst_gpu_addr & 255; -+ int h = 1; -+ src_gpu_addr = src_gpu_addr & ~255; -+ dst_gpu_addr = dst_gpu_addr & ~255; -+ -+ if (!src_x && !dst_x) { -+ h = (cur_size / max_bytes); -+ if (h > 8192) -+ h = 8192; -+ if (h == 0) -+ h = 1; -+ else -+ cur_size = max_bytes; -+ } else { -+ if (cur_size > max_bytes) -+ cur_size = max_bytes; -+ if (cur_size > (max_bytes - dst_x)) -+ cur_size = (max_bytes - dst_x); -+ if (cur_size > (max_bytes - src_x)) -+ cur_size = (max_bytes - src_x); -+ } -+ -+ if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { -+ WARN_ON(1); -+ -+#if 0 -+ r600_vb_ib_put(rdev); -+ -+ r600_nomm_put_vb(dev); -+ r600_nomm_get_vb(dev); -+ if (!dev_priv->blit_vb) -+ return; -+ set_shaders(dev); -+ vb = r600_nomm_get_vb_ptr(dev); -+#endif -+ } -+ -+ vb[0] = i2f(dst_x); -+ vb[1] = 0; -+ vb[2] = i2f(src_x); -+ vb[3] = 0; -+ -+ vb[4] = i2f(dst_x); -+ vb[5] = i2f(h); -+ vb[6] = i2f(src_x); -+ vb[7] = i2f(h); -+ -+ vb[8] = i2f(dst_x + cur_size); -+ vb[9] = i2f(h); -+ vb[10] = i2f(src_x + cur_size); -+ vb[11] = i2f(h); -+ -+ /* src 9 */ -+ set_tex_resource(rdev, FMT_8, -+ src_x + cur_size, h, src_x + cur_size, -+ src_gpu_addr); -+ -+ /* 5 */ -+ cp_set_surface_sync(rdev, -+ PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); -+ -+ /* dst 23 */ -+ set_render_target(rdev, COLOR_8, -+ dst_x + cur_size, h, -+ dst_gpu_addr); -+ -+ /* scissors 12 */ -+ set_scissors(rdev, dst_x, 0, dst_x + cur_size, h); -+ -+ /* 14 */ -+ vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; -+ set_vtx_resource(rdev, vb_gpu_addr); -+ -+ /* draw 10 */ -+ draw_auto(rdev); -+ -+ /* 5 */ -+ cp_set_surface_sync(rdev, -+ PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, -+ cur_size * h, dst_gpu_addr); -+ -+ vb += 12; -+ rdev->r600_blit.vb_used += 12 * 4; -+ -+ src_gpu_addr += cur_size * h; -+ dst_gpu_addr += cur_size * h; -+ size_bytes -= cur_size * h; -+ } -+ } else { -+ max_bytes = 8192 * 4; -+ -+ while (size_bytes) { -+ int cur_size = size_bytes; -+ int src_x = (src_gpu_addr & 255); -+ int dst_x = (dst_gpu_addr & 255); -+ int h = 1; -+ src_gpu_addr = src_gpu_addr & ~255; -+ dst_gpu_addr = dst_gpu_addr & ~255; -+ -+ if (!src_x && !dst_x) { -+ h = (cur_size / max_bytes); -+ if (h > 8192) -+ h = 8192; -+ if (h == 0) -+ h = 1; -+ else -+ cur_size = max_bytes; -+ } else { -+ if (cur_size > max_bytes) -+ cur_size = max_bytes; -+ if (cur_size > (max_bytes - dst_x)) -+ cur_size = (max_bytes - dst_x); -+ if (cur_size > (max_bytes - src_x)) -+ cur_size = (max_bytes - src_x); -+ } -+ -+ if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { -+ WARN_ON(1); -+ } -+#if 0 -+ if ((rdev->blit_vb->used + 48) > rdev->blit_vb->total) { -+ r600_nomm_put_vb(dev); -+ r600_nomm_get_vb(dev); -+ if (!rdev->blit_vb) -+ return; -+ -+ set_shaders(dev); -+ vb = r600_nomm_get_vb_ptr(dev); -+ } -+#endif -+ -+ vb[0] = i2f(dst_x / 4); -+ vb[1] = 0; -+ vb[2] = i2f(src_x / 4); -+ vb[3] = 0; -+ -+ vb[4] = i2f(dst_x / 4); -+ vb[5] = i2f(h); -+ vb[6] = i2f(src_x / 4); -+ vb[7] = i2f(h); -+ -+ vb[8] = i2f((dst_x + cur_size) / 4); -+ vb[9] = i2f(h); -+ vb[10] = i2f((src_x + cur_size) / 4); -+ vb[11] = i2f(h); -+ -+ /* src 9 */ -+ set_tex_resource(rdev, FMT_8_8_8_8, -+ (src_x + cur_size) / 4, -+ h, (src_x + cur_size) / 4, -+ src_gpu_addr); -+ /* 5 */ -+ cp_set_surface_sync(rdev, -+ PACKET3_TC_ACTION_ENA, (src_x + cur_size * h), src_gpu_addr); -+ -+ /* dst 23 */ -+ set_render_target(rdev, COLOR_8_8_8_8, -+ dst_x + cur_size, h, -+ dst_gpu_addr); -+ -+ /* scissors 12 */ -+ set_scissors(rdev, (dst_x / 4), 0, (dst_x + cur_size / 4), h); -+ -+ /* Vertex buffer setup 14 */ -+ vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; -+ set_vtx_resource(rdev, vb_gpu_addr); -+ -+ /* draw 10 */ -+ draw_auto(rdev); -+ -+ /* 5 */ -+ cp_set_surface_sync(rdev, -+ PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, -+ cur_size * h, dst_gpu_addr); -+ -+ /* 78 ring dwords per loop */ -+ vb += 12; -+ rdev->r600_blit.vb_used += 12 * 4; -+ -+ src_gpu_addr += cur_size * h; -+ dst_gpu_addr += cur_size * h; -+ size_bytes -= cur_size * h; -+ } -+ } -+} -+ -diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c -new file mode 100644 -index 0000000..d745e81 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c -@@ -0,0 +1,1072 @@ -+ -+#include -+#include -+ -+const u32 r6xx_default_state[] = -+{ -+ 0xc0002400, -+ 0x00000000, -+ 0xc0012800, -+ 0x80000000, -+ 0x80000000, -+ 0xc0004600, -+ 0x00000016, -+ 0xc0016800, -+ 0x00000010, -+ 0x00028000, -+ 0xc0016800, -+ 0x00000010, -+ 0x00008000, -+ 0xc0016800, -+ 0x00000542, -+ 0x07000003, -+ 0xc0016800, -+ 0x000005c5, -+ 0x00000000, -+ 0xc0016800, -+ 0x00000363, -+ 0x00000000, -+ 0xc0016800, -+ 0x0000060c, -+ 0x82000000, -+ 0xc0016800, -+ 0x0000060e, -+ 0x01020204, -+ 0xc0016f00, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016f00, -+ 0x00000001, -+ 0x00000000, -+ 0xc0096900, -+ 0x0000022a, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000004, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000000a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000000b, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010c, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010d, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000200, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000343, -+ 0x00000060, -+ 0xc0016900, -+ 0x00000344, -+ 0x00000040, -+ 0xc0016900, -+ 0x00000351, -+ 0x0000aa00, -+ 0xc0016900, -+ 0x00000104, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010e, -+ 0x00000000, -+ 0xc0046900, -+ 0x00000105, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0036900, -+ 0x00000109, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0046900, -+ 0x0000030c, -+ 0x01000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0046900, -+ 0x00000048, -+ 0x3f800000, -+ 0x00000000, -+ 0x3f800000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000008e, -+ 0x0000000f, -+ 0xc0016900, -+ 0x00000080, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000083, -+ 0x0000ffff, -+ 0xc0016900, -+ 0x00000084, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000085, -+ 0x20002000, -+ 0xc0016900, -+ 0x00000086, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000087, -+ 0x20002000, -+ 0xc0016900, -+ 0x00000088, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000089, -+ 0x20002000, -+ 0xc0016900, -+ 0x0000008a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000008b, -+ 0x20002000, -+ 0xc0016900, -+ 0x0000008c, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000094, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000095, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b4, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000096, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000097, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b6, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000098, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000099, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b8, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009a, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009b, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ba, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009c, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009d, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000bc, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009e, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009f, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000be, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a0, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a1, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c0, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a2, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a3, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c2, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a4, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a5, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c4, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a6, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a7, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c6, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a8, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a9, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c8, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000aa, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000ab, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ca, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000ac, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000ad, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000cc, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000ae, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000af, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ce, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000b0, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000b1, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000d0, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000b2, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000b3, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000d2, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000293, -+ 0x00004010, -+ 0xc0016900, -+ 0x00000300, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000301, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000312, -+ 0xffffffff, -+ 0xc0016900, -+ 0x00000307, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000308, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000283, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000292, -+ 0x00000000, -+ 0xc0066900, -+ 0x0000010f, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000206, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000207, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000208, -+ 0x00000000, -+ 0xc0046900, -+ 0x00000303, -+ 0x3f800000, -+ 0x3f800000, -+ 0x3f800000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000205, -+ 0x00000004, -+ 0xc0016900, -+ 0x00000280, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000281, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000037e, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000382, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000380, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000383, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000381, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000282, -+ 0x00000008, -+ 0xc0016900, -+ 0x00000302, -+ 0x0000002d, -+ 0xc0016900, -+ 0x0000037f, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b2, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b6, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b7, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b8, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b9, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000225, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000229, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000237, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000100, -+ 0x00000800, -+ 0xc0016900, -+ 0x00000101, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000102, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a8, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a9, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000103, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000284, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000290, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000285, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000286, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000287, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000288, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000289, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028b, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028c, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028d, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028e, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028f, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a1, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a5, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ac, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ad, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ae, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002c8, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000206, -+ 0x00000100, -+ 0xc0016900, -+ 0x00000204, -+ 0x00010000, -+ 0xc0036e00, -+ 0x00000000, -+ 0x00000012, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000008f, -+ 0x0000000f, -+ 0xc0016900, -+ 0x000001e8, -+ 0x00000001, -+ 0xc0016900, -+ 0x00000202, -+ 0x00cc0000, -+ 0xc0016900, -+ 0x00000205, -+ 0x00000244, -+ 0xc0016900, -+ 0x00000203, -+ 0x00000210, -+ 0xc0016900, -+ 0x000001b1, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000185, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b3, -+ 0x00000001, -+ 0xc0016900, -+ 0x000001b4, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000191, -+ 0x00000b00, -+ 0xc0016900, -+ 0x000001b5, -+ 0x00000000, -+}; -+ -+const u32 r7xx_default_state[] = -+{ -+ 0xc0012800, -+ 0x80000000, -+ 0x80000000, -+ 0xc0004600, -+ 0x00000016, -+ 0xc0016800, -+ 0x00000010, -+ 0x00028000, -+ 0xc0016800, -+ 0x00000010, -+ 0x00008000, -+ 0xc0016800, -+ 0x00000542, -+ 0x07000002, -+ 0xc0016800, -+ 0x000005c5, -+ 0x00000000, -+ 0xc0016800, -+ 0x00000363, -+ 0x00004000, -+ 0xc0016800, -+ 0x0000060c, -+ 0x00000000, -+ 0xc0016800, -+ 0x0000060e, -+ 0x00420204, -+ 0xc0016f00, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016f00, -+ 0x00000001, -+ 0x00000000, -+ 0xc0096900, -+ 0x0000022a, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000004, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000000a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000000b, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010c, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010d, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000200, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000343, -+ 0x00000060, -+ 0xc0016900, -+ 0x00000344, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000351, -+ 0x0000aa00, -+ 0xc0016900, -+ 0x00000104, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000010e, -+ 0x00000000, -+ 0xc0046900, -+ 0x00000105, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0046900, -+ 0x0000030c, -+ 0x01000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000008e, -+ 0x0000000f, -+ 0xc0016900, -+ 0x00000080, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000083, -+ 0x0000ffff, -+ 0xc0016900, -+ 0x00000084, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000085, -+ 0x20002000, -+ 0xc0016900, -+ 0x00000086, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000087, -+ 0x20002000, -+ 0xc0016900, -+ 0x00000088, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000089, -+ 0x20002000, -+ 0xc0016900, -+ 0x0000008a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000008b, -+ 0x20002000, -+ 0xc0016900, -+ 0x0000008c, -+ 0xaaaaaaaa, -+ 0xc0016900, -+ 0x00000094, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000095, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b4, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000096, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000097, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b6, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000098, -+ 0x80000000, -+ 0xc0016900, -+ 0x00000099, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000b8, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009a, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009b, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ba, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009c, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009d, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000bc, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x0000009e, -+ 0x80000000, -+ 0xc0016900, -+ 0x0000009f, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000be, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a0, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a1, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c0, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a2, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a3, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c2, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a4, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a5, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c4, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a6, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a7, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c6, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000a8, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000a9, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000c8, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000aa, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000ab, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ca, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000ac, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000ad, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000cc, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000ae, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000af, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000ce, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000b0, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000b1, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000d0, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x000000b2, -+ 0x80000000, -+ 0xc0016900, -+ 0x000000b3, -+ 0x20002000, -+ 0xc0026900, -+ 0x000000d2, -+ 0x00000000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000293, -+ 0x00514000, -+ 0xc0016900, -+ 0x00000300, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000301, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000312, -+ 0xffffffff, -+ 0xc0016900, -+ 0x00000307, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000308, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000283, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000292, -+ 0x00000000, -+ 0xc0066900, -+ 0x0000010f, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000206, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000207, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000208, -+ 0x00000000, -+ 0xc0046900, -+ 0x00000303, -+ 0x3f800000, -+ 0x3f800000, -+ 0x3f800000, -+ 0x3f800000, -+ 0xc0016900, -+ 0x00000205, -+ 0x00000004, -+ 0xc0016900, -+ 0x00000280, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000281, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000037e, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000382, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000380, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000383, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000381, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000282, -+ 0x00000008, -+ 0xc0016900, -+ 0x00000302, -+ 0x0000002d, -+ 0xc0016900, -+ 0x0000037f, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b2, -+ 0x00000001, -+ 0xc0016900, -+ 0x000001b6, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b7, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b8, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b9, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000225, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000229, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000237, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000100, -+ 0x00000800, -+ 0xc0016900, -+ 0x00000101, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000102, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a8, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a9, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000103, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000284, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000290, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000285, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000286, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000287, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000288, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000289, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028a, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028b, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028c, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028d, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028e, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000028f, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a1, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002a5, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ac, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ad, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002ae, -+ 0x00000000, -+ 0xc0016900, -+ 0x000002c8, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000206, -+ 0x00000100, -+ 0xc0016900, -+ 0x00000204, -+ 0x00010000, -+ 0xc0036e00, -+ 0x00000000, -+ 0x00000012, -+ 0x00000000, -+ 0x00000000, -+ 0xc0016900, -+ 0x0000008f, -+ 0x0000000f, -+ 0xc0016900, -+ 0x000001e8, -+ 0x00000001, -+ 0xc0016900, -+ 0x00000202, -+ 0x00cc0000, -+ 0xc0016900, -+ 0x00000205, -+ 0x00000244, -+ 0xc0016900, -+ 0x00000203, -+ 0x00000210, -+ 0xc0016900, -+ 0x000001b1, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000185, -+ 0x00000000, -+ 0xc0016900, -+ 0x000001b3, -+ 0x00000001, -+ 0xc0016900, -+ 0x000001b4, -+ 0x00000000, -+ 0xc0016900, -+ 0x00000191, -+ 0x00000b00, -+ 0xc0016900, -+ 0x000001b5, -+ 0x00000000, -+}; -+ -+/* same for r6xx/r7xx */ -+const u32 r6xx_vs[] = -+{ -+ 0x00000004, -+ 0x81000000, -+ 0x0000203c, -+ 0x94000b08, -+ 0x00004000, -+ 0x14200b1a, -+ 0x00000000, -+ 0x00000000, -+ 0x3c000000, -+ 0x68cd1000, -+ 0x00080000, -+ 0x00000000, -+}; -+ -+const u32 r6xx_ps[] = -+{ -+ 0x00000002, -+ 0x80800000, -+ 0x00000000, -+ 0x94200688, -+ 0x00000010, -+ 0x000d1000, -+ 0xb0800000, -+ 0x00000000, -+}; -+ -+const u32 r6xx_ps_size = ARRAY_SIZE(r6xx_ps); -+const u32 r6xx_vs_size = ARRAY_SIZE(r6xx_vs); -+const u32 r6xx_default_size = ARRAY_SIZE(r6xx_default_state); -+const u32 r7xx_default_size = ARRAY_SIZE(r7xx_default_state); -diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.h b/drivers/gpu/drm/radeon/r600_blit_shaders.h -new file mode 100644 -index 0000000..fdc3b37 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600_blit_shaders.h -@@ -0,0 +1,14 @@ -+ -+#ifndef R600_BLIT_SHADERS_H -+#define R600_BLIT_SHADERS_H -+ -+extern const u32 r6xx_ps[]; -+extern const u32 r6xx_vs[]; -+extern const u32 r7xx_default_state[]; -+extern const u32 r6xx_default_state[]; -+ -+ -+extern const u32 r6xx_ps_size, r6xx_vs_size; -+extern const u32 r6xx_default_size, r7xx_default_size; -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c -index 20f1790..6d5a711 100644 ---- a/drivers/gpu/drm/radeon/r600_cp.c -+++ b/drivers/gpu/drm/radeon/r600_cp.c -@@ -31,7 +31,38 @@ - #include "radeon_drm.h" - #include "radeon_drv.h" - --#include "r600_microcode.h" -+#define PFP_UCODE_SIZE 576 -+#define PM4_UCODE_SIZE 1792 -+#define R700_PFP_UCODE_SIZE 848 -+#define R700_PM4_UCODE_SIZE 1360 -+ -+/* Firmware Names */ -+MODULE_FIRMWARE("radeon/R600_pfp.bin"); -+MODULE_FIRMWARE("radeon/R600_me.bin"); -+MODULE_FIRMWARE("radeon/RV610_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV610_me.bin"); -+MODULE_FIRMWARE("radeon/RV630_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV630_me.bin"); -+MODULE_FIRMWARE("radeon/RV620_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV620_me.bin"); -+MODULE_FIRMWARE("radeon/RV635_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV635_me.bin"); -+MODULE_FIRMWARE("radeon/RV670_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV670_me.bin"); -+MODULE_FIRMWARE("radeon/RS780_pfp.bin"); -+MODULE_FIRMWARE("radeon/RS780_me.bin"); -+MODULE_FIRMWARE("radeon/RV770_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV770_me.bin"); -+MODULE_FIRMWARE("radeon/RV730_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV730_me.bin"); -+MODULE_FIRMWARE("radeon/RV710_pfp.bin"); -+MODULE_FIRMWARE("radeon/RV710_me.bin"); -+ -+ -+int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, -+ unsigned family, u32 *ib, int *l); -+void r600_cs_legacy_init(void); -+ - - # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ - # define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) -@@ -275,11 +306,93 @@ static void r600_vm_init(struct drm_device *dev) - r600_vm_flush_gart_range(dev); - } - --/* load r600 microcode */ -+static int r600_cp_init_microcode(drm_radeon_private_t *dev_priv) -+{ -+ struct platform_device *pdev; -+ const char *chip_name; -+ size_t pfp_req_size, me_req_size; -+ char fw_name[30]; -+ int err; -+ -+ pdev = platform_device_register_simple("r600_cp", 0, NULL, 0); -+ err = IS_ERR(pdev); -+ if (err) { -+ printk(KERN_ERR "r600_cp: Failed to register firmware\n"); -+ return -EINVAL; -+ } -+ -+ switch (dev_priv->flags & RADEON_FAMILY_MASK) { -+ case CHIP_R600: chip_name = "R600"; break; -+ case CHIP_RV610: chip_name = "RV610"; break; -+ case CHIP_RV630: chip_name = "RV630"; break; -+ case CHIP_RV620: chip_name = "RV620"; break; -+ case CHIP_RV635: chip_name = "RV635"; break; -+ case CHIP_RV670: chip_name = "RV670"; break; -+ case CHIP_RS780: -+ case CHIP_RS880: chip_name = "RS780"; break; -+ case CHIP_RV770: chip_name = "RV770"; break; -+ case CHIP_RV730: -+ case CHIP_RV740: chip_name = "RV730"; break; -+ case CHIP_RV710: chip_name = "RV710"; break; -+ default: BUG(); -+ } -+ -+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { -+ pfp_req_size = R700_PFP_UCODE_SIZE * 4; -+ me_req_size = R700_PM4_UCODE_SIZE * 4; -+ } else { -+ pfp_req_size = PFP_UCODE_SIZE * 4; -+ me_req_size = PM4_UCODE_SIZE * 12; -+ } -+ -+ DRM_INFO("Loading %s CP Microcode\n", chip_name); -+ -+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); -+ err = request_firmware(&dev_priv->pfp_fw, fw_name, &pdev->dev); -+ if (err) -+ goto out; -+ if (dev_priv->pfp_fw->size != pfp_req_size) { -+ printk(KERN_ERR -+ "r600_cp: Bogus length %zu in firmware \"%s\"\n", -+ dev_priv->pfp_fw->size, fw_name); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); -+ err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); -+ if (err) -+ goto out; -+ if (dev_priv->me_fw->size != me_req_size) { -+ printk(KERN_ERR -+ "r600_cp: Bogus length %zu in firmware \"%s\"\n", -+ dev_priv->me_fw->size, fw_name); -+ err = -EINVAL; -+ } -+out: -+ platform_device_unregister(pdev); -+ -+ if (err) { -+ if (err != -EINVAL) -+ printk(KERN_ERR -+ "r600_cp: Failed to load firmware \"%s\"\n", -+ fw_name); -+ release_firmware(dev_priv->pfp_fw); -+ dev_priv->pfp_fw = NULL; -+ release_firmware(dev_priv->me_fw); -+ dev_priv->me_fw = NULL; -+ } -+ return err; -+} -+ - static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) - { -+ const __be32 *fw_data; - int i; - -+ if (!dev_priv->me_fw || !dev_priv->pfp_fw) -+ return; -+ - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, -@@ -292,115 +405,18 @@ static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) - DRM_UDELAY(15000); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - -+ fw_data = (const __be32 *)dev_priv->me_fw->data; - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -+ for (i = 0; i < PM4_UCODE_SIZE * 3; i++) -+ RADEON_WRITE(R600_CP_ME_RAM_DATA, -+ be32_to_cpup(fw_data++)); - -- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { -- DRM_INFO("Loading R600 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- R600_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- R600_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- R600_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading R600 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) { -- DRM_INFO("Loading RV610 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV610_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV610_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV610_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV610 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { -- DRM_INFO("Loading RV630 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV630_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV630_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV630_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV630 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) { -- DRM_INFO("Loading RV620 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV620_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV620_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV620_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV620 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { -- DRM_INFO("Loading RV635 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV635_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV635_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV635_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV635 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) { -- DRM_INFO("Loading RV670 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV670_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV670_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RV670_cp_microcode[i][2]); -- } -- -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV670 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780) || -- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS880)) { -- DRM_INFO("Loading RS780/RS880 CP Microcode\n"); -- for (i = 0; i < PM4_UCODE_SIZE; i++) { -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RS780_cp_microcode[i][0]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RS780_cp_microcode[i][1]); -- RADEON_WRITE(R600_CP_ME_RAM_DATA, -- RS780_cp_microcode[i][2]); -- } -+ fw_data = (const __be32 *)dev_priv->pfp_fw->data; -+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -+ for (i = 0; i < PFP_UCODE_SIZE; i++) -+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, -+ be32_to_cpup(fw_data++)); - -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RS780/RS880 PFP Microcode\n"); -- for (i = 0; i < PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]); -- } - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); -@@ -459,11 +475,14 @@ static void r700_vm_init(struct drm_device *dev) - r600_vm_flush_gart_range(dev); - } - --/* load r600 microcode */ - static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) - { -+ const __be32 *fw_data; - int i; - -+ if (!dev_priv->me_fw || !dev_priv->pfp_fw) -+ return; -+ - r600_do_cp_stop(dev_priv); - - RADEON_WRITE(R600_CP_RB_CNTL, -@@ -476,48 +495,18 @@ static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) - DRM_UDELAY(15000); - RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); - -+ fw_data = (const __be32 *)dev_priv->pfp_fw->data; -+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++) -+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); -+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - -- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV770/RV790 PFP Microcode\n"); -- for (i = 0; i < R700_PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -- DRM_INFO("Loading RV770/RV790 CP Microcode\n"); -- for (i = 0; i < R700_PM4_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]); -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -- -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730) || -- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)) { -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV730/RV740 PFP Microcode\n"); -- for (i = 0; i < R700_PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]); -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -- DRM_INFO("Loading RV730/RV740 CP Microcode\n"); -- for (i = 0; i < R700_PM4_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]); -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -- -- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) { -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- DRM_INFO("Loading RV710 PFP Microcode\n"); -- for (i = 0; i < R700_PFP_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]); -- RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); -- -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -- DRM_INFO("Loading RV710 CP Microcode\n"); -- for (i = 0; i < R700_PM4_UCODE_SIZE; i++) -- RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]); -- RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -+ fw_data = (const __be32 *)dev_priv->me_fw->data; -+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); -+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++) -+ RADEON_WRITE(R600_CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); -+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - -- } - RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); - RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); -@@ -1874,6 +1863,8 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - - DRM_DEBUG("\n"); - -+ mutex_init(&dev_priv->cs_mutex); -+ r600_cs_legacy_init(); - /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); -@@ -1905,7 +1896,7 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - /* Enable vblank on CRTC1 for older X servers - */ - dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; -- -+ dev_priv->do_boxes = 0; - dev_priv->cp_mode = init->cp_mode; - - /* We don't support anything other than bus-mastering ring mode, -@@ -1991,11 +1982,11 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - } else - #endif - { -- dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; -+ dev_priv->cp_ring->handle = (void *)(unsigned long)dev_priv->cp_ring->offset; - dev_priv->ring_rptr->handle = -- (void *)dev_priv->ring_rptr->offset; -+ (void *)(unsigned long)dev_priv->ring_rptr->offset; - dev->agp_buffer_map->handle = -- (void *)dev->agp_buffer_map->offset; -+ (void *)(unsigned long)dev->agp_buffer_map->offset; - - DRM_DEBUG("dev_priv->cp_ring->handle %p\n", - dev_priv->cp_ring->handle); -@@ -2147,6 +2138,14 @@ int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - r600_vm_init(dev); - } - -+ if (!dev_priv->me_fw || !dev_priv->pfp_fw) { -+ int err = r600_cp_init_microcode(dev_priv); -+ if (err) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ r600_do_cleanup_cp(dev); -+ return err; -+ } -+ } - if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) - r700_cp_load_microcode(dev_priv); - else -@@ -2291,3 +2290,239 @@ int r600_cp_dispatch_indirect(struct drm_device *dev, - - return 0; - } -+ -+void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ struct drm_master *master = file_priv->master; -+ struct drm_radeon_master_private *master_priv = master->driver_priv; -+ drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; -+ int nbox = sarea_priv->nbox; -+ struct drm_clip_rect *pbox = sarea_priv->boxes; -+ int i, cpp, src_pitch, dst_pitch; -+ uint64_t src, dst; -+ RING_LOCALS; -+ DRM_DEBUG("\n"); -+ -+ if (dev_priv->color_fmt == RADEON_COLOR_FORMAT_ARGB8888) -+ cpp = 4; -+ else -+ cpp = 2; -+ -+ if (sarea_priv->pfCurrentPage == 0) { -+ src_pitch = dev_priv->back_pitch; -+ dst_pitch = dev_priv->front_pitch; -+ src = dev_priv->back_offset + dev_priv->fb_location; -+ dst = dev_priv->front_offset + dev_priv->fb_location; -+ } else { -+ src_pitch = dev_priv->front_pitch; -+ dst_pitch = dev_priv->back_pitch; -+ src = dev_priv->front_offset + dev_priv->fb_location; -+ dst = dev_priv->back_offset + dev_priv->fb_location; -+ } -+ -+ if (r600_prepare_blit_copy(dev, file_priv)) { -+ DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); -+ return; -+ } -+ for (i = 0; i < nbox; i++) { -+ int x = pbox[i].x1; -+ int y = pbox[i].y1; -+ int w = pbox[i].x2 - x; -+ int h = pbox[i].y2 - y; -+ -+ DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h); -+ -+ r600_blit_swap(dev, -+ src, dst, -+ x, y, x, y, w, h, -+ src_pitch, dst_pitch, cpp); -+ } -+ r600_done_blit_copy(dev); -+ -+ /* Increment the frame counter. The client-side 3D driver must -+ * throttle the framerate by waiting for this value before -+ * performing the swapbuffer ioctl. -+ */ -+ sarea_priv->last_frame++; -+ -+ BEGIN_RING(3); -+ R600_FRAME_AGE(sarea_priv->last_frame); -+ ADVANCE_RING(); -+} -+ -+int r600_cp_dispatch_texture(struct drm_device *dev, -+ struct drm_file *file_priv, -+ drm_radeon_texture_t *tex, -+ drm_radeon_tex_image_t *image) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ struct drm_buf *buf; -+ u32 *buffer; -+ const u8 __user *data; -+ int size, pass_size; -+ u64 src_offset, dst_offset; -+ -+ if (!radeon_check_offset(dev_priv, tex->offset)) { -+ DRM_ERROR("Invalid destination offset\n"); -+ return -EINVAL; -+ } -+ -+ /* this might fail for zero-sized uploads - are those illegal? */ -+ if (!radeon_check_offset(dev_priv, tex->offset + tex->height * tex->pitch - 1)) { -+ DRM_ERROR("Invalid final destination offset\n"); -+ return -EINVAL; -+ } -+ -+ size = tex->height * tex->pitch; -+ -+ if (size == 0) -+ return 0; -+ -+ dst_offset = tex->offset; -+ -+ if (r600_prepare_blit_copy(dev, file_priv)) { -+ DRM_ERROR("unable to allocate vertex buffer for swap buffer\n"); -+ return -EAGAIN; -+ } -+ do { -+ data = (const u8 __user *)image->data; -+ pass_size = size; -+ -+ buf = radeon_freelist_get(dev); -+ if (!buf) { -+ DRM_DEBUG("EAGAIN\n"); -+ if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image))) -+ return -EFAULT; -+ return -EAGAIN; -+ } -+ -+ if (pass_size > buf->total) -+ pass_size = buf->total; -+ -+ /* Dispatch the indirect buffer. -+ */ -+ buffer = -+ (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset); -+ -+ if (DRM_COPY_FROM_USER(buffer, data, pass_size)) { -+ DRM_ERROR("EFAULT on pad, %d bytes\n", pass_size); -+ return -EFAULT; -+ } -+ -+ buf->file_priv = file_priv; -+ buf->used = pass_size; -+ src_offset = dev_priv->gart_buffers_offset + buf->offset; -+ -+ r600_blit_copy(dev, src_offset, dst_offset, pass_size); -+ -+ radeon_cp_discard_buffer(dev, file_priv->master, buf); -+ -+ /* Update the input parameters for next time */ -+ image->data = (const u8 __user *)image->data + pass_size; -+ dst_offset += pass_size; -+ size -= pass_size; -+ } while (size > 0); -+ r600_done_blit_copy(dev); -+ -+ return 0; -+} -+ -+/* -+ * Legacy cs ioctl -+ */ -+static u32 radeon_cs_id_get(struct drm_radeon_private *radeon) -+{ -+ /* FIXME: check if wrap affect last reported wrap & sequence */ -+ radeon->cs_id_scnt = (radeon->cs_id_scnt + 1) & 0x00FFFFFF; -+ if (!radeon->cs_id_scnt) { -+ /* increment wrap counter */ -+ radeon->cs_id_wcnt += 0x01000000; -+ /* valid sequence counter start at 1 */ -+ radeon->cs_id_scnt = 1; -+ } -+ return (radeon->cs_id_scnt | radeon->cs_id_wcnt); -+} -+ -+static void r600_cs_id_emit(drm_radeon_private_t *dev_priv, u32 *id) -+{ -+ RING_LOCALS; -+ -+ *id = radeon_cs_id_get(dev_priv); -+ -+ /* SCRATCH 2 */ -+ BEGIN_RING(3); -+ R600_CLEAR_AGE(*id); -+ ADVANCE_RING(); -+ COMMIT_RING(); -+} -+ -+static int r600_ib_get(struct drm_device *dev, -+ struct drm_file *fpriv, -+ struct drm_buf **buffer) -+{ -+ struct drm_buf *buf; -+ -+ *buffer = NULL; -+ buf = radeon_freelist_get(dev); -+ if (!buf) { -+ return -EBUSY; -+ } -+ buf->file_priv = fpriv; -+ *buffer = buf; -+ return 0; -+} -+ -+static void r600_ib_free(struct drm_device *dev, struct drm_buf *buf, -+ struct drm_file *fpriv, int l, int r) -+{ -+ drm_radeon_private_t *dev_priv = dev->dev_private; -+ -+ if (buf) { -+ if (!r) -+ r600_cp_dispatch_indirect(dev, buf, 0, l * 4); -+ radeon_cp_discard_buffer(dev, fpriv->master, buf); -+ COMMIT_RING(); -+ } -+} -+ -+int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv) -+{ -+ struct drm_radeon_private *dev_priv = dev->dev_private; -+ struct drm_radeon_cs *cs = data; -+ struct drm_buf *buf; -+ unsigned family; -+ int l, r = 0; -+ u32 *ib, cs_id = 0; -+ -+ if (dev_priv == NULL) { -+ DRM_ERROR("called with no initialization\n"); -+ return -EINVAL; -+ } -+ family = dev_priv->flags & RADEON_FAMILY_MASK; -+ if (family < CHIP_R600) { -+ DRM_ERROR("cs ioctl valid only for R6XX & R7XX in legacy mode\n"); -+ return -EINVAL; -+ } -+ mutex_lock(&dev_priv->cs_mutex); -+ /* get ib */ -+ r = r600_ib_get(dev, fpriv, &buf); -+ if (r) { -+ DRM_ERROR("ib_get failed\n"); -+ goto out; -+ } -+ ib = dev->agp_buffer_map->handle + buf->offset; -+ /* now parse command stream */ -+ r = r600_cs_legacy(dev, data, fpriv, family, ib, &l); -+ if (r) { -+ goto out; -+ } -+ -+out: -+ r600_ib_free(dev, buf, fpriv, l, r); -+ /* emit cs id sequence */ -+ r600_cs_id_emit(dev_priv, &cs_id); -+ cs->cs_id = cs_id; -+ mutex_unlock(&dev_priv->cs_mutex); -+ return r; -+} -diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c -new file mode 100644 -index 0000000..39bf634 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600_cs.c -@@ -0,0 +1,658 @@ -+/* -+ * Copyright 2008 Advanced Micro Devices, Inc. -+ * Copyright 2008 Red Hat Inc. -+ * Copyright 2009 Jerome Glisse. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#include "drmP.h" -+#include "radeon.h" -+#include "radeon_share.h" -+#include "r600d.h" -+#include "avivod.h" -+ -+static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, -+ struct radeon_cs_reloc **cs_reloc); -+static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, -+ struct radeon_cs_reloc **cs_reloc); -+typedef int (*next_reloc_t)(struct radeon_cs_parser*, struct radeon_cs_reloc**); -+static next_reloc_t r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_mm; -+ -+/** -+ * r600_cs_packet_parse() - parse cp packet and point ib index to next packet -+ * @parser: parser structure holding parsing context. -+ * @pkt: where to store packet informations -+ * -+ * Assume that chunk_ib_index is properly set. Will return -EINVAL -+ * if packet is bigger than remaining ib size. or if packets is unknown. -+ **/ -+int r600_cs_packet_parse(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt, -+ unsigned idx) -+{ -+ struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ uint32_t header; -+ -+ if (idx >= ib_chunk->length_dw) { -+ DRM_ERROR("Can not parse packet at %d after CS end %d !\n", -+ idx, ib_chunk->length_dw); -+ return -EINVAL; -+ } -+ header = ib_chunk->kdata[idx]; -+ pkt->idx = idx; -+ pkt->type = CP_PACKET_GET_TYPE(header); -+ pkt->count = CP_PACKET_GET_COUNT(header); -+ pkt->one_reg_wr = 0; -+ switch (pkt->type) { -+ case PACKET_TYPE0: -+ pkt->reg = CP_PACKET0_GET_REG(header); -+ break; -+ case PACKET_TYPE3: -+ pkt->opcode = CP_PACKET3_GET_OPCODE(header); -+ break; -+ case PACKET_TYPE2: -+ pkt->count = -1; -+ break; -+ default: -+ DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); -+ return -EINVAL; -+ } -+ if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { -+ DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", -+ pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+/** -+ * r600_cs_packet_next_reloc_mm() - parse next packet which should be reloc packet3 -+ * @parser: parser structure holding parsing context. -+ * @data: pointer to relocation data -+ * @offset_start: starting offset -+ * @offset_mask: offset mask (to align start offset on) -+ * @reloc: reloc informations -+ * -+ * Check next packet is relocation packet3, do bo validation and compute -+ * GPU offset using the provided start. -+ **/ -+static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, -+ struct radeon_cs_reloc **cs_reloc) -+{ -+ struct radeon_cs_chunk *ib_chunk; -+ struct radeon_cs_chunk *relocs_chunk; -+ struct radeon_cs_packet p3reloc; -+ unsigned idx; -+ int r; -+ -+ if (p->chunk_relocs_idx == -1) { -+ DRM_ERROR("No relocation chunk !\n"); -+ return -EINVAL; -+ } -+ *cs_reloc = NULL; -+ ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ relocs_chunk = &p->chunks[p->chunk_relocs_idx]; -+ r = r600_cs_packet_parse(p, &p3reloc, p->idx); -+ if (r) { -+ return r; -+ } -+ p->idx += p3reloc.count + 2; -+ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { -+ DRM_ERROR("No packet3 for relocation for packet at %d.\n", -+ p3reloc.idx); -+ return -EINVAL; -+ } -+ idx = ib_chunk->kdata[p3reloc.idx + 1]; -+ if (idx >= relocs_chunk->length_dw) { -+ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", -+ idx, relocs_chunk->length_dw); -+ return -EINVAL; -+ } -+ /* FIXME: we assume reloc size is 4 dwords */ -+ *cs_reloc = p->relocs_ptr[(idx / 4)]; -+ return 0; -+} -+ -+/** -+ * r600_cs_packet_next_reloc_nomm() - parse next packet which should be reloc packet3 -+ * @parser: parser structure holding parsing context. -+ * @data: pointer to relocation data -+ * @offset_start: starting offset -+ * @offset_mask: offset mask (to align start offset on) -+ * @reloc: reloc informations -+ * -+ * Check next packet is relocation packet3, do bo validation and compute -+ * GPU offset using the provided start. -+ **/ -+static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, -+ struct radeon_cs_reloc **cs_reloc) -+{ -+ struct radeon_cs_chunk *ib_chunk; -+ struct radeon_cs_chunk *relocs_chunk; -+ struct radeon_cs_packet p3reloc; -+ unsigned idx; -+ int r; -+ -+ if (p->chunk_relocs_idx == -1) { -+ DRM_ERROR("No relocation chunk !\n"); -+ return -EINVAL; -+ } -+ *cs_reloc = NULL; -+ ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ relocs_chunk = &p->chunks[p->chunk_relocs_idx]; -+ r = r600_cs_packet_parse(p, &p3reloc, p->idx); -+ if (r) { -+ return r; -+ } -+ p->idx += p3reloc.count + 2; -+ if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { -+ DRM_ERROR("No packet3 for relocation for packet at %d.\n", -+ p3reloc.idx); -+ return -EINVAL; -+ } -+ idx = ib_chunk->kdata[p3reloc.idx + 1]; -+ if (idx >= relocs_chunk->length_dw) { -+ DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", -+ idx, relocs_chunk->length_dw); -+ return -EINVAL; -+ } -+ *cs_reloc = &p->relocs[0]; -+ (*cs_reloc)->lobj.gpu_offset = (u64)relocs_chunk->kdata[idx + 3] << 32; -+ (*cs_reloc)->lobj.gpu_offset |= relocs_chunk->kdata[idx + 0]; -+ return 0; -+} -+ -+static int r600_packet0_check(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt, -+ unsigned idx, unsigned reg) -+{ -+ switch (reg) { -+ case AVIVO_D1MODE_VLINE_START_END: -+ case AVIVO_D2MODE_VLINE_START_END: -+ break; -+ default: -+ printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", -+ reg, idx); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static int r600_cs_parse_packet0(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt) -+{ -+ unsigned reg, i; -+ unsigned idx; -+ int r; -+ -+ idx = pkt->idx + 1; -+ reg = pkt->reg; -+ for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { -+ r = r600_packet0_check(p, pkt, idx, reg); -+ if (r) { -+ return r; -+ } -+ } -+ return 0; -+} -+ -+static int r600_packet3_check(struct radeon_cs_parser *p, -+ struct radeon_cs_packet *pkt) -+{ -+ struct radeon_cs_chunk *ib_chunk; -+ struct radeon_cs_reloc *reloc; -+ volatile u32 *ib; -+ unsigned idx; -+ unsigned i; -+ unsigned start_reg, end_reg, reg; -+ int r; -+ -+ ib = p->ib->ptr; -+ ib_chunk = &p->chunks[p->chunk_ib_idx]; -+ idx = pkt->idx + 1; -+ switch (pkt->opcode) { -+ case PACKET3_START_3D_CMDBUF: -+ if (p->family >= CHIP_RV770 || pkt->count) { -+ DRM_ERROR("bad START_3D\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_CONTEXT_CONTROL: -+ if (pkt->count != 1) { -+ DRM_ERROR("bad CONTEXT_CONTROL\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_INDEX_TYPE: -+ case PACKET3_NUM_INSTANCES: -+ if (pkt->count) { -+ DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_DRAW_INDEX: -+ if (pkt->count != 3) { -+ DRM_ERROR("bad DRAW_INDEX\n"); -+ return -EINVAL; -+ } -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad DRAW_INDEX\n"); -+ return -EINVAL; -+ } -+ ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; -+ break; -+ case PACKET3_DRAW_INDEX_AUTO: -+ if (pkt->count != 1) { -+ DRM_ERROR("bad DRAW_INDEX_AUTO\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_DRAW_INDEX_IMMD_BE: -+ case PACKET3_DRAW_INDEX_IMMD: -+ if (pkt->count < 2) { -+ DRM_ERROR("bad DRAW_INDEX_IMMD\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_WAIT_REG_MEM: -+ if (pkt->count != 5) { -+ DRM_ERROR("bad WAIT_REG_MEM\n"); -+ return -EINVAL; -+ } -+ /* bit 4 is reg (0) or mem (1) */ -+ if (ib_chunk->kdata[idx+0] & 0x10) { -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad WAIT_REG_MEM\n"); -+ return -EINVAL; -+ } -+ ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; -+ } -+ break; -+ case PACKET3_SURFACE_SYNC: -+ if (pkt->count != 3) { -+ DRM_ERROR("bad SURFACE_SYNC\n"); -+ return -EINVAL; -+ } -+ /* 0xffffffff/0x0 is flush all cache flag */ -+ if (ib_chunk->kdata[idx+1] != 0xffffffff || -+ ib_chunk->kdata[idx+2] != 0) { -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SURFACE_SYNC\n"); -+ return -EINVAL; -+ } -+ ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -+ } -+ break; -+ case PACKET3_EVENT_WRITE: -+ if (pkt->count != 2 && pkt->count != 0) { -+ DRM_ERROR("bad EVENT_WRITE\n"); -+ return -EINVAL; -+ } -+ if (pkt->count) { -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad EVENT_WRITE\n"); -+ return -EINVAL; -+ } -+ ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; -+ } -+ break; -+ case PACKET3_EVENT_WRITE_EOP: -+ if (pkt->count != 4) { -+ DRM_ERROR("bad EVENT_WRITE_EOP\n"); -+ return -EINVAL; -+ } -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad EVENT_WRITE\n"); -+ return -EINVAL; -+ } -+ ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); -+ ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; -+ break; -+ case PACKET3_SET_CONFIG_REG: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || -+ (start_reg >= PACKET3_SET_CONFIG_REG_END) || -+ (end_reg >= PACKET3_SET_CONFIG_REG_END)) { -+ DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); -+ return -EINVAL; -+ } -+ for (i = 0; i < pkt->count; i++) { -+ reg = start_reg + (4 * i); -+ switch (reg) { -+ case CP_COHER_BASE: -+ /* use PACKET3_SURFACE_SYNC */ -+ return -EINVAL; -+ default: -+ break; -+ } -+ } -+ break; -+ case PACKET3_SET_CONTEXT_REG: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || -+ (start_reg >= PACKET3_SET_CONTEXT_REG_END) || -+ (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { -+ DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); -+ return -EINVAL; -+ } -+ for (i = 0; i < pkt->count; i++) { -+ reg = start_reg + (4 * i); -+ switch (reg) { -+ case DB_DEPTH_BASE: -+ case CB_COLOR0_BASE: -+ case CB_COLOR1_BASE: -+ case CB_COLOR2_BASE: -+ case CB_COLOR3_BASE: -+ case CB_COLOR4_BASE: -+ case CB_COLOR5_BASE: -+ case CB_COLOR6_BASE: -+ case CB_COLOR7_BASE: -+ case SQ_PGM_START_FS: -+ case SQ_PGM_START_ES: -+ case SQ_PGM_START_VS: -+ case SQ_PGM_START_GS: -+ case SQ_PGM_START_PS: -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET_CONTEXT_REG " -+ "0x%04X\n", reg); -+ return -EINVAL; -+ } -+ ib[idx+1+i] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -+ break; -+ case VGT_DMA_BASE: -+ case VGT_DMA_BASE_HI: -+ /* These should be handled by DRAW_INDEX packet 3 */ -+ case VGT_STRMOUT_BASE_OFFSET_0: -+ case VGT_STRMOUT_BASE_OFFSET_1: -+ case VGT_STRMOUT_BASE_OFFSET_2: -+ case VGT_STRMOUT_BASE_OFFSET_3: -+ case VGT_STRMOUT_BASE_OFFSET_HI_0: -+ case VGT_STRMOUT_BASE_OFFSET_HI_1: -+ case VGT_STRMOUT_BASE_OFFSET_HI_2: -+ case VGT_STRMOUT_BASE_OFFSET_HI_3: -+ case VGT_STRMOUT_BUFFER_BASE_0: -+ case VGT_STRMOUT_BUFFER_BASE_1: -+ case VGT_STRMOUT_BUFFER_BASE_2: -+ case VGT_STRMOUT_BUFFER_BASE_3: -+ case VGT_STRMOUT_BUFFER_OFFSET_0: -+ case VGT_STRMOUT_BUFFER_OFFSET_1: -+ case VGT_STRMOUT_BUFFER_OFFSET_2: -+ case VGT_STRMOUT_BUFFER_OFFSET_3: -+ /* These should be handled by STRMOUT_BUFFER packet 3 */ -+ DRM_ERROR("bad context reg: 0x%08x\n", reg); -+ return -EINVAL; -+ default: -+ break; -+ } -+ } -+ break; -+ case PACKET3_SET_RESOURCE: -+ if (pkt->count % 7) { -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || -+ (start_reg >= PACKET3_SET_RESOURCE_END) || -+ (end_reg >= PACKET3_SET_RESOURCE_END)) { -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ for (i = 0; i < (pkt->count / 7); i++) { -+ switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) { -+ case SQ_TEX_VTX_VALID_TEXTURE: -+ /* tex base */ -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ ib[idx+1+(i*7)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -+ /* tex mip base */ -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ ib[idx+1+(i*7)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); -+ break; -+ case SQ_TEX_VTX_VALID_BUFFER: -+ /* vtx base */ -+ r = r600_cs_packet_next_reloc(p, &reloc); -+ if (r) { -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); -+ ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; -+ break; -+ case SQ_TEX_VTX_INVALID_TEXTURE: -+ case SQ_TEX_VTX_INVALID_BUFFER: -+ default: -+ DRM_ERROR("bad SET_RESOURCE\n"); -+ return -EINVAL; -+ } -+ } -+ break; -+ case PACKET3_SET_ALU_CONST: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || -+ (start_reg >= PACKET3_SET_ALU_CONST_END) || -+ (end_reg >= PACKET3_SET_ALU_CONST_END)) { -+ DRM_ERROR("bad SET_ALU_CONST\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_SET_BOOL_CONST: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || -+ (start_reg >= PACKET3_SET_BOOL_CONST_END) || -+ (end_reg >= PACKET3_SET_BOOL_CONST_END)) { -+ DRM_ERROR("bad SET_BOOL_CONST\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_SET_LOOP_CONST: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || -+ (start_reg >= PACKET3_SET_LOOP_CONST_END) || -+ (end_reg >= PACKET3_SET_LOOP_CONST_END)) { -+ DRM_ERROR("bad SET_LOOP_CONST\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_SET_CTL_CONST: -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || -+ (start_reg >= PACKET3_SET_CTL_CONST_END) || -+ (end_reg >= PACKET3_SET_CTL_CONST_END)) { -+ DRM_ERROR("bad SET_CTL_CONST\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_SET_SAMPLER: -+ if (pkt->count % 3) { -+ DRM_ERROR("bad SET_SAMPLER\n"); -+ return -EINVAL; -+ } -+ start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET; -+ end_reg = 4 * pkt->count + start_reg - 4; -+ if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || -+ (start_reg >= PACKET3_SET_SAMPLER_END) || -+ (end_reg >= PACKET3_SET_SAMPLER_END)) { -+ DRM_ERROR("bad SET_SAMPLER\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_SURFACE_BASE_UPDATE: -+ if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { -+ DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); -+ return -EINVAL; -+ } -+ if (pkt->count) { -+ DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); -+ return -EINVAL; -+ } -+ break; -+ case PACKET3_NOP: -+ break; -+ default: -+ DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+int r600_cs_parse(struct radeon_cs_parser *p) -+{ -+ struct radeon_cs_packet pkt; -+ int r; -+ -+ do { -+ r = r600_cs_packet_parse(p, &pkt, p->idx); -+ if (r) { -+ return r; -+ } -+ p->idx += pkt.count + 2; -+ switch (pkt.type) { -+ case PACKET_TYPE0: -+ r = r600_cs_parse_packet0(p, &pkt); -+ break; -+ case PACKET_TYPE2: -+ break; -+ case PACKET_TYPE3: -+ r = r600_packet3_check(p, &pkt); -+ break; -+ default: -+ DRM_ERROR("Unknown packet type %d !\n", pkt.type); -+ return -EINVAL; -+ } -+ if (r) { -+ return r; -+ } -+ } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); -+#if 0 -+ for (r = 0; r < p->ib->length_dw; r++) { -+ printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); -+ mdelay(1); -+ } -+#endif -+ return 0; -+} -+ -+static int r600_cs_parser_relocs_legacy(struct radeon_cs_parser *p) -+{ -+ if (p->chunk_relocs_idx == -1) { -+ return 0; -+ } -+ p->relocs = kcalloc(1, sizeof(struct radeon_cs_reloc), GFP_KERNEL); -+ if (p->relocs == NULL) { -+ return -ENOMEM; -+ } -+ return 0; -+} -+ -+/** -+ * cs_parser_fini() - clean parser states -+ * @parser: parser structure holding parsing context. -+ * @error: error number -+ * -+ * If error is set than unvalidate buffer, otherwise just free memory -+ * used by parsing context. -+ **/ -+static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) -+{ -+ unsigned i; -+ -+ kfree(parser->relocs); -+ for (i = 0; i < parser->nchunks; i++) { -+ kfree(parser->chunks[i].kdata); -+ } -+ kfree(parser->chunks); -+ kfree(parser->chunks_array); -+} -+ -+int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, -+ unsigned family, u32 *ib, int *l) -+{ -+ struct radeon_cs_parser parser; -+ struct radeon_cs_chunk *ib_chunk; -+ struct radeon_ib fake_ib; -+ int r; -+ -+ /* initialize parser */ -+ memset(&parser, 0, sizeof(struct radeon_cs_parser)); -+ parser.filp = filp; -+ parser.rdev = NULL; -+ parser.family = family; -+ parser.ib = &fake_ib; -+ fake_ib.ptr = ib; -+ r = radeon_cs_parser_init(&parser, data); -+ if (r) { -+ DRM_ERROR("Failed to initialize parser !\n"); -+ r600_cs_parser_fini(&parser, r); -+ return r; -+ } -+ r = r600_cs_parser_relocs_legacy(&parser); -+ if (r) { -+ DRM_ERROR("Failed to parse relocation !\n"); -+ r600_cs_parser_fini(&parser, r); -+ return r; -+ } -+ /* Copy the packet into the IB, the parser will read from the -+ * input memory (cached) and write to the IB (which can be -+ * uncached). */ -+ ib_chunk = &parser.chunks[parser.chunk_ib_idx]; -+ parser.ib->length_dw = ib_chunk->length_dw; -+ memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4); -+ *l = parser.ib->length_dw; -+ r = r600_cs_parse(&parser); -+ if (r) { -+ DRM_ERROR("Invalid command stream !\n"); -+ r600_cs_parser_fini(&parser, r); -+ return r; -+ } -+ r600_cs_parser_fini(&parser, r); -+ return r; -+} -+ -+void r600_cs_legacy_init(void) -+{ -+ r600_cs_packet_next_reloc = &r600_cs_packet_next_reloc_nomm; -+} -diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h -deleted file mode 100644 -index 778c8b4..0000000 ---- a/drivers/gpu/drm/radeon/r600_microcode.h -+++ /dev/null -@@ -1,23297 +0,0 @@ --/* -- * Copyright 2008-2009 Advanced Micro Devices, Inc. -- * All Rights Reserved. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice (including the next -- * paragraph) shall be included in all copies or substantial portions of the -- * Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- * -- */ -- --#ifndef R600_MICROCODE_H --#define R600_MICROCODE_H -- --static const int ME_JUMP_TABLE_START = 1764; --static const int ME_JUMP_TABLE_END = 1792; -- --#define PFP_UCODE_SIZE 576 --#define PM4_UCODE_SIZE 1792 --#define R700_PFP_UCODE_SIZE 848 --#define R700_PM4_UCODE_SIZE 1360 -- --static const u32 R600_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x614 }, -- { 0x00000000, 0x00600000, 0x5b2 }, -- { 0x00000000, 0x00600000, 0x5c5 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000020, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000021, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x0000001d, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x0000001d, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000030, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x00000010, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000030, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000032, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x0000002d, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x080 }, -- { 0x0000002e, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x081 }, -- { 0x00000000, 0x00400000, 0x087 }, -- { 0x0000002d, 0x00203623, 0x000 }, -- { 0x0000002e, 0x00203624, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x087 }, -- { 0x00000000, 0x00600000, 0x5ed }, -- { 0x00000000, 0x00600000, 0x5e1 }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08a }, -- { 0x00000018, 0xc0403620, 0x090 }, -- { 0x00000000, 0x2ee00000, 0x08e }, -- { 0x00000000, 0x2ce00000, 0x08d }, -- { 0x00000002, 0x00400e2d, 0x08f }, -- { 0x00000003, 0x00400e2d, 0x08f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000018, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x095 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x09d }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09b }, -- { 0x00000000, 0x2ce00000, 0x09a }, -- { 0x00000002, 0x00400e2d, 0x09c }, -- { 0x00000003, 0x00400e2d, 0x09c }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a4 }, -- { 0x0000001c, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x0000001b, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0db }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x28c }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x128 }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0c5 }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0d6 }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0d4 }, -- { 0x00000013, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0cf }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ce }, -- { 0x00003f00, 0x00400c11, 0x0d0 }, -- { 0x00001f00, 0x00400c11, 0x0d0 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0d6 }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00284a22, 0x000 }, -- { 0x00000030, 0x00200e2d, 0x000 }, -- { 0x0000002e, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e3 }, -- { 0x00000000, 0x00600000, 0x5e7 }, -- { 0x00000000, 0x00400000, 0x0e4 }, -- { 0x00000000, 0x00600000, 0x5ea }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x0000001d, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f1 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f1 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x0000001a, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f6 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x104 }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000013, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0fd }, -- { 0xffffffff, 0x00404811, 0x104 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x100 }, -- { 0x0000ffff, 0x00404811, 0x104 }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x103 }, -- { 0x000000ff, 0x00404811, 0x104 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000019, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x10d }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000019, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x114 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x110 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x127 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x614 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x613 }, -- { 0x00000004, 0x00404c11, 0x12e }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x00000000, 0x00600000, 0x151 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2a4 }, -- { 0x0001a1fd, 0x00604411, 0x2c9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x138 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x151 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2a4 }, -- { 0x0001a1fd, 0x00604411, 0x2c9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x149 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x17c }, -- { 0x00000000, 0x00600000, 0x18d }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x189 }, -- { 0x00000000, 0x00600000, 0x2a4 }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x28c }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x173 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x16f }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x184 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000013, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2e4 }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x165 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x2fe }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x181 }, -- { 0x0000001b, 0xc0203620, 0x000 }, -- { 0x0000001c, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x19f }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x188 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000032, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x00000011, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x128 }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00600e2d, 0x1aa }, -- { 0x0000001c, 0x00600e2d, 0x1aa }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x0000001d, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1a6 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000020, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000019, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1cd }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1c9 }, -- { 0x00000000, 0x00600000, 0x1d6 }, -- { 0x00000001, 0x00531e27, 0x1c5 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1be }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1d6 }, -- { 0x00000001, 0x00531e27, 0x1d2 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2a4 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e5 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x1f2 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x1f2 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x613 }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2a4 }, -- { 0x0001a1fd, 0x00604411, 0x2c9 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x206 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x1ff }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x5c5 }, -- { 0x00000000, 0x0040040f, 0x200 }, -- { 0x00000000, 0x00600000, 0x5b2 }, -- { 0x00000000, 0x00600000, 0x5c5 }, -- { 0x00000210, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00600000, 0x18d }, -- { 0x00000000, 0x00600000, 0x189 }, -- { 0x00000000, 0x00600000, 0x2a4 }, -- { 0x00000000, 0x00600000, 0x28c }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x21f }, -- { 0x00000000, 0xc0404800, 0x21c }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2e4 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x5b2 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x235 }, -- { 0x0000001a, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x0000001a, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x23a }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x2fe }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x265 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x253 }, -- { 0x00000018, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x248 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x24b }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000018, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x250 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x253 }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2aa }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25b }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25a }, -- { 0x00000016, 0x00404811, 0x25f }, -- { 0x00000018, 0x00404811, 0x25f }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25e }, -- { 0x00000017, 0x00404811, 0x25f }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2d2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x23f }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x614 }, -- { 0x00000000, 0x00600000, 0x5b2 }, -- { 0x00000000, 0xc0600000, 0x28c }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x00000034, 0x00201a2d, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x00000033, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x27b }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000034, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x128 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x286 }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000024, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000032, 0x00203622, 0x000 }, -- { 0x00000031, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000029, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000029, 0x00203627, 0x000 }, -- { 0x0000002a, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x0000002a, 0x00203627, 0x000 }, -- { 0x0000002b, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x0000002b, 0x00203627, 0x000 }, -- { 0x0000002c, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x0000002c, 0x00803627, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x0000002a, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x0000002b, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x0000002c, 0x00803627, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00203628, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2c5 }, -- { 0x00000000, 0x00400000, 0x2c2 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00203628, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2c2 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2c5 }, -- { 0x0000002b, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2c5 }, -- { 0x00000029, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2c5 }, -- { 0x0000002c, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2c5 }, -- { 0x0000002a, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2c5 }, -- { 0x00000000, 0x00600000, 0x5ed }, -- { 0x00000000, 0x00600000, 0x29e }, -- { 0x00000000, 0x00400000, 0x2c7 }, -- { 0x00000000, 0x00600000, 0x29e }, -- { 0x00000000, 0x00600000, 0x5e4 }, -- { 0x00000000, 0x00400000, 0x2c7 }, -- { 0x00000000, 0x00600000, 0x290 }, -- { 0x00000000, 0x00400000, 0x2c7 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000023, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x0000001d, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x301 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x0000001a, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x5c5 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x334 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x614 }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x33d }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x351 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000016, 0x00604811, 0x35e }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x355 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00404811, 0x349 }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x349 }, -- { 0x00002104, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x00000035, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x360 }, -- { 0x00000035, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x376 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x380 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x38c }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x398 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x398 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39a }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39f }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000015, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x614 }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x382 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x614 }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x38e }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000016, 0x00604811, 0x35e }, -- { 0x00000016, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3b9 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x614 }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ab }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3be }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x614 }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3cc }, -- { 0x00000000, 0xc0401800, 0x3cf }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x614 }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3d2 }, -- { 0x00000000, 0xc0401c00, 0x3d5 }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x614 }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x3fd }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3e2 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ea }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x3fd }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x3fd }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3e5 }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3e5 }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3e5 }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3e5 }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3e5 }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3e5 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0018f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x614 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x42e }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x43c }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x444 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x614 }, -- { 0x00000000, 0x00400000, 0x44d }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x449 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x44c }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x454 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x459 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x45e }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x463 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x468 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46d }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x46d }, -- { 0x00000000, 0x00400000, 0x47a }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x477 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x480 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x43c }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x48a }, -- { 0x00040000, 0xc0494a20, 0x48b }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x497 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x493 }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x491 }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4ae }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x4a9 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x4ac }, -- { 0x00000000, 0x00400000, 0x4b2 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x614 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4b9 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x614 }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4bb }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4eb }, -- { 0x00000035, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4da }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4ce }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000036, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x491 }, -- { 0x00000035, 0xc0203620, 0x000 }, -- { 0x00000036, 0xc0403620, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0xe0000000, 0xc0484a20, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4f2 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x4f6 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x50b }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0x00000034, 0x00203623, 0x000 }, -- { 0x00000032, 0x00203623, 0x000 }, -- { 0x00000031, 0x00203623, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x0000002d, 0x00203623, 0x000 }, -- { 0x0000002e, 0x00203623, 0x000 }, -- { 0x0000001b, 0x00203623, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x0000002a, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x0000002c, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000033, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000027, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000028, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x00000026, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x602 }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x541 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x614 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x549 }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x55b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x549 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x614 }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x55b }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x54d }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x55b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x559 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x554 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x557 }, -- { 0x00000000, 0x00401c10, 0x55b }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x55d }, -- { 0x00000000, 0x00600000, 0x5a4 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56d }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x614 }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x56b }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x57d }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x614 }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x57b }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x58d }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x614 }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x58b }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x614 }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x599 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x59f }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5a4 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x5b7 }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x00000034, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x5bb }, -- { 0x00000000, 0x00600000, 0x5a4 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5bb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x0000217a, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x5e1 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000016, 0x00604811, 0x35e }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x614 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x5dc }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x0000001d, 0x00803627, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x0000001d, 0x00803627, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x0000001d, 0x00803627, 0x000 }, -- { 0x0000001d, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x0000001d, 0x00803627, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000016, 0x00604811, 0x35e }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0x00ffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x614 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x613 }, -- { 0x00000010, 0x00404c11, 0x5f9 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x00000025, 0x00200a2d, 0x000 }, -- { 0x00000026, 0x00200e2d, 0x000 }, -- { 0x00000027, 0x0020122d, 0x000 }, -- { 0x00000028, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x612 }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x00000027, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x614 }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x617 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x2fe }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x19f }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000029, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x0000002c, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000002a, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000002b, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x013304ef, 0x059b0239, 0x000 }, -- { 0x01b00159, 0x0425059b, 0x000 }, -- { 0x021201f6, 0x02390142, 0x000 }, -- { 0x0210022e, 0x0289022a, 0x000 }, -- { 0x03c2059b, 0x059b059b, 0x000 }, -- { 0x05cd05ce, 0x0308059b, 0x000 }, -- { 0x059b05a0, 0x03090329, 0x000 }, -- { 0x0313026b, 0x032b031d, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b052c, 0x059b059b, 0x000 }, -- { 0x03a5059b, 0x04a2032d, 0x000 }, -- { 0x04810433, 0x0423059b, 0x000 }, -- { 0x04bb04ed, 0x042704c8, 0x000 }, -- { 0x043304f4, 0x033a0365, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b059b, 0x05b905a2, 0x000 }, -- { 0x059b059b, 0x0007059b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x03e303d8, 0x03f303f1, 0x000 }, -- { 0x03f903f5, 0x03f703fb, 0x000 }, -- { 0x04070403, 0x040f040b, 0x000 }, -- { 0x04170413, 0x041f041b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x059b059b, 0x059b059b, 0x000 }, -- { 0x00020600, 0x06190006, 0x000 }, --}; -- --static const u32 R600_pfp_microcode[] = { --0xd40071, --0xd40072, --0xca0400, --0xa00000, --0x7e828b, --0x800003, --0xca0400, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d4, --0xd5c01e, --0xca0800, --0x80001b, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000d, --0xc41838, --0xe4013e, --0xd4001e, --0x80000d, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800054, --0xd40073, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800002, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800002, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b9, --0xd4c01e, --0xc6083e, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800002, --0x062001, --0xc6083e, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x80007a, --0xd42013, --0xc6083e, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008e, --0x000000, --0xc41432, --0xc6183e, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800002, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xd40073, --0xe4015e, --0xd4001e, --0x8001b9, --0x062001, --0x0a2001, --0xd60074, --0xc40836, --0xc61040, --0x988007, --0xcc3835, --0x95010f, --0xd4001f, --0xd46062, --0x800002, --0xd42062, --0xcc1433, --0x8401bc, --0xd40070, --0xd5401e, --0x800002, --0xee001e, --0xca0c00, --0xca1000, --0xd4c01a, --0x8401bc, --0xd5001a, --0xcc0443, --0x35101f, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b9, --0xd4006d, --0x344401, --0xcc0c44, --0x98403a, --0xcc2c46, --0x958004, --0xcc0445, --0x8001b9, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f3, --0xcc1003, --0x98801b, --0x04380c, --0x8400f3, --0xcc1003, --0x988017, --0x043808, --0x8400f3, --0xcc1003, --0x988013, --0x043804, --0x8400f3, --0xcc1003, --0x988014, --0xcc1047, --0x9a8009, --0xcc1448, --0x9840da, --0xd4006d, --0xcc1844, --0xd5001a, --0xd5401a, --0x8000cc, --0xd5801a, --0x96c0d3, --0xd4006d, --0x8001b9, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800002, --0xec007f, --0x9ac0ca, --0xd4006d, --0x8001b9, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b9, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809c, --0xd4006d, --0x98409a, --0xd4006e, --0xcc0847, --0xcc0c48, --0xcc1044, --0xd4801a, --0xd4c01a, --0x800104, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d8, --0xca0c00, --0xd4401e, --0x800002, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800002, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bc, --0x000000, --0x8401bc, --0xd7806f, --0x800002, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902af, --0x7c738b, --0x8401bc, --0xd7806f, --0x800002, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984296, --0x000000, --0x800164, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800002, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc1049, --0x990004, --0xd40071, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800002, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x95001f, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x7d8380, --0xd5806f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0x8001b9, --0xd60074, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800002, --0xee001e, --0x800002, --0xee001f, --0xd4001f, --0x800002, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010174, --0x02017b, --0x030090, --0x040080, --0x050005, --0x060040, --0x070033, --0x08012f, --0x090047, --0x0a0037, --0x1001b7, --0x1700a4, --0x22013d, --0x23014c, --0x2000b5, --0x240128, --0x27004e, --0x28006b, --0x2a0061, --0x2b0053, --0x2f0066, --0x320088, --0x340182, --0x3c0159, --0x3f0073, --0x41018f, --0x440131, --0x550176, --0x56017d, --0x60000c, --0x610035, --0x620039, --0x630039, --0x640039, --0x650039, --0x660039, --0x670039, --0x68003b, --0x690042, --0x6a0049, --0x6b0049, --0x6c0049, --0x6d0049, --0x6e0049, --0x6f0049, --0x7301b7, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --0x000007, --}; -- --static const u32 RV610_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x668 }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x662 }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x668 }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x65f }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x34b }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x354 }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x364 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x36e }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5c0 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x370 }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x386 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b1 }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b5 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39c }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x390 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x392 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x39e }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3ae }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ce }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c0 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3d3 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e1 }, -- { 0x00000000, 0xc0401800, 0x3e4 }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x68d }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e7 }, -- { 0x00000000, 0xc0401c00, 0x3ea }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x68d }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3f7 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ff }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3fa }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3fa }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3fa }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3fa }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3fa }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3fa }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000018, 0x40210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x445 }, -- { 0x00800000, 0xc0494a20, 0x446 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x44b }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x459 }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x461 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x68d }, -- { 0x00000000, 0x00400000, 0x466 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x692 }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46d }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x472 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x477 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47c }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x481 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x486 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x490 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x499 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x459 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4a3 }, -- { 0x00040000, 0xc0494a20, 0x4a4 }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4b0 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4ac }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4aa }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c3 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x692 }, -- { 0x00000000, 0x00400000, 0x4c7 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x68d }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4ce }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4d0 }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x500 }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4ef }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4e3 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4aa }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x505 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x519 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x52e }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x67b }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x566 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56e }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x572 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x57a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x692 }, -- { 0x00000000, 0x00401c10, 0x57c }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x57e }, -- { 0x00000000, 0x00600000, 0x5c9 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x58f }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x58d }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5a0 }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x59e }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5b1 }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5af }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5be }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5c4 }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5c9 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000002c, 0x00203621, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5d0 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000030, 0x00403621, 0x5e3 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5e3 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a092, 0x00604411, 0x68d }, -- { 0x00000031, 0x00203630, 0x000 }, -- { 0x0004a093, 0x00604411, 0x68d }, -- { 0x00000032, 0x00203630, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68d }, -- { 0x00000033, 0x00203630, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68d }, -- { 0x00000034, 0x00203630, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68d }, -- { 0x00000035, 0x00203630, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68d }, -- { 0x00000036, 0x00203630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000001, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62c }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62c }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x605 }, -- { 0x0000a092, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x0000a093, 0x00204411, 0x000 }, -- { 0x00000032, 0x00204a2d, 0x000 }, -- { 0x0000a2b6, 0x00204411, 0x000 }, -- { 0x00000033, 0x00204a2d, 0x000 }, -- { 0x0000a2ba, 0x00204411, 0x000 }, -- { 0x00000034, 0x00204a2d, 0x000 }, -- { 0x0000a2be, 0x00204411, 0x000 }, -- { 0x00000035, 0x00204a2d, 0x000 }, -- { 0x0000a2c2, 0x00204411, 0x000 }, -- { 0x00000036, 0x00204a2d, 0x000 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x000001ff, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62b }, -- { 0x00000000, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x60e }, -- { 0x0004a003, 0x00604411, 0x68d }, -- { 0x0000a003, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x14c00000, 0x613 }, -- { 0x0004a010, 0x00604411, 0x68d }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62b }, -- { 0x0004a011, 0x00604411, 0x68d }, -- { 0x0000a011, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a012, 0x00604411, 0x68d }, -- { 0x0000a012, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a013, 0x00604411, 0x68d }, -- { 0x0000a013, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a014, 0x00604411, 0x68d }, -- { 0x0000a014, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a015, 0x00604411, 0x68d }, -- { 0x0000a015, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a016, 0x00604411, 0x68d }, -- { 0x0000a016, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a017, 0x00604411, 0x68d }, -- { 0x0000a017, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000002c, 0x0080062d, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x63d }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000002, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x63b }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x641 }, -- { 0x00000000, 0x00600000, 0x5c9 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x641 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x62d }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x62d }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x656 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000010, 0x00404c11, 0x672 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x68b }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68d }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x690 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x692 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x695 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x01420502, 0x05c00250, 0x000 }, -- { 0x01c30168, 0x043f05c0, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03d705c0, 0x05c005c0, 0x000 }, -- { 0x0649064a, 0x031f05c0, 0x000 }, -- { 0x05c005c5, 0x03200340, 0x000 }, -- { 0x032a0282, 0x03420334, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c00551, 0x05c005c0, 0x000 }, -- { 0x03ba05c0, 0x04bb0344, 0x000 }, -- { 0x049a0450, 0x043d05c0, 0x000 }, -- { 0x04d005c0, 0x044104dd, 0x000 }, -- { 0x04500507, 0x03510375, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x063f05c7, 0x000 }, -- { 0x05c005c0, 0x000705c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x03f803ed, 0x04080406, 0x000 }, -- { 0x040e040a, 0x040c0410, 0x000 }, -- { 0x041c0418, 0x04240420, 0x000 }, -- { 0x042c0428, 0x04340430, 0x000 }, -- { 0x05c005c0, 0x043805c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x00020679, 0x06970006, 0x000 }, --}; -- --static const u32 RV610_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001b8, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800053, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b8, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x800079, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008d, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401bb, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401bb, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b8, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001b8, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f0, --0xcc1003, --0x98801b, --0x04380c, --0x8400f0, --0xcc1003, --0x988017, --0x043808, --0x8400f0, --0xcc1003, --0x988013, --0x043804, --0x8400f0, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000c9, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001b8, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001b8, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b8, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800101, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d9, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bd, --0x000000, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902b0, --0x7c738b, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984297, --0x000000, --0x800161, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001b8, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010171, --0x020178, --0x03008f, --0x04007f, --0x050003, --0x06003f, --0x070032, --0x08012c, --0x090046, --0x0a0036, --0x1001b6, --0x1700a2, --0x22013a, --0x230149, --0x2000b4, --0x240125, --0x27004d, --0x28006a, --0x2a0060, --0x2b0052, --0x2f0065, --0x320087, --0x34017f, --0x3c0156, --0x3f0072, --0x41018c, --0x44012e, --0x550173, --0x56017a, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RV620_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x668 }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x662 }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00000000, 0x00600000, 0x631 }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x668 }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x65f }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x645 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x34b }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x354 }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x364 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x36e }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5c0 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x370 }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x386 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b1 }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b5 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39c }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x390 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x392 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x39e }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3ae }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ce }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c0 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3d3 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e1 }, -- { 0x00000000, 0xc0401800, 0x3e4 }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x68d }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e7 }, -- { 0x00000000, 0xc0401c00, 0x3ea }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x68d }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3f7 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ff }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3fa }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3fa }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3fa }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3fa }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3fa }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3fa }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000018, 0x40210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x445 }, -- { 0x00800000, 0xc0494a20, 0x446 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x44b }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x459 }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x461 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x68d }, -- { 0x00000000, 0x00400000, 0x466 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x692 }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46d }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x472 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x477 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47c }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x481 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x486 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x486 }, -- { 0x00000000, 0x00400000, 0x493 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x490 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x499 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x459 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4a3 }, -- { 0x00040000, 0xc0494a20, 0x4a4 }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4b0 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4ac }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4aa }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c3 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x692 }, -- { 0x00000000, 0x00400000, 0x4c7 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x68d }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4ce }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68d }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4d0 }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x500 }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4ef }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4e3 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4aa }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x505 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x519 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x52e }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x67b }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x566 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56e }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68d }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x572 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x57c }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x57a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x692 }, -- { 0x00000000, 0x00401c10, 0x57c }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x57e }, -- { 0x00000000, 0x00600000, 0x5c9 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x58f }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x58d }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5a0 }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x59e }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5b1 }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5af }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68d }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5be }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5c4 }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5c9 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000002c, 0x00203621, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5d0 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000030, 0x00403621, 0x5e3 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5e3 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a092, 0x00604411, 0x68d }, -- { 0x00000031, 0x00203630, 0x000 }, -- { 0x0004a093, 0x00604411, 0x68d }, -- { 0x00000032, 0x00203630, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68d }, -- { 0x00000033, 0x00203630, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68d }, -- { 0x00000034, 0x00203630, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68d }, -- { 0x00000035, 0x00203630, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68d }, -- { 0x00000036, 0x00203630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000001, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62c }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62c }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x605 }, -- { 0x0000a092, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x0000a093, 0x00204411, 0x000 }, -- { 0x00000032, 0x00204a2d, 0x000 }, -- { 0x0000a2b6, 0x00204411, 0x000 }, -- { 0x00000033, 0x00204a2d, 0x000 }, -- { 0x0000a2ba, 0x00204411, 0x000 }, -- { 0x00000034, 0x00204a2d, 0x000 }, -- { 0x0000a2be, 0x00204411, 0x000 }, -- { 0x00000035, 0x00204a2d, 0x000 }, -- { 0x0000a2c2, 0x00204411, 0x000 }, -- { 0x00000036, 0x00204a2d, 0x000 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x000001ff, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62b }, -- { 0x00000000, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x60e }, -- { 0x0004a003, 0x00604411, 0x68d }, -- { 0x0000a003, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x14c00000, 0x613 }, -- { 0x0004a010, 0x00604411, 0x68d }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62b }, -- { 0x0004a011, 0x00604411, 0x68d }, -- { 0x0000a011, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a012, 0x00604411, 0x68d }, -- { 0x0000a012, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a013, 0x00604411, 0x68d }, -- { 0x0000a013, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a014, 0x00604411, 0x68d }, -- { 0x0000a014, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a015, 0x00604411, 0x68d }, -- { 0x0000a015, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a016, 0x00604411, 0x68d }, -- { 0x0000a016, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a017, 0x00604411, 0x68d }, -- { 0x0000a017, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x0000002c, 0x0080062d, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x63d }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000002, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x63b }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68d }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x641 }, -- { 0x00000000, 0x00600000, 0x5c9 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x641 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x62d }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x62d }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x656 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68d }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x68c }, -- { 0x00000010, 0x00404c11, 0x672 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x68b }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68d }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x690 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x692 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x695 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x01420502, 0x05c00250, 0x000 }, -- { 0x01c30168, 0x043f05c0, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03d705c0, 0x05c005c0, 0x000 }, -- { 0x0649064a, 0x031f05c0, 0x000 }, -- { 0x05c005c5, 0x03200340, 0x000 }, -- { 0x032a0282, 0x03420334, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c00551, 0x05c005c0, 0x000 }, -- { 0x03ba05c0, 0x04bb0344, 0x000 }, -- { 0x049a0450, 0x043d05c0, 0x000 }, -- { 0x04d005c0, 0x044104dd, 0x000 }, -- { 0x04500507, 0x03510375, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x063f05c7, 0x000 }, -- { 0x05c005c0, 0x000705c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x03f803ed, 0x04080406, 0x000 }, -- { 0x040e040a, 0x040c0410, 0x000 }, -- { 0x041c0418, 0x04240420, 0x000 }, -- { 0x042c0428, 0x04340430, 0x000 }, -- { 0x05c005c0, 0x043805c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x05c005c0, 0x05c005c0, 0x000 }, -- { 0x00020679, 0x06970006, 0x000 }, --}; -- --static const u32 RV620_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001b8, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800053, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b8, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x800079, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008d, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401bb, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401bb, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b8, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001b8, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f0, --0xcc1003, --0x98801b, --0x04380c, --0x8400f0, --0xcc1003, --0x988017, --0x043808, --0x8400f0, --0xcc1003, --0x988013, --0x043804, --0x8400f0, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000c9, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001b8, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001b8, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b8, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800101, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d9, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bd, --0x000000, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902b0, --0x7c738b, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984297, --0x000000, --0x800161, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001b8, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010171, --0x020178, --0x03008f, --0x04007f, --0x050003, --0x06003f, --0x070032, --0x08012c, --0x090046, --0x0a0036, --0x1001b6, --0x1700a2, --0x22013a, --0x230149, --0x2000b4, --0x240125, --0x27004d, --0x28006a, --0x2a0060, --0x2b0052, --0x2f0065, --0x320087, --0x34017f, --0x3c0156, --0x3f0072, --0x41018c, --0x44012e, --0x550173, --0x56017a, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RV630_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x65f }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x662 }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x34b }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x354 }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x364 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x36e }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5bd }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x370 }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x386 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b1 }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b5 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39c }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x390 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x392 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x39e }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3ae }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ce }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c0 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3d3 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e1 }, -- { 0x00000000, 0xc0401800, 0x3e4 }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x68a }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e7 }, -- { 0x00000000, 0xc0401c00, 0x3ea }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x68a }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3f7 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ff }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3fa }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3fa }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3fa }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3fa }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3fa }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3fa }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x448 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x456 }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x45e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x68a }, -- { 0x00000000, 0x00400000, 0x463 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x68f }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46a }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46f }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x474 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x479 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47e }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x483 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x48d }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x496 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x456 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4a0 }, -- { 0x00040000, 0xc0494a20, 0x4a1 }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4ad }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4a9 }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4a7 }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c0 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x68f }, -- { 0x00000000, 0x00400000, 0x4c4 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x68a }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4cb }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4cd }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4fd }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4ec }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4e0 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4a7 }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x502 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x516 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x52b }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x678 }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x563 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56b }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56b }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56f }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x577 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x68f }, -- { 0x00000000, 0x00401c10, 0x579 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x57b }, -- { 0x00000000, 0x00600000, 0x5c6 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x58c }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x58a }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x59d }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x59b }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5ae }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5ac }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5bb }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5c1 }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5c6 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000002c, 0x00203621, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5cd }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000030, 0x00403621, 0x5e0 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5e0 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a092, 0x00604411, 0x68a }, -- { 0x00000031, 0x00203630, 0x000 }, -- { 0x0004a093, 0x00604411, 0x68a }, -- { 0x00000032, 0x00203630, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68a }, -- { 0x00000033, 0x00203630, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68a }, -- { 0x00000034, 0x00203630, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68a }, -- { 0x00000035, 0x00203630, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68a }, -- { 0x00000036, 0x00203630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000001, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x629 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x629 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x602 }, -- { 0x0000a092, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x0000a093, 0x00204411, 0x000 }, -- { 0x00000032, 0x00204a2d, 0x000 }, -- { 0x0000a2b6, 0x00204411, 0x000 }, -- { 0x00000033, 0x00204a2d, 0x000 }, -- { 0x0000a2ba, 0x00204411, 0x000 }, -- { 0x00000034, 0x00204a2d, 0x000 }, -- { 0x0000a2be, 0x00204411, 0x000 }, -- { 0x00000035, 0x00204a2d, 0x000 }, -- { 0x0000a2c2, 0x00204411, 0x000 }, -- { 0x00000036, 0x00204a2d, 0x000 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x000001ff, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x628 }, -- { 0x00000000, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x60b }, -- { 0x0004a003, 0x00604411, 0x68a }, -- { 0x0000a003, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x14c00000, 0x610 }, -- { 0x0004a010, 0x00604411, 0x68a }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x628 }, -- { 0x0004a011, 0x00604411, 0x68a }, -- { 0x0000a011, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a012, 0x00604411, 0x68a }, -- { 0x0000a012, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a013, 0x00604411, 0x68a }, -- { 0x0000a013, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a014, 0x00604411, 0x68a }, -- { 0x0000a014, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a015, 0x00604411, 0x68a }, -- { 0x0000a015, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a016, 0x00604411, 0x68a }, -- { 0x0000a016, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a017, 0x00604411, 0x68a }, -- { 0x0000a017, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000002c, 0x0080062d, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x63a }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000002, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x638 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x63e }, -- { 0x00000000, 0x00600000, 0x5c6 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x63e }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x62a }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x62a }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x653 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000010, 0x00404c11, 0x66f }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x688 }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68a }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x68d }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68f }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x692 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x014204ff, 0x05bd0250, 0x000 }, -- { 0x01c30168, 0x043f05bd, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03d705bd, 0x05bd05bd, 0x000 }, -- { 0x06460647, 0x031f05bd, 0x000 }, -- { 0x05bd05c2, 0x03200340, 0x000 }, -- { 0x032a0282, 0x03420334, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd054e, 0x05bd05bd, 0x000 }, -- { 0x03ba05bd, 0x04b80344, 0x000 }, -- { 0x0497044d, 0x043d05bd, 0x000 }, -- { 0x04cd05bd, 0x044104da, 0x000 }, -- { 0x044d0504, 0x03510375, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x063c05c4, 0x000 }, -- { 0x05bd05bd, 0x000705bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x03f803ed, 0x04080406, 0x000 }, -- { 0x040e040a, 0x040c0410, 0x000 }, -- { 0x041c0418, 0x04240420, 0x000 }, -- { 0x042c0428, 0x04340430, 0x000 }, -- { 0x05bd05bd, 0x043805bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x00020676, 0x06940006, 0x000 }, --}; -- --static const u32 RV630_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001b8, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800053, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b8, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x800079, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008d, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401bb, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401bb, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b8, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001b8, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f0, --0xcc1003, --0x98801b, --0x04380c, --0x8400f0, --0xcc1003, --0x988017, --0x043808, --0x8400f0, --0xcc1003, --0x988013, --0x043804, --0x8400f0, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000c9, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001b8, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001b8, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b8, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800101, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d9, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bd, --0x000000, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902b0, --0x7c738b, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984297, --0x000000, --0x800161, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001b8, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010171, --0x020178, --0x03008f, --0x04007f, --0x050003, --0x06003f, --0x070032, --0x08012c, --0x090046, --0x0a0036, --0x1001b6, --0x1700a2, --0x22013a, --0x230149, --0x2000b4, --0x240125, --0x27004d, --0x28006a, --0x2a0060, --0x2b0052, --0x2f0065, --0x320087, --0x34017f, --0x3c0156, --0x3f0072, --0x41018c, --0x44012e, --0x550173, --0x56017a, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RV635_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x65f }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x662 }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00000000, 0x00600000, 0x62e }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x665 }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x65c }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x642 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x34b }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x354 }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x364 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x36e }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5bd }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35f }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x370 }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x386 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b1 }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b5 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x39c }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a8 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x390 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x392 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x39e }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3ae }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ce }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c0 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3d3 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e1 }, -- { 0x00000000, 0xc0401800, 0x3e4 }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x68a }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e7 }, -- { 0x00000000, 0xc0401c00, 0x3ea }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x68a }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3f7 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ff }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3fa }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3fa }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3fa }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3fa }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3fa }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3fa }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x448 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x456 }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x45e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x68a }, -- { 0x00000000, 0x00400000, 0x463 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x68f }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46a }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46f }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x474 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x479 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47e }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x483 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x483 }, -- { 0x00000000, 0x00400000, 0x490 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x48d }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x496 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x456 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4a0 }, -- { 0x00040000, 0xc0494a20, 0x4a1 }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4ad }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4a9 }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4a7 }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c0 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x68f }, -- { 0x00000000, 0x00400000, 0x4c4 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x68a }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4cb }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x68a }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4cd }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4fd }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4ec }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4e0 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4a7 }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x502 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x516 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x52b }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x678 }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x563 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56b }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56b }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x68a }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56f }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x579 }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x577 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x68f }, -- { 0x00000000, 0x00401c10, 0x579 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x57b }, -- { 0x00000000, 0x00600000, 0x5c6 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x58c }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x58a }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x59d }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x59b }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5ae }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5ac }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68a }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5bb }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5c1 }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5c6 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000002c, 0x00203621, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5cd }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000030, 0x00403621, 0x5e0 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5e0 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a092, 0x00604411, 0x68a }, -- { 0x00000031, 0x00203630, 0x000 }, -- { 0x0004a093, 0x00604411, 0x68a }, -- { 0x00000032, 0x00203630, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x68a }, -- { 0x00000033, 0x00203630, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x68a }, -- { 0x00000034, 0x00203630, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x68a }, -- { 0x00000035, 0x00203630, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x68a }, -- { 0x00000036, 0x00203630, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000001, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x629 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x629 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x602 }, -- { 0x0000a092, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x0000a093, 0x00204411, 0x000 }, -- { 0x00000032, 0x00204a2d, 0x000 }, -- { 0x0000a2b6, 0x00204411, 0x000 }, -- { 0x00000033, 0x00204a2d, 0x000 }, -- { 0x0000a2ba, 0x00204411, 0x000 }, -- { 0x00000034, 0x00204a2d, 0x000 }, -- { 0x0000a2be, 0x00204411, 0x000 }, -- { 0x00000035, 0x00204a2d, 0x000 }, -- { 0x0000a2c2, 0x00204411, 0x000 }, -- { 0x00000036, 0x00204a2d, 0x000 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x000001ff, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x628 }, -- { 0x00000000, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x60b }, -- { 0x0004a003, 0x00604411, 0x68a }, -- { 0x0000a003, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x14c00000, 0x610 }, -- { 0x0004a010, 0x00604411, 0x68a }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x628 }, -- { 0x0004a011, 0x00604411, 0x68a }, -- { 0x0000a011, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a012, 0x00604411, 0x68a }, -- { 0x0000a012, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a013, 0x00604411, 0x68a }, -- { 0x0000a013, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a014, 0x00604411, 0x68a }, -- { 0x0000a014, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a015, 0x00604411, 0x68a }, -- { 0x0000a015, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a016, 0x00604411, 0x68a }, -- { 0x0000a016, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a017, 0x00604411, 0x68a }, -- { 0x0000a017, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x0000002c, 0x0080062d, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x63a }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000002, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x638 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x68a }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x63e }, -- { 0x00000000, 0x00600000, 0x5c6 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x63e }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x62a }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x62a }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x653 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36e }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x68a }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x689 }, -- { 0x00000010, 0x00404c11, 0x66f }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x688 }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68a }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x68d }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x68f }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x692 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x014204ff, 0x05bd0250, 0x000 }, -- { 0x01c30168, 0x043f05bd, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03d705bd, 0x05bd05bd, 0x000 }, -- { 0x06460647, 0x031f05bd, 0x000 }, -- { 0x05bd05c2, 0x03200340, 0x000 }, -- { 0x032a0282, 0x03420334, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd054e, 0x05bd05bd, 0x000 }, -- { 0x03ba05bd, 0x04b80344, 0x000 }, -- { 0x0497044d, 0x043d05bd, 0x000 }, -- { 0x04cd05bd, 0x044104da, 0x000 }, -- { 0x044d0504, 0x03510375, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x063c05c4, 0x000 }, -- { 0x05bd05bd, 0x000705bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x03f803ed, 0x04080406, 0x000 }, -- { 0x040e040a, 0x040c0410, 0x000 }, -- { 0x041c0418, 0x04240420, 0x000 }, -- { 0x042c0428, 0x04340430, 0x000 }, -- { 0x05bd05bd, 0x043805bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x05bd05bd, 0x05bd05bd, 0x000 }, -- { 0x00020676, 0x06940006, 0x000 }, --}; -- --static const u32 RV635_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001b8, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800053, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b8, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x800079, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008d, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401bb, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401bb, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b8, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001b8, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f0, --0xcc1003, --0x98801b, --0x04380c, --0x8400f0, --0xcc1003, --0x988017, --0x043808, --0x8400f0, --0xcc1003, --0x988013, --0x043804, --0x8400f0, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000c9, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001b8, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001b8, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b8, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800101, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d9, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bd, --0x000000, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902b0, --0x7c738b, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984297, --0x000000, --0x800161, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001b8, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010171, --0x020178, --0x03008f, --0x04007f, --0x050003, --0x06003f, --0x070032, --0x08012c, --0x090046, --0x0a0036, --0x1001b6, --0x1700a2, --0x22013a, --0x230149, --0x2000b4, --0x240125, --0x27004d, --0x28006a, --0x2a0060, --0x2b0052, --0x2f0065, --0x320087, --0x34017f, --0x3c0156, --0x3f0072, --0x41018c, --0x44012e, --0x550173, --0x56017a, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RV670_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x00000000, 0x00600000, 0x624 }, -- { 0x00000000, 0x00600000, 0x638 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00000000, 0x00600000, 0x64d }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x653 }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x656 }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x67c }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x67b }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x67b }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x638 }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x624 }, -- { 0x00000000, 0x00600000, 0x638 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x624 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x00000000, 0x00600000, 0x624 }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x659 }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x650 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x638 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x34b }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x354 }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x362 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x36a }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x366 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35d }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5b3 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x35d }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36c }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x382 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3ad }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3af }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x398 }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a4 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a4 }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x38c }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x38e }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x39a }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3aa }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36a }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c4 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3b8 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3c9 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x67c }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3d7 }, -- { 0x00000000, 0xc0401800, 0x3da }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x67c }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3dd }, -- { 0x00000000, 0xc0401c00, 0x3e0 }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x67c }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x408 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3ed }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3f5 }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x408 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x408 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3f0 }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3f0 }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3f0 }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3f0 }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3f0 }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3f0 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x67c }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x43e }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x44c }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x454 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x67c }, -- { 0x00000000, 0x00400000, 0x459 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x681 }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x460 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x465 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46a }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x46f }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x474 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x479 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x479 }, -- { 0x00000000, 0x00400000, 0x486 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x483 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x48c }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x44c }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x496 }, -- { 0x00040000, 0xc0494a20, 0x497 }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4a3 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x49f }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x49d }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4b6 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x681 }, -- { 0x00000000, 0x00400000, 0x4ba }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x67c }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c1 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x67c }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4c3 }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4f3 }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4e2 }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4d6 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x49d }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4f8 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x50c }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x521 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x66a }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x559 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x67c }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x561 }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x56f }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x561 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x67c }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x56f }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x565 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x56f }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x56d }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x681 }, -- { 0x00000000, 0x00401c10, 0x56f }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x571 }, -- { 0x00000000, 0x00600000, 0x5bc }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x582 }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x67c }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x580 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x593 }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x67c }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x591 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5a4 }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x67c }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5a2 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x67c }, -- { 0x0000001a, 0x00212230, 0x000 }, -- { 0x00000006, 0x00222630, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5b1 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5b7 }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5bc }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000002c, 0x00203621, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5c3 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000030, 0x00403621, 0x5d6 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5d6 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004a092, 0x00604411, 0x67c }, -- { 0x00000031, 0x00203630, 0x000 }, -- { 0x0004a093, 0x00604411, 0x67c }, -- { 0x00000032, 0x00203630, 0x000 }, -- { 0x0004a2b6, 0x00604411, 0x67c }, -- { 0x00000033, 0x00203630, 0x000 }, -- { 0x0004a2ba, 0x00604411, 0x67c }, -- { 0x00000034, 0x00203630, 0x000 }, -- { 0x0004a2be, 0x00604411, 0x67c }, -- { 0x00000035, 0x00203630, 0x000 }, -- { 0x0004a2c2, 0x00604411, 0x67c }, -- { 0x00000036, 0x00203630, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000001, 0x002f0230, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x61f }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x61f }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00007e00, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x5f8 }, -- { 0x0000a092, 0x00204411, 0x000 }, -- { 0x00000031, 0x00204a2d, 0x000 }, -- { 0x0000a093, 0x00204411, 0x000 }, -- { 0x00000032, 0x00204a2d, 0x000 }, -- { 0x0000a2b6, 0x00204411, 0x000 }, -- { 0x00000033, 0x00204a2d, 0x000 }, -- { 0x0000a2ba, 0x00204411, 0x000 }, -- { 0x00000034, 0x00204a2d, 0x000 }, -- { 0x0000a2be, 0x00204411, 0x000 }, -- { 0x00000035, 0x00204a2d, 0x000 }, -- { 0x0000a2c2, 0x00204411, 0x000 }, -- { 0x00000036, 0x00204a2d, 0x000 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x000001ff, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x61e }, -- { 0x00000000, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x601 }, -- { 0x0004a003, 0x00604411, 0x67c }, -- { 0x0000a003, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x14c00000, 0x606 }, -- { 0x0004a010, 0x00604411, 0x67c }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00000001, 0x00210621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x61e }, -- { 0x0004a011, 0x00604411, 0x67c }, -- { 0x0000a011, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a012, 0x00604411, 0x67c }, -- { 0x0000a012, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a013, 0x00604411, 0x67c }, -- { 0x0000a013, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a014, 0x00604411, 0x67c }, -- { 0x0000a014, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a015, 0x00604411, 0x67c }, -- { 0x0000a015, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a016, 0x00604411, 0x67c }, -- { 0x0000a016, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x0004a017, 0x00604411, 0x67c }, -- { 0x0000a017, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x0000002c, 0x0080062d, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x630 }, -- { 0x00000030, 0x0020062d, 0x000 }, -- { 0x00000002, 0x00280621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x62e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x67c }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x634 }, -- { 0x00000000, 0x00600000, 0x5bc }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x634 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x620 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x620 }, -- { 0x00000000, 0x00600000, 0x64d }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x67c }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x647 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x36a }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x67c }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x67b }, -- { 0x00000010, 0x00404c11, 0x661 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x67a }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x67c }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x67f }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x681 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x684 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x014204f5, 0x05b30250, 0x000 }, -- { 0x01c30168, 0x043505b3, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03cd05b3, 0x05b305b3, 0x000 }, -- { 0x063c063d, 0x031f05b3, 0x000 }, -- { 0x05b305b8, 0x03200340, 0x000 }, -- { 0x032a0282, 0x03420334, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x05b30544, 0x05b305b3, 0x000 }, -- { 0x03b205b3, 0x04ae0344, 0x000 }, -- { 0x048d0443, 0x043305b3, 0x000 }, -- { 0x04c305b3, 0x043704d0, 0x000 }, -- { 0x044304fa, 0x03510371, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x05b305b3, 0x063205ba, 0x000 }, -- { 0x05b305b3, 0x000705b3, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x03ee03e3, 0x03fe03fc, 0x000 }, -- { 0x04040400, 0x04020406, 0x000 }, -- { 0x0412040e, 0x041a0416, 0x000 }, -- { 0x0422041e, 0x042a0426, 0x000 }, -- { 0x05b305b3, 0x042e05b3, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x05b305b3, 0x05b305b3, 0x000 }, -- { 0x00020668, 0x06860006, 0x000 }, --}; -- --static const u32 RV670_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001b8, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581a8, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0fff0, --0x042c04, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255403, --0x7cd580, --0x259c03, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca1800, --0xd4401e, --0xd5801e, --0x800053, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xd48060, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001b8, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x800079, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x80008d, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401bb, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401bb, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001b8, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001b8, --0xd4001a, --0xd4c01a, --0x282801, --0x8400f0, --0xcc1003, --0x98801b, --0x04380c, --0x8400f0, --0xcc1003, --0x988017, --0x043808, --0x8400f0, --0xcc1003, --0x988013, --0x043804, --0x8400f0, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000c9, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001b8, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001b8, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001b8, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800101, --0xd5001a, --0xcc0832, --0xd40032, --0x9482d9, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x9882bd, --0x000000, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x9902b0, --0x7c738b, --0x8401bb, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984297, --0x000000, --0x800161, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001b8, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010171, --0x020178, --0x03008f, --0x04007f, --0x050003, --0x06003f, --0x070032, --0x08012c, --0x090046, --0x0a0036, --0x1001b6, --0x1700a2, --0x22013a, --0x230149, --0x2000b4, --0x240125, --0x27004d, --0x28006a, --0x2a0060, --0x2b0052, --0x2f0065, --0x320087, --0x34017f, --0x3c0156, --0x3f0072, --0x41018c, --0x44012e, --0x550173, --0x56017a, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RS780_cp_microcode[][3] = { -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0000ffff, 0x00284621, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000000, 0x00e00000, 0x000 }, -- { 0x00010000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x622 }, -- { 0x00000000, 0x00600000, 0x5d1 }, -- { 0x00000000, 0x00600000, 0x5de }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000f00, 0x00281622, 0x000 }, -- { 0x00000008, 0x00211625, 0x000 }, -- { 0x00000018, 0x00203625, 0x000 }, -- { 0x8d000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x002f0225, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x018 }, -- { 0x00412000, 0x00404811, 0x019 }, -- { 0x00422000, 0x00204811, 0x000 }, -- { 0x8e000000, 0x00204411, 0x000 }, -- { 0x00000028, 0x00204a2d, 0x000 }, -- { 0x90000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x0000000c, 0x00211622, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000019, 0x00211a22, 0x000 }, -- { 0x00000004, 0x00281a26, 0x000 }, -- { 0x00000000, 0x002914c5, 0x000 }, -- { 0x00000019, 0x00203625, 0x000 }, -- { 0x00000000, 0x003a1402, 0x000 }, -- { 0x00000016, 0x00211625, 0x000 }, -- { 0x00000003, 0x00281625, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0xfffffffc, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002914a3, 0x000 }, -- { 0x00000017, 0x00203625, 0x000 }, -- { 0x00008000, 0x00280e22, 0x000 }, -- { 0x00000007, 0x00220e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x20000000, 0x00280e22, 0x000 }, -- { 0x00000006, 0x00210e23, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x00000000, 0x00220222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x038 }, -- { 0x00000000, 0x2ee00000, 0x035 }, -- { 0x00000000, 0x2ce00000, 0x037 }, -- { 0x00000000, 0x00400e2d, 0x039 }, -- { 0x00000008, 0x00200e2d, 0x000 }, -- { 0x00000009, 0x0040122d, 0x046 }, -- { 0x00000001, 0x00400e2d, 0x039 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x03e }, -- { 0x00000008, 0x00401c11, 0x041 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x0000000f, 0x00281e27, 0x000 }, -- { 0x00000003, 0x00221e27, 0x000 }, -- { 0x7fc00000, 0x00281a23, 0x000 }, -- { 0x00000014, 0x00211a26, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000008, 0x00221a26, 0x000 }, -- { 0x00000000, 0x00290cc7, 0x000 }, -- { 0x00000027, 0x00203624, 0x000 }, -- { 0x00007f00, 0x00281221, 0x000 }, -- { 0x00001400, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x04b }, -- { 0x00000001, 0x00290e23, 0x000 }, -- { 0x0000000e, 0x00203623, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfff80000, 0x00294a23, 0x000 }, -- { 0x00000000, 0x003a2c02, 0x000 }, -- { 0x00000002, 0x00220e2b, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x0000000f, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00204a2d, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000029, 0x00200e2d, 0x000 }, -- { 0x060a0200, 0x00294a23, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14e00000, 0x061 }, -- { 0x00000000, 0x2ee00000, 0x05f }, -- { 0x00000000, 0x2ce00000, 0x05e }, -- { 0x00000000, 0x00400e2d, 0x062 }, -- { 0x00000001, 0x00400e2d, 0x062 }, -- { 0x0000000a, 0x00200e2d, 0x000 }, -- { 0x0000000b, 0x0040122d, 0x06a }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x003ffffc, 0x00281223, 0x000 }, -- { 0x00000002, 0x00221224, 0x000 }, -- { 0x7fc00000, 0x00281623, 0x000 }, -- { 0x00000014, 0x00211625, 0x000 }, -- { 0x00000001, 0x00331625, 0x000 }, -- { 0x80000000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00290ca3, 0x000 }, -- { 0x3ffffc00, 0x00290e23, 0x000 }, -- { 0x0000001f, 0x00211e23, 0x000 }, -- { 0x00000000, 0x14e00000, 0x06d }, -- { 0x00000100, 0x00401c11, 0x070 }, -- { 0x0000000d, 0x00201e2d, 0x000 }, -- { 0x000000f0, 0x00281e27, 0x000 }, -- { 0x00000004, 0x00221e27, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0xfffff0ff, 0x00281a30, 0x000 }, -- { 0x0000a028, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948e6, 0x000 }, -- { 0x0000a018, 0x00204411, 0x000 }, -- { 0x3fffffff, 0x00284a23, 0x000 }, -- { 0x0000a010, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000030, 0x0020162d, 0x000 }, -- { 0x00000002, 0x00291625, 0x000 }, -- { 0x00000030, 0x00203625, 0x000 }, -- { 0x00000025, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a3, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x083 }, -- { 0x00000026, 0x0020162d, 0x000 }, -- { 0x00000000, 0x002f00a4, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x084 }, -- { 0x00000000, 0x00400000, 0x08a }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203624, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x08a }, -- { 0x00000000, 0x00600000, 0x5ff }, -- { 0x00000000, 0x00600000, 0x5f3 }, -- { 0x00000002, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x08d }, -- { 0x00000012, 0xc0403620, 0x093 }, -- { 0x00000000, 0x2ee00000, 0x091 }, -- { 0x00000000, 0x2ce00000, 0x090 }, -- { 0x00000002, 0x00400e2d, 0x092 }, -- { 0x00000003, 0x00400e2d, 0x092 }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000012, 0x00203623, 0x000 }, -- { 0x00000003, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x098 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x0a0 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x2ee00000, 0x09e }, -- { 0x00000000, 0x2ce00000, 0x09d }, -- { 0x00000002, 0x00400e2d, 0x09f }, -- { 0x00000003, 0x00400e2d, 0x09f }, -- { 0x0000000c, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x003f0000, 0x00280e23, 0x000 }, -- { 0x00000010, 0x00210e23, 0x000 }, -- { 0x00000011, 0x00203623, 0x000 }, -- { 0x0000001e, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0a7 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x0000001f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0aa }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000008, 0x00210e2b, 0x000 }, -- { 0x0000007f, 0x00280e23, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0e1 }, -- { 0x00000000, 0x27000000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x0b3 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000000c, 0x00221e30, 0x000 }, -- { 0x99800000, 0x00204411, 0x000 }, -- { 0x00000004, 0x0020122d, 0x000 }, -- { 0x00000008, 0x00221224, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00291ce4, 0x000 }, -- { 0x00000000, 0x00604807, 0x12f }, -- { 0x9b000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x9c000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x0033146f, 0x000 }, -- { 0x00000001, 0x00333e23, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0x00203c05, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e007, 0x00204411, 0x000 }, -- { 0x0000000f, 0x0021022b, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0cb }, -- { 0x00f8ff08, 0x00204811, 0x000 }, -- { 0x98000000, 0x00404811, 0x0dc }, -- { 0x000000f0, 0x00280e22, 0x000 }, -- { 0x000000a0, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x0da }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d5 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0d4 }, -- { 0x00003f00, 0x00400c11, 0x0d6 }, -- { 0x00001f00, 0x00400c11, 0x0d6 }, -- { 0x00000f00, 0x00200c11, 0x000 }, -- { 0x00380009, 0x00294a23, 0x000 }, -- { 0x3f000000, 0x00280e2b, 0x000 }, -- { 0x00000002, 0x00220e23, 0x000 }, -- { 0x00000007, 0x00494a23, 0x0dc }, -- { 0x00380f09, 0x00204811, 0x000 }, -- { 0x68000007, 0x00204811, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000a202, 0x00204411, 0x000 }, -- { 0x00ff0000, 0x00280e22, 0x000 }, -- { 0x00000080, 0x00294a23, 0x000 }, -- { 0x00000027, 0x00200e2d, 0x000 }, -- { 0x00000026, 0x0020122d, 0x000 }, -- { 0x00000000, 0x002f0083, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x0ea }, -- { 0x00000000, 0x00600000, 0x5f9 }, -- { 0x00000000, 0x00400000, 0x0eb }, -- { 0x00000000, 0x00600000, 0x5fc }, -- { 0x00000007, 0x0020222d, 0x000 }, -- { 0x00000005, 0x00220e22, 0x000 }, -- { 0x00100000, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000000, 0x003a0c02, 0x000 }, -- { 0x000000ef, 0x00280e23, 0x000 }, -- { 0x00000000, 0x00292068, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000003, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x0f8 }, -- { 0x0000000b, 0x00210228, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0f8 }, -- { 0x00000400, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000001c, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x0fd }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000001e, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x10b }, -- { 0x0000a30f, 0x00204411, 0x000 }, -- { 0x00000011, 0x00200e2d, 0x000 }, -- { 0x00000001, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x104 }, -- { 0xffffffff, 0x00404811, 0x10b }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x107 }, -- { 0x0000ffff, 0x00404811, 0x10b }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x10a }, -- { 0x000000ff, 0x00404811, 0x10b }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0002c400, 0x00204411, 0x000 }, -- { 0x0000001f, 0x00210e22, 0x000 }, -- { 0x00000000, 0x14c00000, 0x112 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000018, 0x40224a20, 0x000 }, -- { 0x00000010, 0xc0424a20, 0x114 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x00000013, 0x00203623, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000000a, 0x00201011, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x11b }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00531224, 0x117 }, -- { 0xffbfffff, 0x00283a2e, 0x000 }, -- { 0x0000001b, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x12e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000d, 0x00204811, 0x000 }, -- { 0x00000018, 0x00220e30, 0x000 }, -- { 0xfc000000, 0x00280e23, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x00000000, 0x00201010, 0x000 }, -- { 0x0000e00e, 0x00204411, 0x000 }, -- { 0x07f8ff08, 0x00204811, 0x000 }, -- { 0x00000000, 0x00294a23, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a24, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00800000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204806, 0x000 }, -- { 0x00000008, 0x00214a27, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x622 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x621 }, -- { 0x00000004, 0x00404c11, 0x135 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000001c, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x13c }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40280620, 0x000 }, -- { 0x00000010, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x00341461, 0x000 }, -- { 0x00000000, 0x00741882, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x147 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x160 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0681a20, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x158 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000001, 0x00300a2f, 0x000 }, -- { 0x00000001, 0x00210a22, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600000, 0x18f }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00202c08, 0x000 }, -- { 0x00000000, 0x00202411, 0x000 }, -- { 0x00000000, 0x00202811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00221e29, 0x000 }, -- { 0x00000000, 0x007048eb, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000001, 0x40330620, 0x000 }, -- { 0x00000000, 0xc0302409, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x181 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x186 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x186 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000001, 0x00530621, 0x182 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0604800, 0x197 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000011, 0x0020062d, 0x000 }, -- { 0x00000000, 0x0078042a, 0x2fb }, -- { 0x00000000, 0x00202809, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x174 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x194 }, -- { 0x00000015, 0xc0203620, 0x000 }, -- { 0x00000016, 0xc0203620, 0x000 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x46000000, 0x00600811, 0x1b2 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x19b }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00804811, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000ffff, 0x40281620, 0x000 }, -- { 0x00000010, 0xc0811a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x00000008, 0x00221e30, 0x000 }, -- { 0x00000029, 0x00201a2d, 0x000 }, -- { 0x0000e000, 0x00204411, 0x000 }, -- { 0xfffbff09, 0x00204811, 0x000 }, -- { 0x0000000f, 0x0020222d, 0x000 }, -- { 0x00001fff, 0x00294a28, 0x000 }, -- { 0x00000006, 0x0020222d, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000100, 0x00201811, 0x000 }, -- { 0x00000008, 0x00621e28, 0x12f }, -- { 0x00000008, 0x00822228, 0x000 }, -- { 0x0002c000, 0x00204411, 0x000 }, -- { 0x00000015, 0x00600e2d, 0x1bd }, -- { 0x00000016, 0x00600e2d, 0x1bd }, -- { 0x0000c008, 0x00204411, 0x000 }, -- { 0x00000017, 0x00200e2d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x1b9 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x39000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00804802, 0x000 }, -- { 0x00000018, 0x00202e2d, 0x000 }, -- { 0x00000000, 0x003b0d63, 0x000 }, -- { 0x00000008, 0x00224a23, 0x000 }, -- { 0x00000010, 0x00224a23, 0x000 }, -- { 0x00000018, 0x00224a23, 0x000 }, -- { 0x00000000, 0x00804803, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00000007, 0x0021062f, 0x000 }, -- { 0x00000013, 0x00200a2d, 0x000 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000ffff, 0x40282220, 0x000 }, -- { 0x0000000f, 0x00262228, 0x000 }, -- { 0x00000010, 0x40212620, 0x000 }, -- { 0x0000000f, 0x00262629, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1e0 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000081, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000080, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1dc }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1d8 }, -- { 0x00000001, 0x00202c11, 0x000 }, -- { 0x0000001f, 0x00280a22, 0x000 }, -- { 0x0000001f, 0x00282a2a, 0x000 }, -- { 0x00000001, 0x00530621, 0x1d1 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000002, 0x00304a2f, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000001, 0x00301e2f, 0x000 }, -- { 0x00000000, 0x002f0227, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00600000, 0x1e9 }, -- { 0x00000001, 0x00531e27, 0x1e5 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x0000000f, 0x00260e23, 0x000 }, -- { 0x00000010, 0xc0211220, 0x000 }, -- { 0x0000000f, 0x00261224, 0x000 }, -- { 0x00000000, 0x00201411, 0x000 }, -- { 0x00000000, 0x00601811, 0x2bb }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022b, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x1f8 }, -- { 0x00000010, 0x00221628, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a29, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x0020480a, 0x000 }, -- { 0x00000000, 0x00202c11, 0x000 }, -- { 0x00000010, 0x00221623, 0x000 }, -- { 0xffff0000, 0x00281625, 0x000 }, -- { 0x0000ffff, 0x00281a24, 0x000 }, -- { 0x00000000, 0x002948c5, 0x000 }, -- { 0x00000000, 0x00731503, 0x205 }, -- { 0x00000000, 0x00201805, 0x000 }, -- { 0x00000000, 0x00731524, 0x205 }, -- { 0x00000000, 0x002d14c5, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00202802, 0x000 }, -- { 0x00000000, 0x00202003, 0x000 }, -- { 0x00000000, 0x00802404, 0x000 }, -- { 0x0000000f, 0x00210225, 0x000 }, -- { 0x00000000, 0x14c00000, 0x621 }, -- { 0x00000000, 0x002b1405, 0x000 }, -- { 0x00000001, 0x00901625, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001a, 0x00294a22, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a21, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000ffff, 0x40281220, 0x000 }, -- { 0x00000010, 0xc0211a20, 0x000 }, -- { 0x0000ffff, 0x40280e20, 0x000 }, -- { 0x00000010, 0xc0211620, 0x000 }, -- { 0x00000000, 0x00741465, 0x2bb }, -- { 0x0001a1fd, 0x00604411, 0x2e0 }, -- { 0x00000001, 0x00330621, 0x000 }, -- { 0x00000000, 0x002f0221, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x219 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x212 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x5de }, -- { 0x00000000, 0x0040040f, 0x213 }, -- { 0x00000000, 0x00600000, 0x5d1 }, -- { 0x00000000, 0x00600000, 0x5de }, -- { 0x00000210, 0x00600411, 0x315 }, -- { 0x00000000, 0x00600000, 0x1a0 }, -- { 0x00000000, 0x00600000, 0x19c }, -- { 0x00000000, 0x00600000, 0x2bb }, -- { 0x00000000, 0x00600000, 0x2a3 }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204808, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x232 }, -- { 0x00000000, 0x00600000, 0x13a }, -- { 0x00000000, 0x00400000, 0x236 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x236 }, -- { 0x00000000, 0xc0404800, 0x233 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x00600411, 0x2fb }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000000, 0x00600000, 0x5d1 }, -- { 0x0000a00c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000018, 0x40210a20, 0x000 }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x24c }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x00080101, 0x00292228, 0x000 }, -- { 0x00000014, 0x00203628, 0x000 }, -- { 0x0000a30c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x251 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000010, 0x00600411, 0x315 }, -- { 0x3f800000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00000000, 0x00600000, 0x27c }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000001, 0x00211e27, 0x000 }, -- { 0x00000000, 0x14e00000, 0x26a }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x0000ffff, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00341c27, 0x000 }, -- { 0x00000000, 0x12c00000, 0x25f }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e5, 0x000 }, -- { 0x00000000, 0x08c00000, 0x262 }, -- { 0x00000000, 0x00201407, 0x000 }, -- { 0x00000012, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00211e27, 0x000 }, -- { 0x00000000, 0x00341c47, 0x000 }, -- { 0x00000000, 0x12c00000, 0x267 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x08c00000, 0x26a }, -- { 0x00000000, 0x00201807, 0x000 }, -- { 0x00000000, 0x00600000, 0x2c1 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x00000000, 0x00342023, 0x000 }, -- { 0x00000000, 0x12c00000, 0x272 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x271 }, -- { 0x00000016, 0x00404811, 0x276 }, -- { 0x00000018, 0x00404811, 0x276 }, -- { 0x00000000, 0x00342044, 0x000 }, -- { 0x00000000, 0x12c00000, 0x275 }, -- { 0x00000017, 0x00404811, 0x276 }, -- { 0x00000019, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0x00604411, 0x2e9 }, -- { 0x00003fff, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x256 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x00000010, 0x40210620, 0x000 }, -- { 0x0000ffff, 0xc0280a20, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x00000010, 0x40211620, 0x000 }, -- { 0x0000ffff, 0xc0881a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00042004, 0x00604411, 0x622 }, -- { 0x00000000, 0x00600000, 0x5d1 }, -- { 0x00000000, 0xc0600000, 0x2a3 }, -- { 0x00000005, 0x00200a2d, 0x000 }, -- { 0x00000008, 0x00220a22, 0x000 }, -- { 0x0000002b, 0x00201a2d, 0x000 }, -- { 0x0000001c, 0x00201e2d, 0x000 }, -- { 0x00007000, 0x00281e27, 0x000 }, -- { 0x00000000, 0x00311ce6, 0x000 }, -- { 0x0000002a, 0x00201a2d, 0x000 }, -- { 0x0000000c, 0x00221a26, 0x000 }, -- { 0x00000000, 0x002f00e6, 0x000 }, -- { 0x00000000, 0x06e00000, 0x292 }, -- { 0x00000000, 0x00201c11, 0x000 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000010, 0x00201811, 0x000 }, -- { 0x00000000, 0x00691ce2, 0x12f }, -- { 0x93800000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x95000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f022f, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x29d }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x92000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000001c, 0x00403627, 0x000 }, -- { 0x0000000c, 0xc0220a20, 0x000 }, -- { 0x00000029, 0x00203622, 0x000 }, -- { 0x00000028, 0xc0403620, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000009, 0x00204811, 0x000 }, -- { 0xa1000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00804811, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce3, 0x000 }, -- { 0x00000021, 0x00203627, 0x000 }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002c1ce4, 0x000 }, -- { 0x00000022, 0x00203627, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a3, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x00000000, 0x002d1d07, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203624, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000023, 0x00203627, 0x000 }, -- { 0x00000000, 0x00311cc4, 0x000 }, -- { 0x00000024, 0x00803627, 0x000 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14c00000, 0x2dc }, -- { 0x00000000, 0x00400000, 0x2d9 }, -- { 0x0000001a, 0x00203627, 0x000 }, -- { 0x0000001b, 0x00203628, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000002, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2d9 }, -- { 0x00000003, 0x00210227, 0x000 }, -- { 0x00000000, 0x14e00000, 0x2dc }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e1, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120a1, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000024, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x002e00e2, 0x000 }, -- { 0x00000000, 0x02c00000, 0x2dc }, -- { 0x00000022, 0x00201e2d, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x00000000, 0x002e00e8, 0x000 }, -- { 0x00000000, 0x06c00000, 0x2dc }, -- { 0x00000000, 0x00600000, 0x5ff }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2b5 }, -- { 0x00000000, 0x00600000, 0x5f6 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x00000000, 0x00600000, 0x2a7 }, -- { 0x00000000, 0x00400000, 0x2de }, -- { 0x0000001a, 0x00201e2d, 0x000 }, -- { 0x0000001b, 0x0080222d, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000000, 0x00311ca1, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294847, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e21, 0x000 }, -- { 0x00000000, 0x003120c2, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00311ca3, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294887, 0x000 }, -- { 0x00000001, 0x00220a21, 0x000 }, -- { 0x00000000, 0x003008a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000010, 0x00221e23, 0x000 }, -- { 0x00000000, 0x003120c4, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x003808c5, 0x000 }, -- { 0x00000000, 0x00300841, 0x000 }, -- { 0x00000001, 0x00220a22, 0x000 }, -- { 0x00000000, 0x003308a2, 0x000 }, -- { 0x00000010, 0x00221e22, 0x000 }, -- { 0x00000010, 0x00212222, 0x000 }, -- { 0x00000000, 0x00894907, 0x000 }, -- { 0x00000017, 0x0020222d, 0x000 }, -- { 0x00000000, 0x14c00000, 0x318 }, -- { 0xffffffef, 0x00280621, 0x000 }, -- { 0x00000014, 0x0020222d, 0x000 }, -- { 0x0000f8e0, 0x00204411, 0x000 }, -- { 0x00000000, 0x00294901, 0x000 }, -- { 0x00000000, 0x00894901, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x060a0200, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0204811, 0x000 }, -- { 0x8a000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00002257, 0x00204411, 0x000 }, -- { 0x00000003, 0xc0484a20, 0x000 }, -- { 0x0000225d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0x00600000, 0x5de }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00384a22, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0001a1fd, 0x00204411, 0x000 }, -- { 0x00000000, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x00000001, 0x40304a20, 0x000 }, -- { 0x00000002, 0xc0304a20, 0x000 }, -- { 0x00000001, 0x00530a22, 0x355 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x35e }, -- { 0x00000014, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x36c }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00604802, 0x374 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x370 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x367 }, -- { 0x00000028, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5ba }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x367 }, -- { 0x0000002c, 0x00203626, 0x000 }, -- { 0x00000049, 0x00201811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000001, 0x00331a26, 0x000 }, -- { 0x00000000, 0x002f0226, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x376 }, -- { 0x0000002c, 0x00801a2d, 0x000 }, -- { 0x0000003f, 0xc0280a20, 0x000 }, -- { 0x00000015, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x38c }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b7 }, -- { 0x00000016, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3b9 }, -- { 0x00000020, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3a2 }, -- { 0x0000000f, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3ae }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x3ae }, -- { 0x0000001e, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x396 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x08000000, 0x00290a22, 0x000 }, -- { 0x00000003, 0x40210e20, 0x000 }, -- { 0x0000000c, 0xc0211220, 0x000 }, -- { 0x00080000, 0x00281224, 0x000 }, -- { 0x00000014, 0xc0221620, 0x000 }, -- { 0x00000000, 0x002914a4, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x002948a2, 0x000 }, -- { 0x0000a1fe, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000016, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000015, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x398 }, -- { 0x0000210e, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000017, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000003, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3a4 }, -- { 0x00002108, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404802, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x80000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000010, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3b4 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000006, 0x00404811, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x374 }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x0000001d, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3ce }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x00000018, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000011, 0x00210230, 0x000 }, -- { 0x00000000, 0x14e00000, 0x3c2 }, -- { 0x00002100, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0xbabecafe, 0x00204811, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000004, 0x00404811, 0x000 }, -- { 0x00002170, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000a, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3d3 }, -- { 0x8c000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00003fff, 0x40280a20, 0x000 }, -- { 0x80000000, 0x40280e20, 0x000 }, -- { 0x40000000, 0xc0281220, 0x000 }, -- { 0x00040000, 0x00694622, 0x622 }, -- { 0x00000000, 0x00201410, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e1 }, -- { 0x00000000, 0xc0401800, 0x3e4 }, -- { 0x00003fff, 0xc0281a20, 0x000 }, -- { 0x00040000, 0x00694626, 0x622 }, -- { 0x00000000, 0x00201810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x3e7 }, -- { 0x00000000, 0xc0401c00, 0x3ea }, -- { 0x00003fff, 0xc0281e20, 0x000 }, -- { 0x00040000, 0x00694627, 0x622 }, -- { 0x00000000, 0x00201c10, 0x000 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0x002820c5, 0x000 }, -- { 0x00000000, 0x004948e8, 0x000 }, -- { 0xa5800000, 0x00200811, 0x000 }, -- { 0x00002000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x40204800, 0x000 }, -- { 0x0000001f, 0xc0210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x3f7 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00008000, 0x00204811, 0x000 }, -- { 0x0000ffff, 0xc0481220, 0x3ff }, -- { 0xa7800000, 0x00200811, 0x000 }, -- { 0x0000a000, 0x00200c11, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0x00204402, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000ffff, 0xc0281220, 0x000 }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00304883, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x83000000, 0x00604411, 0x412 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xa9800000, 0x00200811, 0x000 }, -- { 0x0000c000, 0x00400c11, 0x3fa }, -- { 0xab800000, 0x00200811, 0x000 }, -- { 0x0000f8e0, 0x00400c11, 0x3fa }, -- { 0xad800000, 0x00200811, 0x000 }, -- { 0x0000f880, 0x00400c11, 0x3fa }, -- { 0xb3800000, 0x00200811, 0x000 }, -- { 0x0000f3fc, 0x00400c11, 0x3fa }, -- { 0xaf800000, 0x00200811, 0x000 }, -- { 0x0000e000, 0x00400c11, 0x3fa }, -- { 0xb1800000, 0x00200811, 0x000 }, -- { 0x0000f000, 0x00400c11, 0x3fa }, -- { 0x83000000, 0x00204411, 0x000 }, -- { 0x00002148, 0x00204811, 0x000 }, -- { 0x84000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x1d000000, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x01182000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0218a000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0318c000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0418f8e0, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0518f880, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0618e000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0718f000, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x0818f3fc, 0xc0304620, 0x000 }, -- { 0x00000000, 0xd9004800, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x00000033, 0xc0300a20, 0x000 }, -- { 0x00000000, 0xc0403440, 0x000 }, -- { 0x00000030, 0x00200a2d, 0x000 }, -- { 0x00000000, 0xc0290c40, 0x000 }, -- { 0x00000030, 0x00203623, 0x000 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x00a0000a, 0x000 }, -- { 0x86000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x85000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0x00404801, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x00000018, 0x40210220, 0x000 }, -- { 0x00000000, 0x14c00000, 0x447 }, -- { 0x00800000, 0xc0494a20, 0x448 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x06e00000, 0x450 }, -- { 0x00000004, 0x00200811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x622 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00404c02, 0x450 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x00000000, 0xc0201400, 0x000 }, -- { 0x00000000, 0xc0201800, 0x000 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x461 }, -- { 0x00000000, 0xc0202000, 0x000 }, -- { 0x00000004, 0x002f0228, 0x000 }, -- { 0x00000000, 0x06e00000, 0x461 }, -- { 0x00000004, 0x00202011, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x00000010, 0x00280a23, 0x000 }, -- { 0x00000010, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x469 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0x00694624, 0x622 }, -- { 0x00000000, 0x00400000, 0x46e }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00604805, 0x627 }, -- { 0x00000000, 0x002824f0, 0x000 }, -- { 0x00000007, 0x00280a23, 0x000 }, -- { 0x00000001, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x475 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x04e00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00000002, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47a }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x02e00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00000003, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x47f }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00000004, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x484 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00000005, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x489 }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x06e00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00000006, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x48e }, -- { 0x00000000, 0x002f00c9, 0x000 }, -- { 0x00000000, 0x08e00000, 0x48e }, -- { 0x00000000, 0x00400000, 0x49b }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x000 }, -- { 0x00000008, 0x00210a23, 0x000 }, -- { 0x00000000, 0x14c00000, 0x498 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00007f00, 0x00280a21, 0x000 }, -- { 0x00004500, 0x002f0222, 0x000 }, -- { 0x00000000, 0x0ae00000, 0x4a1 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x00404c08, 0x461 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000010, 0x40210e20, 0x000 }, -- { 0x00000011, 0x40211220, 0x000 }, -- { 0x00000012, 0x40211620, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00210225, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4ab }, -- { 0x00040000, 0xc0494a20, 0x4ac }, -- { 0xfffbffff, 0xc0284a20, 0x000 }, -- { 0x00000000, 0x00210223, 0x000 }, -- { 0x00000000, 0x14e00000, 0x4b8 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x0000000c, 0x00204811, 0x000 }, -- { 0x00000000, 0x00200010, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4b4 }, -- { 0xa0000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000004, 0x00204811, 0x000 }, -- { 0x0000216b, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000216c, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204810, 0x000 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0ce00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4b2 }, -- { 0x00000000, 0xc0210a20, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4cb }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x627 }, -- { 0x00000000, 0x00400000, 0x4cf }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00040000, 0xc0294620, 0x000 }, -- { 0x00000000, 0xc0600000, 0x622 }, -- { 0x00000001, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4d6 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00404811, 0x000 }, -- { 0x00000000, 0xc0204400, 0x000 }, -- { 0x00000000, 0xc0404810, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x000021f8, 0x00204411, 0x000 }, -- { 0x0000000e, 0x00204811, 0x000 }, -- { 0x000421f9, 0x00604411, 0x622 }, -- { 0x00000000, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x4d8 }, -- { 0x00002180, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000003, 0x00333e2f, 0x000 }, -- { 0x00000001, 0x00210221, 0x000 }, -- { 0x00000000, 0x14e00000, 0x508 }, -- { 0x0000002c, 0x00200a2d, 0x000 }, -- { 0x00040000, 0x18e00c11, 0x4f7 }, -- { 0x00000001, 0x00333e2f, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xd8c04800, 0x4eb }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000002d, 0x0020122d, 0x000 }, -- { 0x00000000, 0x00290c83, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204802, 0x000 }, -- { 0x00000000, 0x00204803, 0x000 }, -- { 0x00000008, 0x00300a22, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000011, 0x00210224, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000000, 0x00400000, 0x4b2 }, -- { 0x0000002c, 0xc0203620, 0x000 }, -- { 0x0000002d, 0xc0403620, 0x000 }, -- { 0x0000000f, 0x00210221, 0x000 }, -- { 0x00000000, 0x14c00000, 0x50d }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00000000, 0xd9000000, 0x000 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0xb5000000, 0x00204411, 0x000 }, -- { 0x00002000, 0x00204811, 0x000 }, -- { 0xb6000000, 0x00204411, 0x000 }, -- { 0x0000a000, 0x00204811, 0x000 }, -- { 0xb7000000, 0x00204411, 0x000 }, -- { 0x0000c000, 0x00204811, 0x000 }, -- { 0xb8000000, 0x00204411, 0x000 }, -- { 0x0000f8e0, 0x00204811, 0x000 }, -- { 0xb9000000, 0x00204411, 0x000 }, -- { 0x0000f880, 0x00204811, 0x000 }, -- { 0xba000000, 0x00204411, 0x000 }, -- { 0x0000e000, 0x00204811, 0x000 }, -- { 0xbb000000, 0x00204411, 0x000 }, -- { 0x0000f000, 0x00204811, 0x000 }, -- { 0xbc000000, 0x00204411, 0x000 }, -- { 0x0000f3fc, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000002, 0x00204811, 0x000 }, -- { 0x000000ff, 0x00280e30, 0x000 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x521 }, -- { 0x00000000, 0xc0200800, 0x000 }, -- { 0x00000000, 0x14c00000, 0x536 }, -- { 0x00000000, 0x00200c11, 0x000 }, -- { 0x0000001c, 0x00203623, 0x000 }, -- { 0x0000002b, 0x00203623, 0x000 }, -- { 0x00000029, 0x00203623, 0x000 }, -- { 0x00000028, 0x00203623, 0x000 }, -- { 0x00000017, 0x00203623, 0x000 }, -- { 0x00000025, 0x00203623, 0x000 }, -- { 0x00000026, 0x00203623, 0x000 }, -- { 0x00000015, 0x00203623, 0x000 }, -- { 0x00000016, 0x00203623, 0x000 }, -- { 0xffffe000, 0x00200c11, 0x000 }, -- { 0x00000021, 0x00203623, 0x000 }, -- { 0x00000022, 0x00203623, 0x000 }, -- { 0x00001fff, 0x00200c11, 0x000 }, -- { 0x00000023, 0x00203623, 0x000 }, -- { 0x00000024, 0x00203623, 0x000 }, -- { 0xf1ffffff, 0x00283a2e, 0x000 }, -- { 0x0000001a, 0xc0220e20, 0x000 }, -- { 0x00000000, 0x0029386e, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000006, 0x00204811, 0x000 }, -- { 0x0000002a, 0x40203620, 0x000 }, -- { 0x87000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0x9d000000, 0x00204411, 0x000 }, -- { 0x0000001f, 0x40214a20, 0x000 }, -- { 0x96000000, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0200c00, 0x000 }, -- { 0x00000000, 0xc0201000, 0x000 }, -- { 0x0000001f, 0x00211624, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x0000001d, 0x00203623, 0x000 }, -- { 0x00000003, 0x00281e23, 0x000 }, -- { 0x00000008, 0x00222223, 0x000 }, -- { 0xfffff000, 0x00282228, 0x000 }, -- { 0x00000000, 0x002920e8, 0x000 }, -- { 0x0000001f, 0x00203628, 0x000 }, -- { 0x00000018, 0x00211e23, 0x000 }, -- { 0x00000020, 0x00203627, 0x000 }, -- { 0x00000002, 0x00221624, 0x000 }, -- { 0x00000000, 0x003014a8, 0x000 }, -- { 0x0000001e, 0x00203625, 0x000 }, -- { 0x00000003, 0x00211a24, 0x000 }, -- { 0x10000000, 0x00281a26, 0x000 }, -- { 0xefffffff, 0x00283a2e, 0x000 }, -- { 0x00000000, 0x004938ce, 0x610 }, -- { 0x00000001, 0x40280a20, 0x000 }, -- { 0x00000006, 0x40280e20, 0x000 }, -- { 0x00000300, 0xc0281220, 0x000 }, -- { 0x00000008, 0x00211224, 0x000 }, -- { 0x00000000, 0xc0201620, 0x000 }, -- { 0x00000000, 0xc0201a20, 0x000 }, -- { 0x00000000, 0x00210222, 0x000 }, -- { 0x00000000, 0x14c00000, 0x56c }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x622 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00020000, 0x00294a26, 0x000 }, -- { 0x00000000, 0x00204810, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x574 }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x582 }, -- { 0x00000002, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x574 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00002258, 0x00300a24, 0x000 }, -- { 0x00040000, 0x00694622, 0x622 }, -- { 0x00000000, 0xc0201c10, 0x000 }, -- { 0x00000000, 0xc0400000, 0x582 }, -- { 0x00000000, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x578 }, -- { 0x00000000, 0xc0201c00, 0x000 }, -- { 0x00000000, 0xc0400000, 0x582 }, -- { 0x00000004, 0x002f0223, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x580 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x0000216d, 0x00204411, 0x000 }, -- { 0x00000000, 0xc0204800, 0x000 }, -- { 0x00000000, 0xc0604800, 0x627 }, -- { 0x00000000, 0x00401c10, 0x582 }, -- { 0x00000000, 0xc0200000, 0x000 }, -- { 0x00000000, 0xc0400000, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x584 }, -- { 0x00000000, 0x00600000, 0x5c3 }, -- { 0x00000000, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x592 }, -- { 0x0000a2b7, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x00000033, 0x0020262d, 0x000 }, -- { 0x0000001a, 0x00212229, 0x000 }, -- { 0x00000006, 0x00222629, 0x000 }, -- { 0x0000a2c4, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x590 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d1, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000001, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5a0 }, -- { 0x0000a2bb, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x00000034, 0x0020262d, 0x000 }, -- { 0x0000001a, 0x00212229, 0x000 }, -- { 0x00000006, 0x00222629, 0x000 }, -- { 0x0000a2c5, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x59e }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d2, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x00000002, 0x002f0224, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x5ae }, -- { 0x0000a2bf, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x00000035, 0x0020262d, 0x000 }, -- { 0x0000001a, 0x00212229, 0x000 }, -- { 0x00000006, 0x00222629, 0x000 }, -- { 0x0000a2c6, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5ac }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d3, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x0000a2c3, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204807, 0x000 }, -- { 0x00000036, 0x0020262d, 0x000 }, -- { 0x0000001a, 0x00212229, 0x000 }, -- { 0x00000006, 0x00222629, 0x000 }, -- { 0x0000a2c7, 0x00204411, 0x000 }, -- { 0x00000000, 0x003048e9, 0x000 }, -- { 0x00000000, 0x00e00000, 0x5b8 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404808, 0x000 }, -- { 0x0000a2d4, 0x00204411, 0x000 }, -- { 0x00000001, 0x00504a28, 0x000 }, -- { 0x85000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0x0000304a, 0x00204411, 0x000 }, -- { 0x01000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x00400000, 0x5be }, -- { 0xa4000000, 0xc0204411, 0x000 }, -- { 0x00000000, 0xc0404800, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5c3 }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x0000003f, 0x00204811, 0x000 }, -- { 0x00000005, 0x00204811, 0x000 }, -- { 0x0000a1f4, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x88000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0xff000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x00000002, 0x00804811, 0x000 }, -- { 0x00000000, 0x0ee00000, 0x5d6 }, -- { 0x00001000, 0x00200811, 0x000 }, -- { 0x0000002b, 0x00203622, 0x000 }, -- { 0x00000000, 0x00600000, 0x5da }, -- { 0x00000000, 0x00600000, 0x5c3 }, -- { 0x98000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00804811, 0x000 }, -- { 0x00000000, 0xc0600000, 0x5da }, -- { 0x00000000, 0xc0400400, 0x001 }, -- { 0x0000a2a4, 0x00204411, 0x000 }, -- { 0x00000022, 0x00204811, 0x000 }, -- { 0x89000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00404811, 0x5cd }, -- { 0x97000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x8a000000, 0x00204411, 0x000 }, -- { 0x00000000, 0x00404811, 0x5cd }, -- { 0x00000000, 0x00600000, 0x5f3 }, -- { 0x0001a2a4, 0xc0204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x374 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x09800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x0004217f, 0x00604411, 0x622 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x000 }, -- { 0x00000004, 0x00404c11, 0x5ed }, -- { 0x00000000, 0x00400000, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000004, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffffb, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0x00000008, 0x00291e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x00000017, 0x00201e2d, 0x000 }, -- { 0xfffffff7, 0x00281e27, 0x000 }, -- { 0x00000017, 0x00803627, 0x000 }, -- { 0x0001a2a4, 0x00204411, 0x000 }, -- { 0x00000016, 0x00604811, 0x374 }, -- { 0x00002010, 0x00204411, 0x000 }, -- { 0x00010000, 0x00204811, 0x000 }, -- { 0x0000217c, 0x00204411, 0x000 }, -- { 0x01800000, 0x00204811, 0x000 }, -- { 0xffffffff, 0x00204811, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000000, 0x17000000, 0x000 }, -- { 0x81000000, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0004217f, 0x00604411, 0x622 }, -- { 0x0000001f, 0x00210230, 0x000 }, -- { 0x00000000, 0x14c00000, 0x621 }, -- { 0x00000010, 0x00404c11, 0x607 }, -- { 0x00000000, 0xc0200400, 0x000 }, -- { 0x00000000, 0x38c00000, 0x000 }, -- { 0x0000001d, 0x00200a2d, 0x000 }, -- { 0x0000001e, 0x00200e2d, 0x000 }, -- { 0x0000001f, 0x0020122d, 0x000 }, -- { 0x00000020, 0x0020162d, 0x000 }, -- { 0x00002169, 0x00204411, 0x000 }, -- { 0x00000000, 0x00204804, 0x000 }, -- { 0x00000000, 0x00204805, 0x000 }, -- { 0x00000000, 0x00204801, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000004, 0x00301224, 0x000 }, -- { 0x00000000, 0x002f0064, 0x000 }, -- { 0x00000000, 0x0cc00000, 0x620 }, -- { 0x00000003, 0x00281a22, 0x000 }, -- { 0x00000008, 0x00221222, 0x000 }, -- { 0xfffff000, 0x00281224, 0x000 }, -- { 0x00000000, 0x002910c4, 0x000 }, -- { 0x0000001f, 0x00403624, 0x000 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x622 }, -- { 0x9f000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x625 }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x1ac00000, 0x627 }, -- { 0x9e000000, 0x00204411, 0x000 }, -- { 0xcafebabe, 0x00204811, 0x000 }, -- { 0x00000000, 0x1ae00000, 0x62a }, -- { 0x00000000, 0x00800000, 0x000 }, -- { 0x00000000, 0x00600000, 0x00b }, -- { 0x00001000, 0x00600411, 0x315 }, -- { 0x00000000, 0x00200411, 0x000 }, -- { 0x00000000, 0x00600811, 0x1b2 }, -- { 0x0000225c, 0x00204411, 0x000 }, -- { 0x00000003, 0x00204811, 0x000 }, -- { 0x00002256, 0x00204411, 0x000 }, -- { 0x0000001b, 0x00204811, 0x000 }, -- { 0x0000a1fc, 0x00204411, 0x000 }, -- { 0x00000001, 0x00204811, 0x000 }, -- { 0x0001a1fd, 0xc0204411, 0x000 }, -- { 0x00000021, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000024, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000022, 0x0020222d, 0x000 }, -- { 0x0000ffff, 0x00282228, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00204811, 0x000 }, -- { 0x00000023, 0x00201e2d, 0x000 }, -- { 0x00000010, 0x00221e27, 0x000 }, -- { 0x00000000, 0x00294907, 0x000 }, -- { 0x00000000, 0x00404811, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x00000000, 0x00000000, 0x000 }, -- { 0x0142050a, 0x05ba0250, 0x000 }, -- { 0x01c30168, 0x044105ba, 0x000 }, -- { 0x02250209, 0x02500151, 0x000 }, -- { 0x02230245, 0x02a00241, 0x000 }, -- { 0x03d705ba, 0x05ba05ba, 0x000 }, -- { 0x05e205e3, 0x031f05ba, 0x000 }, -- { 0x032005bf, 0x0320034a, 0x000 }, -- { 0x03340282, 0x034c033e, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x05ba0557, 0x05ba032a, 0x000 }, -- { 0x03bc05ba, 0x04c3034e, 0x000 }, -- { 0x04a20455, 0x043f05ba, 0x000 }, -- { 0x04d805ba, 0x044304e5, 0x000 }, -- { 0x0455050f, 0x035b037b, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x05ba05ba, 0x05d805c1, 0x000 }, -- { 0x05ba05ba, 0x000705ba, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x03f803ed, 0x04080406, 0x000 }, -- { 0x040e040a, 0x040c0410, 0x000 }, -- { 0x041c0418, 0x04240420, 0x000 }, -- { 0x042c0428, 0x04340430, 0x000 }, -- { 0x05ba05ba, 0x043a0438, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x05ba05ba, 0x05ba05ba, 0x000 }, -- { 0x0002060e, 0x062c0006, 0x000 }, --}; -- --static const u32 RS780_pfp_microcode[] = { --0xca0400, --0xa00000, --0x7e828b, --0x7c038b, --0x8001db, --0x7c038b, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xc41838, --0xca2400, --0xca2800, --0x9581cb, --0xc41c3a, --0xc3c000, --0xca0800, --0xca0c00, --0x7c744b, --0xc20005, --0x99c000, --0xc41c3a, --0x7c744c, --0xc0ffe0, --0x042c08, --0x309002, --0x7d2500, --0x351402, --0x7d350b, --0x255407, --0x7cd580, --0x259c07, --0x95c004, --0xd5001b, --0x7eddc1, --0x7d9d80, --0xd6801b, --0xd5801b, --0xd4401e, --0xd5401e, --0xd6401e, --0xd6801e, --0xd4801e, --0xd4c01e, --0x9783d3, --0xd5c01e, --0xca0800, --0x80001a, --0xca0c00, --0xe4011e, --0xd4001e, --0x80000c, --0xc41838, --0xe4013e, --0xd4001e, --0x80000c, --0xc41838, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0xca0c00, --0x8001db, --0xd48024, --0xca0800, --0x7c00c0, --0xc81425, --0xc81824, --0x7c9488, --0x7c9880, --0xc20003, --0xd40075, --0x7c744c, --0x800064, --0xd4401e, --0xca1800, --0xd4401e, --0xd5801e, --0x800062, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xe2001e, --0xca0400, --0xa00000, --0x7e828b, --0xd40075, --0xd4401e, --0xca0800, --0xca0c00, --0xca1000, --0xd48019, --0xd4c018, --0xd50017, --0xd4801e, --0xd4c01e, --0xd5001e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c01, --0xd48060, --0x94c003, --0x041001, --0x041002, --0xd50025, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xd48061, --0xd4401e, --0x800000, --0xd4801e, --0xca0800, --0xca0c00, --0xd4401e, --0xd48016, --0xd4c016, --0xd4801e, --0x8001db, --0xd4c01e, --0xc60843, --0xca0c00, --0xca1000, --0x948004, --0xca1400, --0xe420f3, --0xd42013, --0xd56065, --0xd4e01c, --0xd5201c, --0xd5601c, --0x800000, --0x062001, --0xc60843, --0xca0c00, --0xca1000, --0x9483f7, --0xca1400, --0xe420f3, --0x80009c, --0xd42013, --0xc60843, --0xca0c00, --0xca1000, --0x9883ef, --0xca1400, --0xd40064, --0x8000b0, --0x000000, --0xc41432, --0xc61843, --0xc4082f, --0x954005, --0xc40c30, --0xd4401e, --0x800000, --0xee001e, --0x9583f5, --0xc41031, --0xd44033, --0xd52065, --0xd4a01c, --0xd4e01c, --0xd5201c, --0xe4015e, --0xd4001e, --0x800000, --0x062001, --0xca1800, --0x0a2001, --0xd60076, --0xc40836, --0x988007, --0xc61045, --0x950110, --0xd4001f, --0xd46062, --0x800000, --0xd42062, --0xcc3835, --0xcc1433, --0x8401de, --0xd40072, --0xd5401e, --0x800000, --0xee001e, --0xe2001a, --0x8401de, --0xe2001a, --0xcc104b, --0xcc0447, --0x2c9401, --0x7d098b, --0x984005, --0x7d15cb, --0xd4001a, --0x8001db, --0xd4006d, --0x344401, --0xcc0c48, --0x98403a, --0xcc2c4a, --0x958004, --0xcc0449, --0x8001db, --0xd4001a, --0xd4c01a, --0x282801, --0x840113, --0xcc1003, --0x98801b, --0x04380c, --0x840113, --0xcc1003, --0x988017, --0x043808, --0x840113, --0xcc1003, --0x988013, --0x043804, --0x840113, --0xcc1003, --0x988014, --0xcc104c, --0x9a8009, --0xcc144d, --0x9840dc, --0xd4006d, --0xcc1848, --0xd5001a, --0xd5401a, --0x8000ec, --0xd5801a, --0x96c0d5, --0xd4006d, --0x8001db, --0xd4006e, --0x9ac003, --0xd4006d, --0xd4006e, --0x800000, --0xec007f, --0x9ac0cc, --0xd4006d, --0x8001db, --0xd4006e, --0xcc1403, --0xcc1803, --0xcc1c03, --0x7d9103, --0x7dd583, --0x7d190c, --0x35cc1f, --0x35701f, --0x7cf0cb, --0x7cd08b, --0x880000, --0x7e8e8b, --0x95c004, --0xd4006e, --0x8001db, --0xd4001a, --0xd4c01a, --0xcc0803, --0xcc0c03, --0xcc1003, --0xcc1403, --0xcc1803, --0xcc1c03, --0xcc2403, --0xcc2803, --0x35c41f, --0x36b01f, --0x7c704b, --0x34f01f, --0x7c704b, --0x35701f, --0x7c704b, --0x7d8881, --0x7dccc1, --0x7e5101, --0x7e9541, --0x7c9082, --0x7cd4c2, --0x7c848b, --0x9ac003, --0x7c8c8b, --0x2c8801, --0x98809e, --0xd4006d, --0x98409c, --0xd4006e, --0xcc084c, --0xcc0c4d, --0xcc1048, --0xd4801a, --0xd4c01a, --0x800124, --0xd5001a, --0xcc0832, --0xd40032, --0x9482b6, --0xca0c00, --0xd4401e, --0x800000, --0xd4001e, --0xe4011e, --0xd4001e, --0xca0800, --0xca0c00, --0xca1000, --0xd4401e, --0xca1400, --0xd4801e, --0xd4c01e, --0xd5001e, --0xd5401e, --0xd54034, --0x800000, --0xee001e, --0x280404, --0xe2001a, --0xe2001a, --0xd4401a, --0xca3800, --0xcc0803, --0xcc0c03, --0xcc0c03, --0xcc0c03, --0x98829a, --0x000000, --0x8401de, --0xd7a06f, --0x800000, --0xee001f, --0xca0400, --0xc2ff00, --0xcc0834, --0xc13fff, --0x7c74cb, --0x7cc90b, --0x7d010f, --0x99028d, --0x7c738b, --0x8401de, --0xd7a06f, --0x800000, --0xee001f, --0xca0800, --0x281900, --0x7d898b, --0x958014, --0x281404, --0xca0c00, --0xca1000, --0xca1c00, --0xca2400, --0xe2001f, --0xd4c01a, --0xd5001a, --0xd5401a, --0xcc1803, --0xcc2c03, --0xcc2c03, --0xcc2c03, --0x7da58b, --0x7d9c47, --0x984274, --0x000000, --0x800184, --0xd4c01a, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xe4011e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xe4013e, --0xd4001e, --0xd4401e, --0xee001e, --0xca0400, --0xa00000, --0x7e828b, --0xca0800, --0x248c06, --0x0ccc06, --0x98c006, --0xcc104e, --0x990004, --0xd40073, --0xe4011e, --0xd4001e, --0xd4401e, --0xd4801e, --0x800000, --0xee001e, --0xca0800, --0xca0c00, --0x34d018, --0x251001, --0x950021, --0xc17fff, --0xca1000, --0xca1400, --0xca1800, --0xd4801d, --0xd4c01d, --0x7db18b, --0xc14202, --0xc2c001, --0xd5801d, --0x34dc0e, --0x7d5d4c, --0x7f734c, --0xd7401e, --0xd5001e, --0xd5401e, --0xc14200, --0xc2c000, --0x099c01, --0x31dc10, --0x7f5f4c, --0x7f734c, --0x042802, --0x7d8380, --0xd5a86f, --0xd58066, --0xd7401e, --0xec005e, --0xc82402, --0xc82402, --0x8001db, --0xd60076, --0xd4401e, --0xd4801e, --0xd4c01e, --0x800000, --0xee001e, --0x800000, --0xee001f, --0xd4001f, --0x800000, --0xd4001f, --0xd4001f, --0x880000, --0xd4001f, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x000000, --0x010194, --0x02019b, --0x0300b2, --0x0400a2, --0x050003, --0x06003f, --0x070032, --0x08014f, --0x090046, --0x0a0036, --0x1001d9, --0x1700c5, --0x22015d, --0x23016c, --0x2000d7, --0x240148, --0x26004d, --0x27005c, --0x28008d, --0x290051, --0x2a007e, --0x2b0061, --0x2f0088, --0x3200aa, --0x3401a2, --0x36006f, --0x3c0179, --0x3f0095, --0x4101af, --0x440151, --0x550196, --0x56019d, --0x60000b, --0x610034, --0x620038, --0x630038, --0x640038, --0x650038, --0x660038, --0x670038, --0x68003a, --0x690041, --0x6a0048, --0x6b0048, --0x6c0048, --0x6d0048, --0x6e0048, --0x6f0048, --0x7301d9, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --0x000006, --}; -- --static const u32 RV770_cp_microcode[] = { --0xcc0003ea, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000001, --0xd040007f, --0x80000001, --0xcc400041, --0x7c40c000, --0xc0160004, --0x30d03fff, --0x7d15000c, --0xcc110000, --0x28d8001e, --0x31980001, --0x28dc001f, --0xc8200004, --0x95c00006, --0x7c424000, --0xcc000062, --0x7e56800c, --0xcc290000, --0xc8240004, --0x7e26000b, --0x95800006, --0x7c42c000, --0xcc000062, --0x7ed7000c, --0xcc310000, --0xc82c0004, --0x7e2e000c, --0xcc000062, --0x31103fff, --0x80000001, --0xce110000, --0x7c40c000, --0x80000001, --0xcc400040, --0x80000001, --0xcc412257, --0x7c418000, --0xcc400045, --0xcc400048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc400045, --0xcc400048, --0x7c40c000, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc000045, --0xcc000048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0x040ca1fd, --0xc0120001, --0xcc000045, --0xcc000048, --0x7cd0c00c, --0xcc41225c, --0xcc41a1fc, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000001, --0xcc41225d, --0x7c408000, --0x7c40c000, --0xc02a0002, --0x7c410000, --0x7d29000c, --0x30940001, --0x30980006, --0x309c0300, --0x29dc0008, --0x7c420000, --0x7c424000, --0x9540000f, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0xccc12169, --0xcd01216a, --0xce81216b, --0x0db40002, --0xcc01216c, --0x9740000e, --0x0db40000, --0x8000007b, --0xc834000a, --0x0db40002, --0x97400009, --0x0db40000, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0x8000007b, --0xc834000a, --0x97400004, --0x7e028000, --0x8000007b, --0xc834000a, --0x0db40004, --0x9740ff8c, --0x00000000, --0xce01216d, --0xce41216e, --0xc8280003, --0xc834000a, --0x9b400004, --0x043c0005, --0x8400026d, --0xcc000062, --0x0df40000, --0x9740000b, --0xc82c03e6, --0xce81a2b7, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c4, --0x80000001, --0xcfc1a2d1, --0x0df40001, --0x9740000b, --0xc82c03e7, --0xce81a2bb, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c5, --0x80000001, --0xcfc1a2d2, --0x0df40002, --0x9740000b, --0xc82c03e8, --0xce81a2bf, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c6, --0x80000001, --0xcfc1a2d3, --0xc82c03e9, --0xce81a2c3, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c7, --0x80000001, --0xcfc1a2d4, --0x80000001, --0xcc400042, --0x7c40c000, --0x7c410000, --0x2914001d, --0x31540001, --0x9940000d, --0x31181000, --0xc81c0011, --0x09dc0001, --0x95c0ffff, --0xc81c0011, --0xccc12100, --0xcd012101, --0xccc12102, --0xcd012103, --0x04180004, --0x8000039f, --0xcd81a2a4, --0xc02a0004, --0x95800008, --0x36a821a3, --0xcc290000, --0xc8280004, --0xc81c0011, --0x0de40040, --0x9640ffff, --0xc81c0011, --0xccc12170, --0xcd012171, --0xc8200012, --0x96000000, --0xc8200012, --0x8000039f, --0xcc000064, --0x7c40c000, --0x7c410000, --0xcc000045, --0xcc000048, --0x40d40003, --0xcd41225c, --0xcd01a1fc, --0xc01a0001, --0x041ca1fd, --0x7dd9c00c, --0x7c420000, --0x08cc0001, --0x06240001, --0x06280002, --0xce1d0000, --0xce5d0000, --0x98c0fffa, --0xce9d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0x30d00001, --0x28cc0001, --0x7c414000, --0x95000006, --0x7c418000, --0xcd41216d, --0xcd81216e, --0x800000f3, --0xc81c0003, --0xc0220004, --0x7e16000c, --0xcc210000, --0xc81c0004, --0x7c424000, --0x98c00004, --0x7c428000, --0x80000001, --0xcde50000, --0xce412169, --0xce81216a, --0xcdc1216b, --0x80000001, --0xcc01216c, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x7c41c000, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9680000a, --0x7c020000, --0x7c420000, --0x1e300003, --0xcc00006a, --0x9b000003, --0x42200005, --0x04200040, --0x80000110, --0x7c024000, --0x7e024000, --0x9a400000, --0x0a640001, --0x30ec0010, --0x9ac0000a, --0xcc000062, --0xc02a0004, --0xc82c0021, --0x7e92800c, --0xcc000041, --0xcc290000, --0xcec00021, --0x80000120, --0xc8300004, --0xcd01216d, --0xcd41216e, --0xc8300003, --0x7f1f000b, --0x30f40007, --0x27780001, --0x9740002a, --0x07b80125, --0x9f800000, --0x00000000, --0x80000135, --0x7f1b8004, --0x80000139, --0x7f1b8005, --0x8000013d, --0x7f1b8002, --0x80000141, --0x7f1b8003, --0x80000145, --0x7f1b8007, --0x80000149, --0x7f1b8006, --0x8000014e, --0x28a40008, --0x9b800019, --0x28a40008, --0x8000015e, --0x326400ff, --0x9b800015, --0x28a40008, --0x8000015e, --0x326400ff, --0x9b800011, --0x28a40008, --0x8000015e, --0x326400ff, --0x9b80000d, --0x28a40008, --0x8000015e, --0x326400ff, --0x9b800009, --0x28a40008, --0x8000015e, --0x326400ff, --0x9b800005, --0x28a40008, --0x8000015e, --0x326400ff, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9a80feb1, --0x28ec0008, --0x7c434000, --0x7c438000, --0x7c43c000, --0x96c00007, --0xcc000062, --0xcf412169, --0xcf81216a, --0xcfc1216b, --0x80000001, --0xcc01216c, --0x80000001, --0xcff50000, --0xcc00006b, --0x840003a2, --0x0e68003c, --0x9a800004, --0xc8280015, --0x80000001, --0xd040007f, --0x9680ffab, --0x7e024000, --0x8400023b, --0xc00e0002, --0xcc000041, --0x80000239, --0xccc1304a, --0x7c40c000, --0x7c410000, --0xc01e0001, --0x29240012, --0xc0220002, --0x96400005, --0xc0260004, --0xc027fffb, --0x7d25000b, --0xc0260000, --0x7dd2800b, --0x7e12c00b, --0x7d25000c, --0x7c414000, --0x7c418000, --0xccc12169, --0x9a80000a, --0xcd01216a, --0xcd41216b, --0x96c0fe82, --0xcd81216c, --0xc8300018, --0x97000000, --0xc8300018, --0x80000001, --0xcc000018, --0x840003a2, --0xcc00007f, --0xc8140013, --0xc8180014, --0xcd41216b, --0x96c0fe76, --0xcd81216c, --0x80000182, --0xc8300018, --0xc80c0008, --0x98c00000, --0xc80c0008, --0x7c410000, --0x95000002, --0x00000000, --0x7c414000, --0xc8200009, --0xcc400043, --0xce01a1f4, --0xcc400044, --0xc00e8000, --0x7c424000, --0x7c428000, --0x2aac001f, --0x96c0fe63, --0xc035f000, --0xce4003e2, --0x32780003, --0x267c0008, --0x7ff7c00b, --0x7ffbc00c, --0x2a780018, --0xcfc003e3, --0xcf8003e4, --0x26b00002, --0x7f3f0000, --0xcf0003e5, --0x8000031f, --0x7c80c000, --0x7c40c000, --0x28d00008, --0x3110000f, --0x9500000f, --0x25280001, --0x06a801b3, --0x9e800000, --0x00000000, --0x800001d4, --0xc0120800, --0x800001e2, --0xc814000f, --0x800001e9, --0xc8140010, --0x800001f0, --0xccc1a2a4, --0x800001f9, --0xc8140011, --0x30d0003f, --0x0d280015, --0x9a800012, --0x0d28001e, --0x9a80001e, --0x0d280020, --0x9a800023, --0x0d24000f, --0x0d280010, --0x7e6a800c, --0x9a800026, --0x0d200004, --0x0d240014, --0x0d280028, --0x7e62400c, --0x7ea6800c, --0x9a80002a, --0xc8140011, --0x80000001, --0xccc1a2a4, --0xc0120800, --0x7c414000, --0x7d0cc00c, --0xc0120008, --0x29580003, --0x295c000c, --0x7c420000, --0x7dd1c00b, --0x26200014, --0x7e1e400c, --0x7e4e800c, --0xce81a2a4, --0x80000001, --0xcd81a1fe, --0xc814000f, --0x0410210e, --0x95400000, --0xc814000f, --0xd0510000, --0x80000001, --0xccc1a2a4, --0xc8140010, --0x04102108, --0x95400000, --0xc8140010, --0xd0510000, --0x80000001, --0xccc1a2a4, --0xccc1a2a4, --0x04100001, --0xcd000019, --0x840003a2, --0xcc00007f, --0xc8100019, --0x99000000, --0xc8100019, --0x80000002, --0x7c408000, --0x04102100, --0x09540001, --0x9540ffff, --0xc8140011, --0xd0510000, --0x8000039f, --0xccc1a2a4, --0x7c40c000, --0xcc40000d, --0x94c0fdff, --0xcc40000e, --0x7c410000, --0x95000005, --0x08cc0001, --0xc8140005, --0x99400014, --0x00000000, --0x98c0fffb, --0x7c410000, --0x80000002, --0x7d008000, --0xc8140005, --0x7c40c000, --0x9940000c, --0xc818000c, --0x7c410000, --0x9580fdee, --0xc820000e, --0xc81c000d, --0x66200020, --0x7e1e002c, --0x25240002, --0x7e624020, --0x80000001, --0xcce60000, --0x7c410000, --0xcc00006c, --0xcc00006d, --0xc818001f, --0xc81c001e, --0x65980020, --0x7dd9c02c, --0x7cd4c00c, --0xccde0000, --0x45dc0004, --0xc8280017, --0x9680000f, --0xc00e0001, --0x28680008, --0x2aac0016, --0x32a800ff, --0x0eb00049, --0x7f2f000b, --0x97000006, --0x00000000, --0xc8140005, --0x7c40c000, --0x80000223, --0x7c410000, --0x80000226, --0xd040007f, --0x8400023b, --0xcc000041, --0xccc1304a, --0x94000000, --0xc83c001a, --0x043c0005, --0xcfc1a2a4, --0xc0361f90, --0xc0387fff, --0x7c03c010, --0x7f7b400c, --0xcf41217c, --0xcfc1217d, --0xcc01217e, --0xc03a0004, --0x0434217f, --0x7f7b400c, --0xcc350000, --0xc83c0004, --0x2bfc001f, --0x04380020, --0x97c00005, --0xcc000062, --0x9b800000, --0x0bb80001, --0x80000247, --0xcc000071, --0xcc01a1f4, --0x04380016, --0xc0360002, --0xcf81a2a4, --0x88000000, --0xcf412010, --0x7c40c000, --0x28d0001c, --0x95000005, --0x04d40001, --0xcd400065, --0x80000001, --0xcd400068, --0x09540002, --0x80000001, --0xcd400066, --0x8400026c, --0xc81803ea, --0x7c40c000, --0x9980fd9d, --0xc8140016, --0x08d00001, --0x9940002b, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0005, --0xcfc1a2a4, --0xcc01a1f4, --0x840003a2, --0xcc000046, --0x88000000, --0xcc00007f, --0x8400027e, --0xc81803ea, --0x7c40c000, --0x9980fd8b, --0xc8140016, --0x08d00001, --0x99400019, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0022, --0xcfc1a2a4, --0x840003a2, --0xcc000047, --0x88000000, --0xcc00007f, --0xc8100016, --0x9900000d, --0xcc400067, --0x80000002, --0x7c408000, --0xc81803ea, --0x9980fd77, --0x7c40c000, --0x94c00003, --0xc8100016, --0x99000004, --0xccc00068, --0x80000002, --0x7c408000, --0x8400023b, --0xc0148000, --0xcc000041, --0xcd41304a, --0xc0148000, --0x99000000, --0xc8100016, --0x80000002, --0x7c408000, --0xc0120001, --0x7c51400c, --0x80000001, --0xd0550000, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x291c001f, --0xccc0004a, --0xcd00004b, --0x95c00003, --0xc01c8000, --0xcdc12010, --0xdd830000, --0x055c2000, --0xcc000062, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004c, --0xcd00004d, --0xdd830000, --0x055ca000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004e, --0xcd00004f, --0xdd830000, --0x055cc000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00050, --0xcd000051, --0xdd830000, --0x055cf8e0, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00052, --0xcd000053, --0xdd830000, --0x055cf880, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00054, --0xcd000055, --0xdd830000, --0x055ce000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00056, --0xcd000057, --0xdd830000, --0x055cf000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00058, --0xcd000059, --0xdd830000, --0x055cf3fc, --0x80000001, --0xd81f4100, --0xd0432000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043a000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043c000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f8e0, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f880, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043e000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f3fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xc81403e0, --0xcc430000, --0xcc430000, --0xcc430000, --0x7d45c000, --0xcdc30000, --0xd0430000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0xc81003e2, --0xc81403e5, --0xc81803e3, --0xc81c03e4, --0xcd812169, --0xcdc1216a, --0xccc1216b, --0xcc01216c, --0x04200004, --0x7da18000, --0x7d964002, --0x9640fcd7, --0xcd8003e3, --0x31280003, --0xc02df000, --0x25180008, --0x7dad800b, --0x7da9800c, --0x80000001, --0xcd8003e3, --0x308cffff, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0x7c410000, --0x29240018, --0x32640001, --0x9a400013, --0xc8140020, --0x15580002, --0x9580ffff, --0xc8140020, --0xcc00006e, --0xccc12180, --0xcd01218d, --0xcc412181, --0x2914001f, --0x34588000, --0xcd81218c, --0x9540fcb9, --0xcc412182, --0xc8140020, --0x9940ffff, --0xc8140020, --0x80000002, --0x7c408000, --0x7c414000, --0x7c418000, --0x7c41c000, --0x65b40020, --0x7f57402c, --0xd4378100, --0x47740004, --0xd4378100, --0x47740004, --0xd4378100, --0x47740004, --0x09dc0004, --0xd4378100, --0x99c0fff8, --0x47740004, --0x2924001f, --0xc0380019, --0x9640fca1, --0xc03e0004, --0xcf8121f8, --0x37e021f9, --0xcc210000, --0xc8200004, --0x2a200018, --0x32200001, --0x9a00fffb, --0xcf8121f8, --0x80000002, --0x7c408000, --0x7c40c000, --0x28d00018, --0x31100001, --0xc0160080, --0x95000003, --0xc02a0004, --0x7cd4c00c, --0xccc1217c, --0xcc41217d, --0xcc41217e, --0x7c418000, --0x1db00003, --0x36a0217f, --0x9b000003, --0x419c0005, --0x041c0040, --0x99c00000, --0x09dc0001, --0xcc210000, --0xc8240004, --0x2a6c001f, --0x419c0005, --0x9ac0fffa, --0xcc800062, --0x80000002, --0x7c408000, --0x7c40c000, --0x04d403e6, --0x80000001, --0xcc540000, --0x8000039f, --0xcc4003ea, --0xc01c8000, --0x044ca000, --0xcdc12010, --0x7c410000, --0xc8140009, --0x04180000, --0x041c0008, --0xcd800071, --0x09dc0001, --0x05980001, --0xcd0d0000, --0x99c0fffc, --0xcc800062, --0x8000039f, --0xcd400071, --0xc00e0100, --0xcc000041, --0xccc1304a, --0xc83c007f, --0xcc00007f, --0x80000001, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00010333, --0x00100004, --0x00170006, --0x00210008, --0x00270028, --0x00280023, --0x00290029, --0x002a0026, --0x002b0029, --0x002d0038, --0x002e003f, --0x002f004a, --0x0034004c, --0x00360030, --0x003900af, --0x003a00d0, --0x003b00e5, --0x003c00fd, --0x003d016c, --0x003f00ad, --0x00410338, --0x0043036c, --0x0044018f, --0x004500fd, --0x004601ad, --0x004701ad, --0x00480200, --0x0049020e, --0x004a0257, --0x004b0284, --0x00520261, --0x00530273, --0x00540289, --0x0057029b, --0x0060029f, --0x006102ae, --0x006202b8, --0x006302c2, --0x006402cc, --0x006502d6, --0x006602e0, --0x006702ea, --0x006802f4, --0x006902f8, --0x006a02fc, --0x006b0300, --0x006c0304, --0x006d0308, --0x006e030c, --0x006f0310, --0x00700314, --0x00720386, --0x0074038c, --0x0079038a, --0x007c031e, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --0x000f039b, --}; -- --static const u32 RV770_pfp_microcode[] = { --0x7c408000, --0xa0000000, --0x7e82800b, --0x80000000, --0xdc030000, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xc818000e, --0x31980001, --0x7c424000, --0x95800252, --0x7c428000, --0xc81c001c, --0xc037c000, --0x7c40c000, --0x7c410000, --0x7cb4800b, --0xc0360003, --0x99c00000, --0xc81c001c, --0x7cb4800c, --0x24d40002, --0x7d654000, --0xcd400043, --0xce800043, --0xcd000043, --0xcc800040, --0xce400040, --0xce800040, --0xccc00040, --0xdc3a0000, --0x9780ffde, --0xcd000040, --0x7c40c000, --0x80000018, --0x7c410000, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x8000000c, --0x31980002, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x288c0008, --0x30cc000f, --0x34100001, --0x7d0d0008, --0x8000000c, --0x7d91800b, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc4003f9, --0x80000261, --0xcc4003f8, --0xc82003f8, --0xc81c03f9, --0xc81803fb, --0xc037ffff, --0x7c414000, --0xcf41a29e, --0x66200020, --0x7de1c02c, --0x7d58c008, --0x7cdcc020, --0x68d00020, --0xc0360003, --0xcc000054, --0x7cb4800c, --0x8000006a, --0xcc800040, --0x7c418000, --0xcd81a29e, --0xcc800040, --0xcd800040, --0x80000068, --0xcc000054, --0xc019ffff, --0xcc800040, --0xcd81a29e, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xcc400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc000054, --0xcc800040, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00001, --0xccc1a29f, --0x95000003, --0x04140001, --0x04140002, --0xcd4003fb, --0xcc800040, --0x80000000, --0xccc00040, --0x7c40c000, --0xcc800040, --0xccc1a2a2, --0x80000000, --0xccc00040, --0x7c40c000, --0x28d4001f, --0xcc800040, --0x95400003, --0x7c410000, --0xccc00057, --0x2918001f, --0xccc00040, --0x95800003, --0xcd000040, --0xcd000058, --0x80000261, --0xcc00007f, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0xca0c0010, --0x7c410000, --0x94c00004, --0x7c414000, --0xd42002c4, --0xcde00044, --0x9b00000b, --0x7c418000, --0xcc00004b, --0xcda00049, --0xcd200041, --0xcd600041, --0xcda00041, --0x06200001, --0xce000056, --0x80000261, --0xcc00007f, --0xc8280020, --0xc82c0021, --0xcc000063, --0x7eea4001, --0x65740020, --0x7f53402c, --0x269c0002, --0x7df5c020, --0x69f80020, --0xce80004b, --0xce600049, --0xcde00041, --0xcfa00041, --0xce600041, --0x271c0002, --0x7df5c020, --0x69f80020, --0x7db24001, --0xcf00004b, --0xce600049, --0xcde00041, --0xcfa00041, --0x800000bd, --0xce600041, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xca0c0010, --0x7c410000, --0x94c0000b, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0x800000b6, --0x7c414000, --0xcc000048, --0x800000ef, --0x00000000, --0xc8200017, --0xc81c0023, --0x0e240002, --0x99c00015, --0x7c418000, --0x0a200001, --0xce000056, --0xd4000440, --0xcc000040, --0xc036c000, --0xca140013, --0x96400007, --0x37747900, --0xcf400040, --0xcc000040, --0xc83003fa, --0x80000104, --0xcf000022, --0xcc000022, --0x9540015d, --0xcc00007f, --0xcca00046, --0x80000000, --0xcc200046, --0x80000261, --0xcc000064, --0xc8200017, --0xc810001f, --0x96000005, --0x09100001, --0xd4000440, --0xcd000040, --0xcd000022, --0xcc800040, --0xd0400040, --0xc80c0025, --0x94c0feeb, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0x7c40c000, --0x7c410000, --0xccc003fd, --0xcd0003fc, --0xccc00042, --0xcd000042, --0x2914001f, --0x29180010, --0x31980007, --0x3b5c0001, --0x7d76000b, --0x99800005, --0x7d5e400b, --0xcc000042, --0x80000261, --0xcc00004d, --0x29980001, --0x292c0008, --0x9980003d, --0x32ec0001, --0x96000004, --0x2930000c, --0x80000261, --0xcc000042, --0x04140010, --0xcd400042, --0x33300001, --0x34280001, --0x8400015e, --0xc8140003, --0x9b40001b, --0x0438000c, --0x8400015e, --0xc8140003, --0x9b400017, --0x04380008, --0x8400015e, --0xc8140003, --0x9b400013, --0x04380004, --0x8400015e, --0xc8140003, --0x9b400015, --0xc80c03fd, --0x9a800009, --0xc81003fc, --0x9b000118, --0xcc00004d, --0x04140010, --0xccc00042, --0xcd000042, --0x80000136, --0xcd400042, --0x96c00111, --0xcc00004d, --0x80000261, --0xcc00004e, --0x9ac00003, --0xcc00004d, --0xcc00004e, --0xdf830000, --0x80000000, --0xd80301ff, --0x9ac00107, --0xcc00004d, --0x80000261, --0xcc00004e, --0xc8180003, --0xc81c0003, --0xc8200003, --0x7d5d4003, --0x7da1c003, --0x7d5d400c, --0x2a10001f, --0x299c001f, --0x7d1d000b, --0x7d17400b, --0x88000000, --0x7e92800b, --0x96400004, --0xcc00004e, --0x80000261, --0xcc000042, --0x04380008, --0xcf800042, --0xc8080003, --0xc80c0003, --0xc8100003, --0xc8140003, --0xc8180003, --0xc81c0003, --0xc8240003, --0xc8280003, --0x29fc001f, --0x2ab0001f, --0x7ff3c00b, --0x28f0001f, --0x7ff3c00b, --0x2970001f, --0x7ff3c00b, --0x7d888001, --0x7dccc001, --0x7e510001, --0x7e954001, --0x7c908002, --0x7cd4c002, --0x7cbc800b, --0x9ac00003, --0x7c8f400b, --0x38b40001, --0x9b4000d8, --0xcc00004d, --0x9bc000d6, --0xcc00004e, --0xc80c03fd, --0xc81003fc, --0xccc00042, --0x8000016f, --0xcd000042, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xcc400040, --0xcc400040, --0xcc400040, --0x7c40c000, --0xccc00040, --0xccc0000d, --0x80000000, --0xd0400040, --0x7c40c000, --0x7c410000, --0x65140020, --0x7d4d402c, --0x24580002, --0x7d598020, --0x7c41c000, --0xcd800042, --0x69980020, --0xcd800042, --0xcdc00042, --0xc023c000, --0x05e40002, --0x7ca0800b, --0x26640010, --0x7ca4800c, --0xcc800040, --0xcdc00040, --0xccc00040, --0x95c0000e, --0xcd000040, --0x09dc0001, --0xc8280003, --0x96800008, --0xce800040, --0xc834001d, --0x97400000, --0xc834001d, --0x26a80008, --0x84000264, --0xcc2b0000, --0x99c0fff7, --0x09dc0001, --0xdc3a0000, --0x97800004, --0x7c418000, --0x800001a3, --0x25980002, --0xa0000000, --0x7d808000, --0xc818001d, --0x7c40c000, --0x64d00008, --0x95800000, --0xc818001d, --0xcc130000, --0xcc800040, --0xccc00040, --0x80000000, --0xcc400040, --0xc810001f, --0x7c40c000, --0xcc800040, --0x7cd1400c, --0xcd400040, --0x05180001, --0x80000000, --0xcd800022, --0x7c40c000, --0x64500020, --0x84000264, --0xcc000061, --0x7cd0c02c, --0xc8200017, --0xc8d60000, --0x99400008, --0x7c438000, --0xdf830000, --0xcfa0004f, --0x84000264, --0xcc000062, --0x80000000, --0xd040007f, --0x80000261, --0xcc000062, --0x84000264, --0xcc000061, --0xc8200017, --0x7c40c000, --0xc036ff00, --0xc810000d, --0xc0303fff, --0x7cf5400b, --0x7d51800b, --0x7d81800f, --0x99800008, --0x7cf3800b, --0xdf830000, --0xcfa0004f, --0x84000264, --0xcc000062, --0x80000000, --0xd040007f, --0x80000261, --0xcc000062, --0x84000264, --0x7c40c000, --0x28dc0008, --0x95c00019, --0x30dc0010, --0x7c410000, --0x99c00004, --0x64540020, --0x80000209, --0xc91d0000, --0x7d15002c, --0xc91e0000, --0x7c420000, --0x7c424000, --0x7c418000, --0x7de5c00b, --0x7de28007, --0x9a80000e, --0x41ac0005, --0x9ac00000, --0x0aec0001, --0x30dc0010, --0x99c00004, --0x00000000, --0x8000020c, --0xc91d0000, --0x8000020c, --0xc91e0000, --0xcc800040, --0xccc00040, --0xd0400040, --0xc80c0025, --0x94c0fde3, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00006, --0x0d100006, --0x99000007, --0xc8140015, --0x99400005, --0xcc000052, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xccc00040, --0x80000000, --0xd0400040, --0x7c40c000, --0xcc4d0000, --0xdc3a0000, --0x9780fdbc, --0x04cc0001, --0x80000243, --0xcc4d0000, --0x7c40c000, --0x7c410000, --0x29240018, --0x32640001, --0x9640000f, --0xcc800040, --0x7c414000, --0x7c418000, --0x7c41c000, --0xccc00043, --0xcd000043, --0x31dc7fff, --0xcdc00043, --0xccc00040, --0xcd000040, --0xcd400040, --0xcd800040, --0x80000000, --0xcdc00040, --0xccc00040, --0xcd000040, --0x80000000, --0xd0400040, --0x80000000, --0xd040007f, --0xcc00007f, --0x80000000, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00030223, --0x0004022b, --0x000500a0, --0x00020003, --0x0006003c, --0x00070027, --0x00080192, --0x00090044, --0x000a002d, --0x0010025f, --0x001700f1, --0x002201d8, --0x002301e9, --0x0026004c, --0x0027005f, --0x0020011b, --0x00280093, --0x0029004f, --0x002a0084, --0x002b0065, --0x002f008e, --0x003200d9, --0x00340233, --0x00360075, --0x0039010b, --0x003c01fd, --0x003f00a0, --0x00410248, --0x00440195, --0x0048019e, --0x004901c6, --0x004a01d0, --0x00550226, --0x0056022e, --0x0060000a, --0x0061002a, --0x00620030, --0x00630030, --0x00640030, --0x00650030, --0x00660030, --0x00670030, --0x00680037, --0x0069003f, --0x006a0047, --0x006b0047, --0x006c0047, --0x006d0047, --0x006e0047, --0x006f0047, --0x00700047, --0x0073025f, --0x007b0241, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --}; -- --static const u32 RV730_pfp_microcode[] = { --0x7c408000, --0xa0000000, --0x7e82800b, --0x80000000, --0xdc030000, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xc818000e, --0x31980001, --0x7c424000, --0x9580023a, --0x7c428000, --0xc81c001c, --0xc037c000, --0x7c40c000, --0x7c410000, --0x7cb4800b, --0xc0360003, --0x99c00000, --0xc81c001c, --0x7cb4800c, --0x24d40002, --0x7d654000, --0xcd400043, --0xce800043, --0xcd000043, --0xcc800040, --0xce400040, --0xce800040, --0xccc00040, --0xdc3a0000, --0x9780ffde, --0xcd000040, --0x7c40c000, --0x80000018, --0x7c410000, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x8000000c, --0x31980002, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x288c0008, --0x30cc000f, --0x34100001, --0x7d0d0008, --0x8000000c, --0x7d91800b, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc4003f9, --0x80000249, --0xcc4003f8, --0xc037ffff, --0x7c414000, --0xcf41a29e, --0xc82003f8, --0xc81c03f9, --0x66200020, --0xc81803fb, --0x7de1c02c, --0x7d58c008, --0x7cdcc020, --0x69100020, --0xc0360003, --0xcc000054, --0x7cb4800c, --0x80000069, --0xcc800040, --0x7c418000, --0xcd81a29e, --0xcc800040, --0x80000067, --0xcd800040, --0xc019ffff, --0xcc800040, --0xcd81a29e, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xcc400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc000054, --0xcc800040, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00001, --0xccc1a29f, --0x95000003, --0x04140001, --0x04140002, --0xcd4003fb, --0xcc800040, --0x80000000, --0xccc00040, --0x7c40c000, --0xcc800040, --0xccc1a2a2, --0x80000000, --0xccc00040, --0x7c40c000, --0x28d4001f, --0xcc800040, --0x95400003, --0x7c410000, --0xccc00057, --0x2918001f, --0xccc00040, --0x95800003, --0xcd000040, --0xcd000058, --0x80000249, --0xcc00007f, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0xca0c0010, --0x7c410000, --0x94c00004, --0x7c414000, --0xd42002c4, --0xcde00044, --0x9b00000b, --0x7c418000, --0xcc00004b, --0xcda00049, --0xcd200041, --0xcd600041, --0xcda00041, --0x06200001, --0xce000056, --0x80000249, --0xcc00007f, --0xc8280020, --0xc82c0021, --0xcc000063, --0x7eea4001, --0x65740020, --0x7f53402c, --0x269c0002, --0x7df5c020, --0x69f80020, --0xce80004b, --0xce600049, --0xcde00041, --0xcfa00041, --0xce600041, --0x271c0002, --0x7df5c020, --0x69f80020, --0x7db24001, --0xcf00004b, --0xce600049, --0xcde00041, --0xcfa00041, --0x800000bc, --0xce600041, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xca0c0010, --0x7c410000, --0x94c0000b, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0x800000b5, --0x7c414000, --0xcc000048, --0x800000ee, --0x00000000, --0xc8200017, --0xc81c0023, --0x0e240002, --0x99c00015, --0x7c418000, --0x0a200001, --0xce000056, --0xd4000440, --0xcc000040, --0xc036c000, --0xca140013, --0x96400007, --0x37747900, --0xcf400040, --0xcc000040, --0xc83003fa, --0x80000103, --0xcf000022, --0xcc000022, --0x95400146, --0xcc00007f, --0xcca00046, --0x80000000, --0xcc200046, --0x80000249, --0xcc000064, --0xc8200017, --0xc810001f, --0x96000005, --0x09100001, --0xd4000440, --0xcd000040, --0xcd000022, --0xcc800040, --0xd0400040, --0xc80c0025, --0x94c0feec, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0x7c40c000, --0x7c410000, --0xccc003fd, --0xcd0003fc, --0xccc00042, --0xcd000042, --0x2914001f, --0x29180010, --0x31980007, --0x3b5c0001, --0x7d76000b, --0x99800005, --0x7d5e400b, --0xcc000042, --0x80000249, --0xcc00004d, --0x29980001, --0x292c0008, --0x9980003d, --0x32ec0001, --0x96000004, --0x2930000c, --0x80000249, --0xcc000042, --0x04140010, --0xcd400042, --0x33300001, --0x34280001, --0x8400015d, --0xc8140003, --0x9b40001b, --0x0438000c, --0x8400015d, --0xc8140003, --0x9b400017, --0x04380008, --0x8400015d, --0xc8140003, --0x9b400013, --0x04380004, --0x8400015d, --0xc8140003, --0x9b400015, --0xc80c03fd, --0x9a800009, --0xc81003fc, --0x9b000101, --0xcc00004d, --0x04140010, --0xccc00042, --0xcd000042, --0x80000135, --0xcd400042, --0x96c000fa, --0xcc00004d, --0x80000249, --0xcc00004e, --0x9ac00003, --0xcc00004d, --0xcc00004e, --0xdf830000, --0x80000000, --0xd80301ff, --0x9ac000f0, --0xcc00004d, --0x80000249, --0xcc00004e, --0xc8180003, --0xc81c0003, --0xc8200003, --0x7d5d4003, --0x7da1c003, --0x7d5d400c, --0x2a10001f, --0x299c001f, --0x7d1d000b, --0x7d17400b, --0x88000000, --0x7e92800b, --0x96400004, --0xcc00004e, --0x80000249, --0xcc000042, --0x04380008, --0xcf800042, --0xc8080003, --0xc80c0003, --0xc8100003, --0xc8140003, --0xc8180003, --0xc81c0003, --0xc8240003, --0xc8280003, --0x29fc001f, --0x2ab0001f, --0x7ff3c00b, --0x28f0001f, --0x7ff3c00b, --0x2970001f, --0x7ff3c00b, --0x7d888001, --0x7dccc001, --0x7e510001, --0x7e954001, --0x7c908002, --0x7cd4c002, --0x7cbc800b, --0x9ac00003, --0x7c8f400b, --0x38b40001, --0x9b4000c1, --0xcc00004d, --0x9bc000bf, --0xcc00004e, --0xc80c03fd, --0xc81003fc, --0xccc00042, --0x8000016e, --0xcd000042, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xcc400040, --0xcc400040, --0xcc400040, --0x7c40c000, --0xccc00040, --0xccc0000d, --0x80000000, --0xd0400040, --0x7c40c000, --0x7c410000, --0x65140020, --0x7d4d402c, --0x24580002, --0x7d598020, --0x7c41c000, --0xcd800042, --0x69980020, --0xcd800042, --0xcdc00042, --0xc023c000, --0x05e40002, --0x7ca0800b, --0x26640010, --0x7ca4800c, --0xcc800040, --0xcdc00040, --0xccc00040, --0x95c0000e, --0xcd000040, --0x09dc0001, --0xc8280003, --0x96800008, --0xce800040, --0xc834001d, --0x97400000, --0xc834001d, --0x26a80008, --0x8400024c, --0xcc2b0000, --0x99c0fff7, --0x09dc0001, --0xdc3a0000, --0x97800004, --0x7c418000, --0x800001a2, --0x25980002, --0xa0000000, --0x7d808000, --0xc818001d, --0x7c40c000, --0x64d00008, --0x95800000, --0xc818001d, --0xcc130000, --0xcc800040, --0xccc00040, --0x80000000, --0xcc400040, --0xc810001f, --0x7c40c000, --0xcc800040, --0x7cd1400c, --0xcd400040, --0x05180001, --0x80000000, --0xcd800022, --0x7c40c000, --0x64500020, --0x8400024c, --0xcc000061, --0x7cd0c02c, --0xc8200017, --0xc8d60000, --0x99400008, --0x7c438000, --0xdf830000, --0xcfa0004f, --0x8400024c, --0xcc000062, --0x80000000, --0xd040007f, --0x80000249, --0xcc000062, --0x8400024c, --0xcc000061, --0xc8200017, --0x7c40c000, --0xc036ff00, --0xc810000d, --0xc0303fff, --0x7cf5400b, --0x7d51800b, --0x7d81800f, --0x99800008, --0x7cf3800b, --0xdf830000, --0xcfa0004f, --0x8400024c, --0xcc000062, --0x80000000, --0xd040007f, --0x80000249, --0xcc000062, --0x8400024c, --0x7c40c000, --0x28dc0008, --0x95c00019, --0x30dc0010, --0x7c410000, --0x99c00004, --0x64540020, --0x80000208, --0xc91d0000, --0x7d15002c, --0xc91e0000, --0x7c420000, --0x7c424000, --0x7c418000, --0x7de5c00b, --0x7de28007, --0x9a80000e, --0x41ac0005, --0x9ac00000, --0x0aec0001, --0x30dc0010, --0x99c00004, --0x00000000, --0x8000020b, --0xc91d0000, --0x8000020b, --0xc91e0000, --0xcc800040, --0xccc00040, --0xd0400040, --0xc80c0025, --0x94c0fde4, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00006, --0x0d100006, --0x99000007, --0xc8140015, --0x99400005, --0xcc000052, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xccc00040, --0x80000000, --0xd0400040, --0x7c40c000, --0xcc4d0000, --0xdc3a0000, --0x9780fdbd, --0x04cc0001, --0x80000242, --0xcc4d0000, --0x80000000, --0xd040007f, --0xcc00007f, --0x80000000, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00030222, --0x0004022a, --0x0005009f, --0x00020003, --0x0006003c, --0x00070027, --0x00080191, --0x00090044, --0x000a002d, --0x00100247, --0x001700f0, --0x002201d7, --0x002301e8, --0x0026004c, --0x0027005f, --0x0020011a, --0x00280092, --0x0029004f, --0x002a0083, --0x002b0064, --0x002f008d, --0x003200d8, --0x00340232, --0x00360074, --0x0039010a, --0x003c01fc, --0x003f009f, --0x00410005, --0x00440194, --0x0048019d, --0x004901c5, --0x004a01cf, --0x00550225, --0x0056022d, --0x0060000a, --0x0061002a, --0x00620030, --0x00630030, --0x00640030, --0x00650030, --0x00660030, --0x00670030, --0x00680037, --0x0069003f, --0x006a0047, --0x006b0047, --0x006c0047, --0x006d0047, --0x006e0047, --0x006f0047, --0x00700047, --0x00730247, --0x007b0240, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --}; -- --static const u32 RV730_cp_microcode[] = { --0xcc0003ea, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000001, --0xd040007f, --0x80000001, --0xcc400041, --0x7c40c000, --0xc0160004, --0x30d03fff, --0x7d15000c, --0xcc110000, --0x28d8001e, --0x31980001, --0x28dc001f, --0xc8200004, --0x95c00006, --0x7c424000, --0xcc000062, --0x7e56800c, --0xcc290000, --0xc8240004, --0x7e26000b, --0x95800006, --0x7c42c000, --0xcc000062, --0x7ed7000c, --0xcc310000, --0xc82c0004, --0x7e2e000c, --0xcc000062, --0x31103fff, --0x80000001, --0xce110000, --0x7c40c000, --0x80000001, --0xcc400040, --0x80000001, --0xcc412257, --0x7c418000, --0xcc400045, --0xcc400048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc400045, --0xcc400048, --0x7c40c000, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc000045, --0xcc000048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0x040ca1fd, --0xc0120001, --0xcc000045, --0xcc000048, --0x7cd0c00c, --0xcc41225c, --0xcc41a1fc, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000001, --0xcc41225d, --0x7c408000, --0x7c40c000, --0xc02a0002, --0x7c410000, --0x7d29000c, --0x30940001, --0x30980006, --0x309c0300, --0x29dc0008, --0x7c420000, --0x7c424000, --0x9540000f, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0xccc12169, --0xcd01216a, --0xce81216b, --0x0db40002, --0xcc01216c, --0x9740000e, --0x0db40000, --0x8000007b, --0xc834000a, --0x0db40002, --0x97400009, --0x0db40000, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0x8000007b, --0xc834000a, --0x97400004, --0x7e028000, --0x8000007b, --0xc834000a, --0x0db40004, --0x9740ff8c, --0x00000000, --0xce01216d, --0xce41216e, --0xc8280003, --0xc834000a, --0x9b400004, --0x043c0005, --0x8400026b, --0xcc000062, --0x0df40000, --0x9740000b, --0xc82c03e6, --0xce81a2b7, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c4, --0x80000001, --0xcfc1a2d1, --0x0df40001, --0x9740000b, --0xc82c03e7, --0xce81a2bb, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c5, --0x80000001, --0xcfc1a2d2, --0x0df40002, --0x9740000b, --0xc82c03e8, --0xce81a2bf, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c6, --0x80000001, --0xcfc1a2d3, --0xc82c03e9, --0xce81a2c3, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c7, --0x80000001, --0xcfc1a2d4, --0x80000001, --0xcc400042, --0x7c40c000, --0x7c410000, --0x2914001d, --0x31540001, --0x9940000c, --0x31181000, --0xc81c0011, --0x95c00000, --0xc81c0011, --0xccc12100, --0xcd012101, --0xccc12102, --0xcd012103, --0x04180004, --0x8000037c, --0xcd81a2a4, --0xc02a0004, --0x95800008, --0x36a821a3, --0xcc290000, --0xc8280004, --0xc81c0011, --0x0de40040, --0x9640ffff, --0xc81c0011, --0xccc12170, --0xcd012171, --0xc8200012, --0x96000000, --0xc8200012, --0x8000037c, --0xcc000064, --0x7c40c000, --0x7c410000, --0xcc000045, --0xcc000048, --0x40d40003, --0xcd41225c, --0xcd01a1fc, --0xc01a0001, --0x041ca1fd, --0x7dd9c00c, --0x7c420000, --0x08cc0001, --0x06240001, --0x06280002, --0xce1d0000, --0xce5d0000, --0x98c0fffa, --0xce9d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0x30d00001, --0x28cc0001, --0x7c414000, --0x95000006, --0x7c418000, --0xcd41216d, --0xcd81216e, --0x800000f2, --0xc81c0003, --0xc0220004, --0x7e16000c, --0xcc210000, --0xc81c0004, --0x7c424000, --0x98c00004, --0x7c428000, --0x80000001, --0xcde50000, --0xce412169, --0xce81216a, --0xcdc1216b, --0x80000001, --0xcc01216c, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x7c41c000, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9680000a, --0x7c020000, --0x7c420000, --0x1e300003, --0xcc00006a, --0x9b000003, --0x42200005, --0x04200040, --0x8000010f, --0x7c024000, --0x7e024000, --0x9a400000, --0x0a640001, --0x30ec0010, --0x9ac0000a, --0xcc000062, --0xc02a0004, --0xc82c0021, --0x7e92800c, --0xcc000041, --0xcc290000, --0xcec00021, --0x8000011f, --0xc8300004, --0xcd01216d, --0xcd41216e, --0xc8300003, --0x7f1f000b, --0x30f40007, --0x27780001, --0x9740002a, --0x07b80124, --0x9f800000, --0x00000000, --0x80000134, --0x7f1b8004, --0x80000138, --0x7f1b8005, --0x8000013c, --0x7f1b8002, --0x80000140, --0x7f1b8003, --0x80000144, --0x7f1b8007, --0x80000148, --0x7f1b8006, --0x8000014d, --0x28a40008, --0x9b800019, --0x28a40008, --0x8000015d, --0x326400ff, --0x9b800015, --0x28a40008, --0x8000015d, --0x326400ff, --0x9b800011, --0x28a40008, --0x8000015d, --0x326400ff, --0x9b80000d, --0x28a40008, --0x8000015d, --0x326400ff, --0x9b800009, --0x28a40008, --0x8000015d, --0x326400ff, --0x9b800005, --0x28a40008, --0x8000015d, --0x326400ff, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9a80feb2, --0x28ec0008, --0x7c434000, --0x7c438000, --0x7c43c000, --0x96c00007, --0xcc000062, --0xcf412169, --0xcf81216a, --0xcfc1216b, --0x80000001, --0xcc01216c, --0x80000001, --0xcff50000, --0xcc00006b, --0x8400037f, --0x0e68003c, --0x9a800004, --0xc8280015, --0x80000001, --0xd040007f, --0x9680ffab, --0x7e024000, --0x84000239, --0xc00e0002, --0xcc000041, --0x80000237, --0xccc1304a, --0x7c40c000, --0x7c410000, --0xc01e0001, --0x29240012, --0xc0220002, --0x96400005, --0xc0260004, --0xc027fffb, --0x7d25000b, --0xc0260000, --0x7dd2800b, --0x7e12c00b, --0x7d25000c, --0x7c414000, --0x7c418000, --0xccc12169, --0x9a80000a, --0xcd01216a, --0xcd41216b, --0x96c0fe83, --0xcd81216c, --0xc8300018, --0x97000000, --0xc8300018, --0x80000001, --0xcc000018, --0x8400037f, --0xcc00007f, --0xc8140013, --0xc8180014, --0xcd41216b, --0x96c0fe77, --0xcd81216c, --0x80000181, --0xc8300018, --0xc80c0008, --0x98c00000, --0xc80c0008, --0x7c410000, --0x95000002, --0x00000000, --0x7c414000, --0xc8200009, --0xcc400043, --0xce01a1f4, --0xcc400044, --0xc00e8000, --0x7c424000, --0x7c428000, --0x2aac001f, --0x96c0fe64, --0xc035f000, --0xce4003e2, --0x32780003, --0x267c0008, --0x7ff7c00b, --0x7ffbc00c, --0x2a780018, --0xcfc003e3, --0xcf8003e4, --0x26b00002, --0x7f3f0000, --0xcf0003e5, --0x8000031d, --0x7c80c000, --0x7c40c000, --0x28d00008, --0x3110000f, --0x9500000f, --0x25280001, --0x06a801b2, --0x9e800000, --0x00000000, --0x800001d3, --0xc0120800, --0x800001e1, --0xc814000f, --0x800001e8, --0xc8140010, --0x800001ef, --0xccc1a2a4, --0x800001f8, --0xc8140011, --0x30d0003f, --0x0d280015, --0x9a800012, --0x0d28001e, --0x9a80001e, --0x0d280020, --0x9a800023, --0x0d24000f, --0x0d280010, --0x7e6a800c, --0x9a800026, --0x0d200004, --0x0d240014, --0x0d280028, --0x7e62400c, --0x7ea6800c, --0x9a80002a, --0xc8140011, --0x80000001, --0xccc1a2a4, --0xc0120800, --0x7c414000, --0x7d0cc00c, --0xc0120008, --0x29580003, --0x295c000c, --0x7c420000, --0x7dd1c00b, --0x26200014, --0x7e1e400c, --0x7e4e800c, --0xce81a2a4, --0x80000001, --0xcd81a1fe, --0xc814000f, --0x0410210e, --0x95400000, --0xc814000f, --0xd0510000, --0x80000001, --0xccc1a2a4, --0xc8140010, --0x04102108, --0x95400000, --0xc8140010, --0xd0510000, --0x80000001, --0xccc1a2a4, --0xccc1a2a4, --0x04100001, --0xcd000019, --0x8400037f, --0xcc00007f, --0xc8100019, --0x99000000, --0xc8100019, --0x80000002, --0x7c408000, --0x04102100, --0x95400000, --0xc8140011, --0xd0510000, --0x8000037c, --0xccc1a2a4, --0x7c40c000, --0xcc40000d, --0x94c0fe01, --0xcc40000e, --0x7c410000, --0x95000005, --0x08cc0001, --0xc8140005, --0x99400014, --0x00000000, --0x98c0fffb, --0x7c410000, --0x80000002, --0x7d008000, --0xc8140005, --0x7c40c000, --0x9940000c, --0xc818000c, --0x7c410000, --0x9580fdf0, --0xc820000e, --0xc81c000d, --0x66200020, --0x7e1e002c, --0x25240002, --0x7e624020, --0x80000001, --0xcce60000, --0x7c410000, --0xcc00006c, --0xcc00006d, --0xc818001f, --0xc81c001e, --0x65980020, --0x7dd9c02c, --0x7cd4c00c, --0xccde0000, --0x45dc0004, --0xc8280017, --0x9680000f, --0xc00e0001, --0x28680008, --0x2aac0016, --0x32a800ff, --0x0eb00049, --0x7f2f000b, --0x97000006, --0x00000000, --0xc8140005, --0x7c40c000, --0x80000221, --0x7c410000, --0x80000224, --0xd040007f, --0x84000239, --0xcc000041, --0xccc1304a, --0x94000000, --0xc83c001a, --0x043c0005, --0xcfc1a2a4, --0xc0361f90, --0xc0387fff, --0x7c03c010, --0x7f7b400c, --0xcf41217c, --0xcfc1217d, --0xcc01217e, --0xc03a0004, --0x0434217f, --0x7f7b400c, --0xcc350000, --0xc83c0004, --0x2bfc001f, --0x04380020, --0x97c00005, --0xcc000062, --0x9b800000, --0x0bb80001, --0x80000245, --0xcc000071, --0xcc01a1f4, --0x04380016, --0xc0360002, --0xcf81a2a4, --0x88000000, --0xcf412010, --0x7c40c000, --0x28d0001c, --0x95000005, --0x04d40001, --0xcd400065, --0x80000001, --0xcd400068, --0x09540002, --0x80000001, --0xcd400066, --0x8400026a, --0xc81803ea, --0x7c40c000, --0x9980fd9f, --0xc8140016, --0x08d00001, --0x9940002b, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0005, --0xcfc1a2a4, --0xcc01a1f4, --0x8400037f, --0xcc000046, --0x88000000, --0xcc00007f, --0x8400027c, --0xc81803ea, --0x7c40c000, --0x9980fd8d, --0xc8140016, --0x08d00001, --0x99400019, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0022, --0xcfc1a2a4, --0x8400037f, --0xcc000047, --0x88000000, --0xcc00007f, --0xc8100016, --0x9900000d, --0xcc400067, --0x80000002, --0x7c408000, --0xc81803ea, --0x9980fd79, --0x7c40c000, --0x94c00003, --0xc8100016, --0x99000004, --0xccc00068, --0x80000002, --0x7c408000, --0x84000239, --0xc0148000, --0xcc000041, --0xcd41304a, --0xc0148000, --0x99000000, --0xc8100016, --0x80000002, --0x7c408000, --0xc0120001, --0x7c51400c, --0x80000001, --0xd0550000, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x291c001f, --0xccc0004a, --0xcd00004b, --0x95c00003, --0xc01c8000, --0xcdc12010, --0xdd830000, --0x055c2000, --0xcc000062, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004c, --0xcd00004d, --0xdd830000, --0x055ca000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004e, --0xcd00004f, --0xdd830000, --0x055cc000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00050, --0xcd000051, --0xdd830000, --0x055cf8e0, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00052, --0xcd000053, --0xdd830000, --0x055cf880, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00054, --0xcd000055, --0xdd830000, --0x055ce000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00056, --0xcd000057, --0xdd830000, --0x055cf000, --0x80000001, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00058, --0xcd000059, --0xdd830000, --0x055cf3fc, --0x80000001, --0xd81f4100, --0xd0432000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043a000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043c000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f8e0, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f880, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043e000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f3fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xc81403e0, --0xcc430000, --0xcc430000, --0xcc430000, --0x7d45c000, --0xcdc30000, --0xd0430000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0xc81003e2, --0xc81403e5, --0xc81803e3, --0xc81c03e4, --0xcd812169, --0xcdc1216a, --0xccc1216b, --0xcc01216c, --0x04200004, --0x7da18000, --0x7d964002, --0x9640fcd9, --0xcd8003e3, --0x31280003, --0xc02df000, --0x25180008, --0x7dad800b, --0x7da9800c, --0x80000001, --0xcd8003e3, --0x308cffff, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0xc8140020, --0x15580002, --0x9580ffff, --0xc8140020, --0xcc00006e, --0xcc412180, --0x7c40c000, --0xccc1218d, --0xcc412181, --0x28d0001f, --0x34588000, --0xcd81218c, --0x9500fcbf, --0xcc412182, --0xc8140020, --0x9940ffff, --0xc8140020, --0x80000002, --0x7c408000, --0x7c40c000, --0x28d00018, --0x31100001, --0xc0160080, --0x95000003, --0xc02a0004, --0x7cd4c00c, --0xccc1217c, --0xcc41217d, --0xcc41217e, --0x7c418000, --0x1db00003, --0x36a0217f, --0x9b000003, --0x419c0005, --0x041c0040, --0x99c00000, --0x09dc0001, --0xcc210000, --0xc8240004, --0x2a6c001f, --0x419c0005, --0x9ac0fffa, --0xcc800062, --0x80000002, --0x7c408000, --0x7c40c000, --0x04d403e6, --0x80000001, --0xcc540000, --0x8000037c, --0xcc4003ea, --0xc01c8000, --0x044ca000, --0xcdc12010, --0x7c410000, --0xc8140009, --0x04180000, --0x041c0008, --0xcd800071, --0x09dc0001, --0x05980001, --0xcd0d0000, --0x99c0fffc, --0xcc800062, --0x8000037c, --0xcd400071, --0xc00e0100, --0xcc000041, --0xccc1304a, --0xc83c007f, --0xcc00007f, --0x80000001, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00010331, --0x00100004, --0x00170006, --0x00210008, --0x00270028, --0x00280023, --0x00290029, --0x002a0026, --0x002b0029, --0x002d0038, --0x002e003f, --0x002f004a, --0x0034004c, --0x00360030, --0x003900af, --0x003a00cf, --0x003b00e4, --0x003c00fc, --0x003d016b, --0x003f00ad, --0x00410336, --0x00430349, --0x0044018e, --0x004500fc, --0x004601ac, --0x004701ac, --0x004801fe, --0x0049020c, --0x004a0255, --0x004b0282, --0x0052025f, --0x00530271, --0x00540287, --0x00570299, --0x0060029d, --0x006102ac, --0x006202b6, --0x006302c0, --0x006402ca, --0x006502d4, --0x006602de, --0x006702e8, --0x006802f2, --0x006902f6, --0x006a02fa, --0x006b02fe, --0x006c0302, --0x006d0306, --0x006e030a, --0x006f030e, --0x00700312, --0x00720363, --0x00740369, --0x00790367, --0x007c031c, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --0x000f0378, --}; -- --static const u32 RV710_pfp_microcode[] = { --0x7c408000, --0xa0000000, --0x7e82800b, --0x80000000, --0xdc030000, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xc818000e, --0x31980001, --0x7c424000, --0x9580023a, --0x7c428000, --0xc81c001c, --0xc037c000, --0x7c40c000, --0x7c410000, --0x7cb4800b, --0xc0360003, --0x99c00000, --0xc81c001c, --0x7cb4800c, --0x24d40002, --0x7d654000, --0xcd400043, --0xce800043, --0xcd000043, --0xcc800040, --0xce400040, --0xce800040, --0xccc00040, --0xdc3a0000, --0x9780ffde, --0xcd000040, --0x7c40c000, --0x80000018, --0x7c410000, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x8000000c, --0x31980002, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xc818000e, --0x288c0008, --0x30cc000f, --0x34100001, --0x7d0d0008, --0x8000000c, --0x7d91800b, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc4003f9, --0x80000249, --0xcc4003f8, --0xc037ffff, --0x7c414000, --0xcf41a29e, --0xc82003f8, --0xc81c03f9, --0x66200020, --0xc81803fb, --0x7de1c02c, --0x7d58c008, --0x7cdcc020, --0x69100020, --0xc0360003, --0xcc000054, --0x7cb4800c, --0x80000069, --0xcc800040, --0x7c418000, --0xcd81a29e, --0xcc800040, --0x80000067, --0xcd800040, --0xc019ffff, --0xcc800040, --0xcd81a29e, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xcc400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xcc000054, --0xcc800040, --0x7c40c000, --0x7c410000, --0x7c414000, --0xccc1a1fa, --0xcd01a1f9, --0xcd41a29d, --0xccc00040, --0xcd000040, --0xcd400040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00001, --0xccc1a29f, --0x95000003, --0x04140001, --0x04140002, --0xcd4003fb, --0xcc800040, --0x80000000, --0xccc00040, --0x7c40c000, --0xcc800040, --0xccc1a2a2, --0x80000000, --0xccc00040, --0x7c40c000, --0x28d4001f, --0xcc800040, --0x95400003, --0x7c410000, --0xccc00057, --0x2918001f, --0xccc00040, --0x95800003, --0xcd000040, --0xcd000058, --0x80000249, --0xcc00007f, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0xca0c0010, --0x7c410000, --0x94c00004, --0x7c414000, --0xd42002c4, --0xcde00044, --0x9b00000b, --0x7c418000, --0xcc00004b, --0xcda00049, --0xcd200041, --0xcd600041, --0xcda00041, --0x06200001, --0xce000056, --0x80000249, --0xcc00007f, --0xc8280020, --0xc82c0021, --0xcc000063, --0x7eea4001, --0x65740020, --0x7f53402c, --0x269c0002, --0x7df5c020, --0x69f80020, --0xce80004b, --0xce600049, --0xcde00041, --0xcfa00041, --0xce600041, --0x271c0002, --0x7df5c020, --0x69f80020, --0x7db24001, --0xcf00004b, --0xce600049, --0xcde00041, --0xcfa00041, --0x800000bc, --0xce600041, --0xc8200017, --0xc8300022, --0x9a000006, --0x0e280001, --0xc824001e, --0x0a640001, --0xd4001240, --0xce400040, --0xca0c0010, --0x7c410000, --0x94c0000b, --0xc036c000, --0x96800007, --0x37747900, --0x041c0001, --0xcf400040, --0xcdc00040, --0xcf0003fa, --0x7c030000, --0x800000b5, --0x7c414000, --0xcc000048, --0x800000ee, --0x00000000, --0xc8200017, --0xc81c0023, --0x0e240002, --0x99c00015, --0x7c418000, --0x0a200001, --0xce000056, --0xd4000440, --0xcc000040, --0xc036c000, --0xca140013, --0x96400007, --0x37747900, --0xcf400040, --0xcc000040, --0xc83003fa, --0x80000103, --0xcf000022, --0xcc000022, --0x95400146, --0xcc00007f, --0xcca00046, --0x80000000, --0xcc200046, --0x80000249, --0xcc000064, --0xc8200017, --0xc810001f, --0x96000005, --0x09100001, --0xd4000440, --0xcd000040, --0xcd000022, --0xcc800040, --0xd0400040, --0xc80c0025, --0x94c0feec, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0x7c40c000, --0x7c410000, --0xccc003fd, --0xcd0003fc, --0xccc00042, --0xcd000042, --0x2914001f, --0x29180010, --0x31980007, --0x3b5c0001, --0x7d76000b, --0x99800005, --0x7d5e400b, --0xcc000042, --0x80000249, --0xcc00004d, --0x29980001, --0x292c0008, --0x9980003d, --0x32ec0001, --0x96000004, --0x2930000c, --0x80000249, --0xcc000042, --0x04140010, --0xcd400042, --0x33300001, --0x34280001, --0x8400015d, --0xc8140003, --0x9b40001b, --0x0438000c, --0x8400015d, --0xc8140003, --0x9b400017, --0x04380008, --0x8400015d, --0xc8140003, --0x9b400013, --0x04380004, --0x8400015d, --0xc8140003, --0x9b400015, --0xc80c03fd, --0x9a800009, --0xc81003fc, --0x9b000101, --0xcc00004d, --0x04140010, --0xccc00042, --0xcd000042, --0x80000135, --0xcd400042, --0x96c000fa, --0xcc00004d, --0x80000249, --0xcc00004e, --0x9ac00003, --0xcc00004d, --0xcc00004e, --0xdf830000, --0x80000000, --0xd80301ff, --0x9ac000f0, --0xcc00004d, --0x80000249, --0xcc00004e, --0xc8180003, --0xc81c0003, --0xc8200003, --0x7d5d4003, --0x7da1c003, --0x7d5d400c, --0x2a10001f, --0x299c001f, --0x7d1d000b, --0x7d17400b, --0x88000000, --0x7e92800b, --0x96400004, --0xcc00004e, --0x80000249, --0xcc000042, --0x04380008, --0xcf800042, --0xc8080003, --0xc80c0003, --0xc8100003, --0xc8140003, --0xc8180003, --0xc81c0003, --0xc8240003, --0xc8280003, --0x29fc001f, --0x2ab0001f, --0x7ff3c00b, --0x28f0001f, --0x7ff3c00b, --0x2970001f, --0x7ff3c00b, --0x7d888001, --0x7dccc001, --0x7e510001, --0x7e954001, --0x7c908002, --0x7cd4c002, --0x7cbc800b, --0x9ac00003, --0x7c8f400b, --0x38b40001, --0x9b4000c1, --0xcc00004d, --0x9bc000bf, --0xcc00004e, --0xc80c03fd, --0xc81003fc, --0xccc00042, --0x8000016e, --0xcd000042, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xcc400040, --0xcc400040, --0xcc400040, --0x7c40c000, --0xccc00040, --0xccc0000d, --0x80000000, --0xd0400040, --0x7c40c000, --0x7c410000, --0x65140020, --0x7d4d402c, --0x24580002, --0x7d598020, --0x7c41c000, --0xcd800042, --0x69980020, --0xcd800042, --0xcdc00042, --0xc023c000, --0x05e40002, --0x7ca0800b, --0x26640010, --0x7ca4800c, --0xcc800040, --0xcdc00040, --0xccc00040, --0x95c0000e, --0xcd000040, --0x09dc0001, --0xc8280003, --0x96800008, --0xce800040, --0xc834001d, --0x97400000, --0xc834001d, --0x26a80008, --0x8400024c, --0xcc2b0000, --0x99c0fff7, --0x09dc0001, --0xdc3a0000, --0x97800004, --0x7c418000, --0x800001a2, --0x25980002, --0xa0000000, --0x7d808000, --0xc818001d, --0x7c40c000, --0x64d00008, --0x95800000, --0xc818001d, --0xcc130000, --0xcc800040, --0xccc00040, --0x80000000, --0xcc400040, --0xc810001f, --0x7c40c000, --0xcc800040, --0x7cd1400c, --0xcd400040, --0x05180001, --0x80000000, --0xcd800022, --0x7c40c000, --0x64500020, --0x8400024c, --0xcc000061, --0x7cd0c02c, --0xc8200017, --0xc8d60000, --0x99400008, --0x7c438000, --0xdf830000, --0xcfa0004f, --0x8400024c, --0xcc000062, --0x80000000, --0xd040007f, --0x80000249, --0xcc000062, --0x8400024c, --0xcc000061, --0xc8200017, --0x7c40c000, --0xc036ff00, --0xc810000d, --0xc0303fff, --0x7cf5400b, --0x7d51800b, --0x7d81800f, --0x99800008, --0x7cf3800b, --0xdf830000, --0xcfa0004f, --0x8400024c, --0xcc000062, --0x80000000, --0xd040007f, --0x80000249, --0xcc000062, --0x8400024c, --0x7c40c000, --0x28dc0008, --0x95c00019, --0x30dc0010, --0x7c410000, --0x99c00004, --0x64540020, --0x80000208, --0xc91d0000, --0x7d15002c, --0xc91e0000, --0x7c420000, --0x7c424000, --0x7c418000, --0x7de5c00b, --0x7de28007, --0x9a80000e, --0x41ac0005, --0x9ac00000, --0x0aec0001, --0x30dc0010, --0x99c00004, --0x00000000, --0x8000020b, --0xc91d0000, --0x8000020b, --0xc91e0000, --0xcc800040, --0xccc00040, --0xd0400040, --0xc80c0025, --0x94c0fde4, --0xc8100008, --0xcd000040, --0xd4000fc0, --0x80000000, --0xd4000fa2, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0xd40003c0, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xd0400040, --0x7c408000, --0xa0000000, --0x7e82800b, --0x7c40c000, --0x30d00006, --0x0d100006, --0x99000007, --0xc8140015, --0x99400005, --0xcc000052, --0xd4000340, --0xd4000fc0, --0xd4000fa2, --0xcc800040, --0xccc00040, --0x80000000, --0xd0400040, --0x7c40c000, --0xcc4d0000, --0xdc3a0000, --0x9780fdbd, --0x04cc0001, --0x80000242, --0xcc4d0000, --0x80000000, --0xd040007f, --0xcc00007f, --0x80000000, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00030222, --0x0004022a, --0x0005009f, --0x00020003, --0x0006003c, --0x00070027, --0x00080191, --0x00090044, --0x000a002d, --0x00100247, --0x001700f0, --0x002201d7, --0x002301e8, --0x0026004c, --0x0027005f, --0x0020011a, --0x00280092, --0x0029004f, --0x002a0083, --0x002b0064, --0x002f008d, --0x003200d8, --0x00340232, --0x00360074, --0x0039010a, --0x003c01fc, --0x003f009f, --0x00410005, --0x00440194, --0x0048019d, --0x004901c5, --0x004a01cf, --0x00550225, --0x0056022d, --0x0060000a, --0x0061002a, --0x00620030, --0x00630030, --0x00640030, --0x00650030, --0x00660030, --0x00670030, --0x00680037, --0x0069003f, --0x006a0047, --0x006b0047, --0x006c0047, --0x006d0047, --0x006e0047, --0x006f0047, --0x00700047, --0x00730247, --0x007b0240, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --0x00000005, --}; -- --static const u32 RV710_cp_microcode[] = { --0xcc0003ea, --0x04080003, --0xcc800043, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000003, --0xd040007f, --0x80000003, --0xcc400041, --0x7c40c000, --0xc0160004, --0x30d03fff, --0x7d15000c, --0xcc110000, --0x28d8001e, --0x31980001, --0x28dc001f, --0xc8200004, --0x95c00006, --0x7c424000, --0xcc000062, --0x7e56800c, --0xcc290000, --0xc8240004, --0x7e26000b, --0x95800006, --0x7c42c000, --0xcc000062, --0x7ed7000c, --0xcc310000, --0xc82c0004, --0x7e2e000c, --0xcc000062, --0x31103fff, --0x80000003, --0xce110000, --0x7c40c000, --0x80000003, --0xcc400040, --0x80000003, --0xcc412257, --0x7c418000, --0xcc400045, --0xcc400048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc400045, --0xcc400048, --0x7c40c000, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xcc000045, --0xcc000048, --0xcc41225c, --0xcc41a1fc, --0x7c408000, --0xa0000000, --0xcc800062, --0x040ca1fd, --0xc0120001, --0xcc000045, --0xcc000048, --0x7cd0c00c, --0xcc41225c, --0xcc41a1fc, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x80000003, --0xcc41225d, --0x7c408000, --0x7c40c000, --0xc02a0002, --0x7c410000, --0x7d29000c, --0x30940001, --0x30980006, --0x309c0300, --0x29dc0008, --0x7c420000, --0x7c424000, --0x9540000f, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0xccc12169, --0xcd01216a, --0xce81216b, --0x0db40002, --0xcc01216c, --0x9740000e, --0x0db40000, --0x8000007d, --0xc834000a, --0x0db40002, --0x97400009, --0x0db40000, --0xc02e0004, --0x05f02258, --0x7f2f000c, --0xcc310000, --0xc8280004, --0x8000007d, --0xc834000a, --0x97400004, --0x7e028000, --0x8000007d, --0xc834000a, --0x0db40004, --0x9740ff8c, --0x00000000, --0xce01216d, --0xce41216e, --0xc8280003, --0xc834000a, --0x9b400004, --0x043c0005, --0x8400026d, --0xcc000062, --0x0df40000, --0x9740000b, --0xc82c03e6, --0xce81a2b7, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c4, --0x80000003, --0xcfc1a2d1, --0x0df40001, --0x9740000b, --0xc82c03e7, --0xce81a2bb, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c5, --0x80000003, --0xcfc1a2d2, --0x0df40002, --0x9740000b, --0xc82c03e8, --0xce81a2bf, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c6, --0x80000003, --0xcfc1a2d3, --0xc82c03e9, --0xce81a2c3, --0xc0300006, --0x7ef34028, --0xc0300020, --0x7f6b8020, --0x7fb3c029, --0xcf81a2c7, --0x80000003, --0xcfc1a2d4, --0x80000003, --0xcc400042, --0x7c40c000, --0x7c410000, --0x2914001d, --0x31540001, --0x9940000c, --0x31181000, --0xc81c0011, --0x95c00000, --0xc81c0011, --0xccc12100, --0xcd012101, --0xccc12102, --0xcd012103, --0x04180004, --0x8000037e, --0xcd81a2a4, --0xc02a0004, --0x95800008, --0x36a821a3, --0xcc290000, --0xc8280004, --0xc81c0011, --0x0de40040, --0x9640ffff, --0xc81c0011, --0xccc12170, --0xcd012171, --0xc8200012, --0x96000000, --0xc8200012, --0x8000037e, --0xcc000064, --0x7c40c000, --0x7c410000, --0xcc000045, --0xcc000048, --0x40d40003, --0xcd41225c, --0xcd01a1fc, --0xc01a0001, --0x041ca1fd, --0x7dd9c00c, --0x7c420000, --0x08cc0001, --0x06240001, --0x06280002, --0xce1d0000, --0xce5d0000, --0x98c0fffa, --0xce9d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0x30d00001, --0x28cc0001, --0x7c414000, --0x95000006, --0x7c418000, --0xcd41216d, --0xcd81216e, --0x800000f4, --0xc81c0003, --0xc0220004, --0x7e16000c, --0xcc210000, --0xc81c0004, --0x7c424000, --0x98c00004, --0x7c428000, --0x80000003, --0xcde50000, --0xce412169, --0xce81216a, --0xcdc1216b, --0x80000003, --0xcc01216c, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x7c41c000, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9680000a, --0x7c020000, --0x7c420000, --0x1e300003, --0xcc00006a, --0x9b000003, --0x42200005, --0x04200040, --0x80000111, --0x7c024000, --0x7e024000, --0x9a400000, --0x0a640001, --0x30ec0010, --0x9ac0000a, --0xcc000062, --0xc02a0004, --0xc82c0021, --0x7e92800c, --0xcc000041, --0xcc290000, --0xcec00021, --0x80000121, --0xc8300004, --0xcd01216d, --0xcd41216e, --0xc8300003, --0x7f1f000b, --0x30f40007, --0x27780001, --0x9740002a, --0x07b80126, --0x9f800000, --0x00000000, --0x80000136, --0x7f1b8004, --0x8000013a, --0x7f1b8005, --0x8000013e, --0x7f1b8002, --0x80000142, --0x7f1b8003, --0x80000146, --0x7f1b8007, --0x8000014a, --0x7f1b8006, --0x8000014f, --0x28a40008, --0x9b800019, --0x28a40008, --0x8000015f, --0x326400ff, --0x9b800015, --0x28a40008, --0x8000015f, --0x326400ff, --0x9b800011, --0x28a40008, --0x8000015f, --0x326400ff, --0x9b80000d, --0x28a40008, --0x8000015f, --0x326400ff, --0x9b800009, --0x28a40008, --0x8000015f, --0x326400ff, --0x9b800005, --0x28a40008, --0x8000015f, --0x326400ff, --0x28a40008, --0x326400ff, --0x0e68003c, --0x9a80feb2, --0x28ec0008, --0x7c434000, --0x7c438000, --0x7c43c000, --0x96c00007, --0xcc000062, --0xcf412169, --0xcf81216a, --0xcfc1216b, --0x80000003, --0xcc01216c, --0x80000003, --0xcff50000, --0xcc00006b, --0x84000381, --0x0e68003c, --0x9a800004, --0xc8280015, --0x80000003, --0xd040007f, --0x9680ffab, --0x7e024000, --0x8400023b, --0xc00e0002, --0xcc000041, --0x80000239, --0xccc1304a, --0x7c40c000, --0x7c410000, --0xc01e0001, --0x29240012, --0xc0220002, --0x96400005, --0xc0260004, --0xc027fffb, --0x7d25000b, --0xc0260000, --0x7dd2800b, --0x7e12c00b, --0x7d25000c, --0x7c414000, --0x7c418000, --0xccc12169, --0x9a80000a, --0xcd01216a, --0xcd41216b, --0x96c0fe83, --0xcd81216c, --0xc8300018, --0x97000000, --0xc8300018, --0x80000003, --0xcc000018, --0x84000381, --0xcc00007f, --0xc8140013, --0xc8180014, --0xcd41216b, --0x96c0fe77, --0xcd81216c, --0x80000183, --0xc8300018, --0xc80c0008, --0x98c00000, --0xc80c0008, --0x7c410000, --0x95000002, --0x00000000, --0x7c414000, --0xc8200009, --0xcc400043, --0xce01a1f4, --0xcc400044, --0xc00e8000, --0x7c424000, --0x7c428000, --0x2aac001f, --0x96c0fe64, --0xc035f000, --0xce4003e2, --0x32780003, --0x267c0008, --0x7ff7c00b, --0x7ffbc00c, --0x2a780018, --0xcfc003e3, --0xcf8003e4, --0x26b00002, --0x7f3f0000, --0xcf0003e5, --0x8000031f, --0x7c80c000, --0x7c40c000, --0x28d00008, --0x3110000f, --0x9500000f, --0x25280001, --0x06a801b4, --0x9e800000, --0x00000000, --0x800001d5, --0xc0120800, --0x800001e3, --0xc814000f, --0x800001ea, --0xc8140010, --0x800001f1, --0xccc1a2a4, --0x800001fa, --0xc8140011, --0x30d0003f, --0x0d280015, --0x9a800012, --0x0d28001e, --0x9a80001e, --0x0d280020, --0x9a800023, --0x0d24000f, --0x0d280010, --0x7e6a800c, --0x9a800026, --0x0d200004, --0x0d240014, --0x0d280028, --0x7e62400c, --0x7ea6800c, --0x9a80002a, --0xc8140011, --0x80000003, --0xccc1a2a4, --0xc0120800, --0x7c414000, --0x7d0cc00c, --0xc0120008, --0x29580003, --0x295c000c, --0x7c420000, --0x7dd1c00b, --0x26200014, --0x7e1e400c, --0x7e4e800c, --0xce81a2a4, --0x80000003, --0xcd81a1fe, --0xc814000f, --0x0410210e, --0x95400000, --0xc814000f, --0xd0510000, --0x80000003, --0xccc1a2a4, --0xc8140010, --0x04102108, --0x95400000, --0xc8140010, --0xd0510000, --0x80000003, --0xccc1a2a4, --0xccc1a2a4, --0x04100001, --0xcd000019, --0x84000381, --0xcc00007f, --0xc8100019, --0x99000000, --0xc8100019, --0x80000004, --0x7c408000, --0x04102100, --0x95400000, --0xc8140011, --0xd0510000, --0x8000037e, --0xccc1a2a4, --0x7c40c000, --0xcc40000d, --0x94c0fe01, --0xcc40000e, --0x7c410000, --0x95000005, --0x08cc0001, --0xc8140005, --0x99400014, --0x00000000, --0x98c0fffb, --0x7c410000, --0x80000004, --0x7d008000, --0xc8140005, --0x7c40c000, --0x9940000c, --0xc818000c, --0x7c410000, --0x9580fdf0, --0xc820000e, --0xc81c000d, --0x66200020, --0x7e1e002c, --0x25240002, --0x7e624020, --0x80000003, --0xcce60000, --0x7c410000, --0xcc00006c, --0xcc00006d, --0xc818001f, --0xc81c001e, --0x65980020, --0x7dd9c02c, --0x7cd4c00c, --0xccde0000, --0x45dc0004, --0xc8280017, --0x9680000f, --0xc00e0001, --0x28680008, --0x2aac0016, --0x32a800ff, --0x0eb00049, --0x7f2f000b, --0x97000006, --0x00000000, --0xc8140005, --0x7c40c000, --0x80000223, --0x7c410000, --0x80000226, --0xd040007f, --0x8400023b, --0xcc000041, --0xccc1304a, --0x94000000, --0xc83c001a, --0x043c0005, --0xcfc1a2a4, --0xc0361f90, --0xc0387fff, --0x7c03c010, --0x7f7b400c, --0xcf41217c, --0xcfc1217d, --0xcc01217e, --0xc03a0004, --0x0434217f, --0x7f7b400c, --0xcc350000, --0xc83c0004, --0x2bfc001f, --0x04380020, --0x97c00005, --0xcc000062, --0x9b800000, --0x0bb80001, --0x80000247, --0xcc000071, --0xcc01a1f4, --0x04380016, --0xc0360002, --0xcf81a2a4, --0x88000000, --0xcf412010, --0x7c40c000, --0x28d0001c, --0x95000005, --0x04d40001, --0xcd400065, --0x80000003, --0xcd400068, --0x09540002, --0x80000003, --0xcd400066, --0x8400026c, --0xc81803ea, --0x7c40c000, --0x9980fd9f, --0xc8140016, --0x08d00001, --0x9940002b, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0005, --0xcfc1a2a4, --0xcc01a1f4, --0x84000381, --0xcc000046, --0x88000000, --0xcc00007f, --0x8400027e, --0xc81803ea, --0x7c40c000, --0x9980fd8d, --0xc8140016, --0x08d00001, --0x99400019, --0xcd000068, --0x7c408000, --0xa0000000, --0xcc800062, --0x043c0022, --0xcfc1a2a4, --0x84000381, --0xcc000047, --0x88000000, --0xcc00007f, --0xc8100016, --0x9900000d, --0xcc400067, --0x80000004, --0x7c408000, --0xc81803ea, --0x9980fd79, --0x7c40c000, --0x94c00003, --0xc8100016, --0x99000004, --0xccc00068, --0x80000004, --0x7c408000, --0x8400023b, --0xc0148000, --0xcc000041, --0xcd41304a, --0xc0148000, --0x99000000, --0xc8100016, --0x80000004, --0x7c408000, --0xc0120001, --0x7c51400c, --0x80000003, --0xd0550000, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0x291c001f, --0xccc0004a, --0xcd00004b, --0x95c00003, --0xc01c8000, --0xcdc12010, --0xdd830000, --0x055c2000, --0xcc000062, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004c, --0xcd00004d, --0xdd830000, --0x055ca000, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc0004e, --0xcd00004f, --0xdd830000, --0x055cc000, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00050, --0xcd000051, --0xdd830000, --0x055cf8e0, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00052, --0xcd000053, --0xdd830000, --0x055cf880, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00054, --0xcd000055, --0xdd830000, --0x055ce000, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00056, --0xcd000057, --0xdd830000, --0x055cf000, --0x80000003, --0xd81f4100, --0x7c40c000, --0x7c410000, --0x7c414000, --0x7c418000, --0xccc00058, --0xcd000059, --0xdd830000, --0x055cf3fc, --0x80000003, --0xd81f4100, --0xd0432000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043a000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043c000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f8e0, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f880, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043e000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f000, --0x7c408000, --0xa0000000, --0xcc800062, --0xd043f3fc, --0x7c408000, --0xa0000000, --0xcc800062, --0xc81403e0, --0xcc430000, --0xcc430000, --0xcc430000, --0x7d45c000, --0xcdc30000, --0xd0430000, --0x7c408000, --0xa0000000, --0xcc800062, --0x7c40c000, --0xc81003e2, --0xc81403e5, --0xc81803e3, --0xc81c03e4, --0xcd812169, --0xcdc1216a, --0xccc1216b, --0xcc01216c, --0x04200004, --0x7da18000, --0x7d964002, --0x9640fcd9, --0xcd8003e3, --0x31280003, --0xc02df000, --0x25180008, --0x7dad800b, --0x7da9800c, --0x80000003, --0xcd8003e3, --0x308cffff, --0xd04d0000, --0x7c408000, --0xa0000000, --0xcc800062, --0xc8140020, --0x15580002, --0x9580ffff, --0xc8140020, --0xcc00006e, --0xcc412180, --0x7c40c000, --0xccc1218d, --0xcc412181, --0x28d0001f, --0x34588000, --0xcd81218c, --0x9500fcbf, --0xcc412182, --0xc8140020, --0x9940ffff, --0xc8140020, --0x80000004, --0x7c408000, --0x7c40c000, --0x28d00018, --0x31100001, --0xc0160080, --0x95000003, --0xc02a0004, --0x7cd4c00c, --0xccc1217c, --0xcc41217d, --0xcc41217e, --0x7c418000, --0x1db00003, --0x36a0217f, --0x9b000003, --0x419c0005, --0x041c0040, --0x99c00000, --0x09dc0001, --0xcc210000, --0xc8240004, --0x2a6c001f, --0x419c0005, --0x9ac0fffa, --0xcc800062, --0x80000004, --0x7c408000, --0x7c40c000, --0x04d403e6, --0x80000003, --0xcc540000, --0x8000037e, --0xcc4003ea, --0xc01c8000, --0x044ca000, --0xcdc12010, --0x7c410000, --0xc8140009, --0x04180000, --0x041c0008, --0xcd800071, --0x09dc0001, --0x05980001, --0xcd0d0000, --0x99c0fffc, --0xcc800062, --0x8000037e, --0xcd400071, --0xc00e0100, --0xcc000041, --0xccc1304a, --0xc83c007f, --0xcc00007f, --0x80000003, --0xcc00007f, --0xcc00007f, --0x88000000, --0xcc00007f, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00000000, --0x00010333, --0x00100006, --0x00170008, --0x0021000a, --0x0027002a, --0x00280025, --0x0029002b, --0x002a0028, --0x002b002b, --0x002d003a, --0x002e0041, --0x002f004c, --0x0034004e, --0x00360032, --0x003900b1, --0x003a00d1, --0x003b00e6, --0x003c00fe, --0x003d016d, --0x003f00af, --0x00410338, --0x0043034b, --0x00440190, --0x004500fe, --0x004601ae, --0x004701ae, --0x00480200, --0x0049020e, --0x004a0257, --0x004b0284, --0x00520261, --0x00530273, --0x00540289, --0x0057029b, --0x0060029f, --0x006102ae, --0x006202b8, --0x006302c2, --0x006402cc, --0x006502d6, --0x006602e0, --0x006702ea, --0x006802f4, --0x006902f8, --0x006a02fc, --0x006b0300, --0x006c0304, --0x006d0308, --0x006e030c, --0x006f0310, --0x00700314, --0x00720365, --0x0074036b, --0x00790369, --0x007c031e, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --0x000f037a, --}; -- --#endif -diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h -new file mode 100644 -index 0000000..723295f ---- /dev/null -+++ b/drivers/gpu/drm/radeon/r600d.h -@@ -0,0 +1,661 @@ -+/* -+ * Copyright 2009 Advanced Micro Devices, Inc. -+ * Copyright 2009 Red Hat Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef R600D_H -+#define R600D_H -+ -+#define CP_PACKET2 0x80000000 -+#define PACKET2_PAD_SHIFT 0 -+#define PACKET2_PAD_MASK (0x3fffffff << 0) -+ -+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -+ -+#define R6XX_MAX_SH_GPRS 256 -+#define R6XX_MAX_TEMP_GPRS 16 -+#define R6XX_MAX_SH_THREADS 256 -+#define R6XX_MAX_SH_STACK_ENTRIES 4096 -+#define R6XX_MAX_BACKENDS 8 -+#define R6XX_MAX_BACKENDS_MASK 0xff -+#define R6XX_MAX_SIMDS 8 -+#define R6XX_MAX_SIMDS_MASK 0xff -+#define R6XX_MAX_PIPES 8 -+#define R6XX_MAX_PIPES_MASK 0xff -+ -+/* PTE flags */ -+#define PTE_VALID (1 << 0) -+#define PTE_SYSTEM (1 << 1) -+#define PTE_SNOOPED (1 << 2) -+#define PTE_READABLE (1 << 5) -+#define PTE_WRITEABLE (1 << 6) -+ -+/* Registers */ -+#define ARB_POP 0x2418 -+#define ENABLE_TC128 (1 << 30) -+#define ARB_GDEC_RD_CNTL 0x246C -+ -+#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -+#define CC_RB_BACKEND_DISABLE 0x98F4 -+#define BACKEND_DISABLE(x) ((x) << 16) -+ -+#define CB_COLOR0_BASE 0x28040 -+#define CB_COLOR1_BASE 0x28044 -+#define CB_COLOR2_BASE 0x28048 -+#define CB_COLOR3_BASE 0x2804C -+#define CB_COLOR4_BASE 0x28050 -+#define CB_COLOR5_BASE 0x28054 -+#define CB_COLOR6_BASE 0x28058 -+#define CB_COLOR7_BASE 0x2805C -+#define CB_COLOR7_FRAG 0x280FC -+ -+#define CB_COLOR0_SIZE 0x28060 -+#define CB_COLOR0_VIEW 0x28080 -+#define CB_COLOR0_INFO 0x280a0 -+#define CB_COLOR0_TILE 0x280c0 -+#define CB_COLOR0_FRAG 0x280e0 -+#define CB_COLOR0_MASK 0x28100 -+ -+#define CONFIG_MEMSIZE 0x5428 -+#define CP_STAT 0x8680 -+#define CP_COHER_BASE 0x85F8 -+#define CP_DEBUG 0xC1FC -+#define R_0086D8_CP_ME_CNTL 0x86D8 -+#define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28) -+#define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF) -+#define CP_ME_RAM_DATA 0xC160 -+#define CP_ME_RAM_RADDR 0xC158 -+#define CP_ME_RAM_WADDR 0xC15C -+#define CP_MEQ_THRESHOLDS 0x8764 -+#define MEQ_END(x) ((x) << 16) -+#define ROQ_END(x) ((x) << 24) -+#define CP_PERFMON_CNTL 0x87FC -+#define CP_PFP_UCODE_ADDR 0xC150 -+#define CP_PFP_UCODE_DATA 0xC154 -+#define CP_QUEUE_THRESHOLDS 0x8760 -+#define ROQ_IB1_START(x) ((x) << 0) -+#define ROQ_IB2_START(x) ((x) << 8) -+#define CP_RB_BASE 0xC100 -+#define CP_RB_CNTL 0xC104 -+#define RB_BUFSZ(x) ((x)<<0) -+#define RB_BLKSZ(x) ((x)<<8) -+#define RB_NO_UPDATE (1<<27) -+#define RB_RPTR_WR_ENA (1<<31) -+#define BUF_SWAP_32BIT (2 << 16) -+#define CP_RB_RPTR 0x8700 -+#define CP_RB_RPTR_ADDR 0xC10C -+#define CP_RB_RPTR_ADDR_HI 0xC110 -+#define CP_RB_RPTR_WR 0xC108 -+#define CP_RB_WPTR 0xC114 -+#define CP_RB_WPTR_ADDR 0xC118 -+#define CP_RB_WPTR_ADDR_HI 0xC11C -+#define CP_RB_WPTR_DELAY 0x8704 -+#define CP_ROQ_IB1_STAT 0x8784 -+#define CP_ROQ_IB2_STAT 0x8788 -+#define CP_SEM_WAIT_TIMER 0x85BC -+ -+#define DB_DEBUG 0x9830 -+#define PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) -+#define DB_DEPTH_BASE 0x2800C -+#define DB_WATERMARKS 0x9838 -+#define DEPTH_FREE(x) ((x) << 0) -+#define DEPTH_FLUSH(x) ((x) << 5) -+#define DEPTH_PENDING_FREE(x) ((x) << 15) -+#define DEPTH_CACHELINE_FREE(x) ((x) << 20) -+ -+#define DCP_TILING_CONFIG 0x6CA0 -+#define PIPE_TILING(x) ((x) << 1) -+#define BANK_TILING(x) ((x) << 4) -+#define GROUP_SIZE(x) ((x) << 6) -+#define ROW_TILING(x) ((x) << 8) -+#define BANK_SWAPS(x) ((x) << 11) -+#define SAMPLE_SPLIT(x) ((x) << 14) -+#define BACKEND_MAP(x) ((x) << 16) -+ -+#define GB_TILING_CONFIG 0x98F0 -+ -+#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -+#define INACTIVE_QD_PIPES(x) ((x) << 8) -+#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -+#define INACTIVE_SIMDS(x) ((x) << 16) -+#define INACTIVE_SIMDS_MASK 0x00FF0000 -+ -+#define SQ_CONFIG 0x8c00 -+# define VC_ENABLE (1 << 0) -+# define EXPORT_SRC_C (1 << 1) -+# define DX9_CONSTS (1 << 2) -+# define ALU_INST_PREFER_VECTOR (1 << 3) -+# define DX10_CLAMP (1 << 4) -+# define CLAUSE_SEQ_PRIO(x) ((x) << 8) -+# define PS_PRIO(x) ((x) << 24) -+# define VS_PRIO(x) ((x) << 26) -+# define GS_PRIO(x) ((x) << 28) -+# define ES_PRIO(x) ((x) << 30) -+#define SQ_GPR_RESOURCE_MGMT_1 0x8c04 -+# define NUM_PS_GPRS(x) ((x) << 0) -+# define NUM_VS_GPRS(x) ((x) << 16) -+# define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -+#define SQ_GPR_RESOURCE_MGMT_2 0x8c08 -+# define NUM_GS_GPRS(x) ((x) << 0) -+# define NUM_ES_GPRS(x) ((x) << 16) -+#define SQ_THREAD_RESOURCE_MGMT 0x8c0c -+# define NUM_PS_THREADS(x) ((x) << 0) -+# define NUM_VS_THREADS(x) ((x) << 8) -+# define NUM_GS_THREADS(x) ((x) << 16) -+# define NUM_ES_THREADS(x) ((x) << 24) -+#define SQ_STACK_RESOURCE_MGMT_1 0x8c10 -+# define NUM_PS_STACK_ENTRIES(x) ((x) << 0) -+# define NUM_VS_STACK_ENTRIES(x) ((x) << 16) -+#define SQ_STACK_RESOURCE_MGMT_2 0x8c14 -+# define NUM_GS_STACK_ENTRIES(x) ((x) << 0) -+# define NUM_ES_STACK_ENTRIES(x) ((x) << 16) -+ -+#define GRBM_CNTL 0x8000 -+# define GRBM_READ_TIMEOUT(x) ((x) << 0) -+#define GRBM_STATUS 0x8010 -+#define CMDFIFO_AVAIL_MASK 0x0000001F -+#define GUI_ACTIVE (1<<31) -+#define GRBM_STATUS2 0x8014 -+#define GRBM_SOFT_RESET 0x8020 -+#define SOFT_RESET_CP (1<<0) -+ -+#define HDP_HOST_PATH_CNTL 0x2C00 -+#define HDP_NONSURFACE_BASE 0x2C04 -+#define HDP_NONSURFACE_INFO 0x2C08 -+#define HDP_NONSURFACE_SIZE 0x2C0C -+#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -+#define HDP_TILING_CONFIG 0x2F3C -+ -+#define MC_VM_AGP_TOP 0x2184 -+#define MC_VM_AGP_BOT 0x2188 -+#define MC_VM_AGP_BASE 0x218C -+#define MC_VM_FB_LOCATION 0x2180 -+#define MC_VM_L1_TLB_MCD_RD_A_CNTL 0x219C -+#define ENABLE_L1_TLB (1 << 0) -+#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -+#define ENABLE_L1_STRICT_ORDERING (1 << 2) -+#define SYSTEM_ACCESS_MODE_MASK 0x000000C0 -+#define SYSTEM_ACCESS_MODE_SHIFT 6 -+#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) -+#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) -+#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) -+#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) -+#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) -+#define SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) -+#define ENABLE_SEMAPHORE_MODE (1 << 10) -+#define ENABLE_WAIT_L2_QUERY (1 << 11) -+#define EFFECTIVE_L1_TLB_SIZE(x) (((x) & 7) << 12) -+#define EFFECTIVE_L1_TLB_SIZE_MASK 0x00007000 -+#define EFFECTIVE_L1_TLB_SIZE_SHIFT 12 -+#define EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 7) << 15) -+#define EFFECTIVE_L1_QUEUE_SIZE_MASK 0x00038000 -+#define EFFECTIVE_L1_QUEUE_SIZE_SHIFT 15 -+#define MC_VM_L1_TLB_MCD_RD_B_CNTL 0x21A0 -+#define MC_VM_L1_TLB_MCB_RD_GFX_CNTL 0x21FC -+#define MC_VM_L1_TLB_MCB_RD_HDP_CNTL 0x2204 -+#define MC_VM_L1_TLB_MCB_RD_PDMA_CNTL 0x2208 -+#define MC_VM_L1_TLB_MCB_RD_SEM_CNTL 0x220C -+#define MC_VM_L1_TLB_MCB_RD_SYS_CNTL 0x2200 -+#define MC_VM_L1_TLB_MCD_WR_A_CNTL 0x21A4 -+#define MC_VM_L1_TLB_MCD_WR_B_CNTL 0x21A8 -+#define MC_VM_L1_TLB_MCB_WR_GFX_CNTL 0x2210 -+#define MC_VM_L1_TLB_MCB_WR_HDP_CNTL 0x2218 -+#define MC_VM_L1_TLB_MCB_WR_PDMA_CNTL 0x221C -+#define MC_VM_L1_TLB_MCB_WR_SEM_CNTL 0x2220 -+#define MC_VM_L1_TLB_MCB_WR_SYS_CNTL 0x2214 -+#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 -+#define LOGICAL_PAGE_NUMBER_MASK 0x000FFFFF -+#define LOGICAL_PAGE_NUMBER_SHIFT 0 -+#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 -+#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 -+ -+#define PA_CL_ENHANCE 0x8A14 -+#define CLIP_VTX_REORDER_ENA (1 << 0) -+#define NUM_CLIP_SEQ(x) ((x) << 1) -+#define PA_SC_AA_CONFIG 0x28C04 -+#define PA_SC_AA_SAMPLE_LOCS_2S 0x8B40 -+#define PA_SC_AA_SAMPLE_LOCS_4S 0x8B44 -+#define PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8B48 -+#define PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8B4C -+#define S0_X(x) ((x) << 0) -+#define S0_Y(x) ((x) << 4) -+#define S1_X(x) ((x) << 8) -+#define S1_Y(x) ((x) << 12) -+#define S2_X(x) ((x) << 16) -+#define S2_Y(x) ((x) << 20) -+#define S3_X(x) ((x) << 24) -+#define S3_Y(x) ((x) << 28) -+#define S4_X(x) ((x) << 0) -+#define S4_Y(x) ((x) << 4) -+#define S5_X(x) ((x) << 8) -+#define S5_Y(x) ((x) << 12) -+#define S6_X(x) ((x) << 16) -+#define S6_Y(x) ((x) << 20) -+#define S7_X(x) ((x) << 24) -+#define S7_Y(x) ((x) << 28) -+#define PA_SC_CLIPRECT_RULE 0x2820c -+#define PA_SC_ENHANCE 0x8BF0 -+#define FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) -+#define FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) -+#define PA_SC_LINE_STIPPLE 0x28A0C -+#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -+#define PA_SC_MODE_CNTL 0x28A4C -+#define PA_SC_MULTI_CHIP_CNTL 0x8B20 -+ -+#define PA_SC_SCREEN_SCISSOR_TL 0x28030 -+#define PA_SC_GENERIC_SCISSOR_TL 0x28240 -+#define PA_SC_WINDOW_SCISSOR_TL 0x28204 -+ -+#define PCIE_PORT_INDEX 0x0038 -+#define PCIE_PORT_DATA 0x003C -+ -+#define RAMCFG 0x2408 -+#define NOOFBANK_SHIFT 0 -+#define NOOFBANK_MASK 0x00000001 -+#define NOOFRANK_SHIFT 1 -+#define NOOFRANK_MASK 0x00000002 -+#define NOOFROWS_SHIFT 2 -+#define NOOFROWS_MASK 0x0000001C -+#define NOOFCOLS_SHIFT 5 -+#define NOOFCOLS_MASK 0x00000060 -+#define CHANSIZE_SHIFT 7 -+#define CHANSIZE_MASK 0x00000080 -+#define BURSTLENGTH_SHIFT 8 -+#define BURSTLENGTH_MASK 0x00000100 -+#define CHANSIZE_OVERRIDE (1 << 10) -+ -+#define SCRATCH_REG0 0x8500 -+#define SCRATCH_REG1 0x8504 -+#define SCRATCH_REG2 0x8508 -+#define SCRATCH_REG3 0x850C -+#define SCRATCH_REG4 0x8510 -+#define SCRATCH_REG5 0x8514 -+#define SCRATCH_REG6 0x8518 -+#define SCRATCH_REG7 0x851C -+#define SCRATCH_UMSK 0x8540 -+#define SCRATCH_ADDR 0x8544 -+ -+#define SPI_CONFIG_CNTL 0x9100 -+#define GPR_WRITE_PRIORITY(x) ((x) << 0) -+#define DISABLE_INTERP_1 (1 << 5) -+#define SPI_CONFIG_CNTL_1 0x913C -+#define VTX_DONE_DELAY(x) ((x) << 0) -+#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -+#define SPI_INPUT_Z 0x286D8 -+#define SPI_PS_IN_CONTROL_0 0x286CC -+#define NUM_INTERP(x) ((x)<<0) -+#define POSITION_ENA (1<<8) -+#define POSITION_CENTROID (1<<9) -+#define POSITION_ADDR(x) ((x)<<10) -+#define PARAM_GEN(x) ((x)<<15) -+#define PARAM_GEN_ADDR(x) ((x)<<19) -+#define BARYC_SAMPLE_CNTL(x) ((x)<<26) -+#define PERSP_GRADIENT_ENA (1<<28) -+#define LINEAR_GRADIENT_ENA (1<<29) -+#define POSITION_SAMPLE (1<<30) -+#define BARYC_AT_SAMPLE_ENA (1<<31) -+#define SPI_PS_IN_CONTROL_1 0x286D0 -+#define GEN_INDEX_PIX (1<<0) -+#define GEN_INDEX_PIX_ADDR(x) ((x)<<1) -+#define FRONT_FACE_ENA (1<<8) -+#define FRONT_FACE_CHAN(x) ((x)<<9) -+#define FRONT_FACE_ALL_BITS (1<<11) -+#define FRONT_FACE_ADDR(x) ((x)<<12) -+#define FOG_ADDR(x) ((x)<<17) -+#define FIXED_PT_POSITION_ENA (1<<24) -+#define FIXED_PT_POSITION_ADDR(x) ((x)<<25) -+ -+#define SQ_MS_FIFO_SIZES 0x8CF0 -+#define CACHE_FIFO_SIZE(x) ((x) << 0) -+#define FETCH_FIFO_HIWATER(x) ((x) << 8) -+#define DONE_FIFO_HIWATER(x) ((x) << 16) -+#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -+#define SQ_PGM_START_ES 0x28880 -+#define SQ_PGM_START_FS 0x28894 -+#define SQ_PGM_START_GS 0x2886C -+#define SQ_PGM_START_PS 0x28840 -+#define SQ_PGM_RESOURCES_PS 0x28850 -+#define SQ_PGM_EXPORTS_PS 0x28854 -+#define SQ_PGM_CF_OFFSET_PS 0x288cc -+#define SQ_PGM_START_VS 0x28858 -+#define SQ_PGM_RESOURCES_VS 0x28868 -+#define SQ_PGM_CF_OFFSET_VS 0x288d0 -+#define SQ_VTX_CONSTANT_WORD6_0 0x38018 -+#define S__SQ_VTX_CONSTANT_TYPE(x) (((x) & 3) << 30) -+#define G__SQ_VTX_CONSTANT_TYPE(x) (((x) >> 30) & 3) -+#define SQ_TEX_VTX_INVALID_TEXTURE 0x0 -+#define SQ_TEX_VTX_INVALID_BUFFER 0x1 -+#define SQ_TEX_VTX_VALID_TEXTURE 0x2 -+#define SQ_TEX_VTX_VALID_BUFFER 0x3 -+ -+ -+#define SX_MISC 0x28350 -+#define SX_DEBUG_1 0x9054 -+#define SMX_EVENT_RELEASE (1 << 0) -+#define ENABLE_NEW_SMX_ADDRESS (1 << 16) -+ -+#define TA_CNTL_AUX 0x9508 -+#define DISABLE_CUBE_WRAP (1 << 0) -+#define DISABLE_CUBE_ANISO (1 << 1) -+#define SYNC_GRADIENT (1 << 24) -+#define SYNC_WALKER (1 << 25) -+#define SYNC_ALIGNER (1 << 26) -+#define BILINEAR_PRECISION_6_BIT (0 << 31) -+#define BILINEAR_PRECISION_8_BIT (1 << 31) -+ -+#define TC_CNTL 0x9608 -+#define TC_L2_SIZE(x) ((x)<<5) -+#define L2_DISABLE_LATE_HIT (1<<9) -+ -+ -+#define VGT_CACHE_INVALIDATION 0x88C4 -+#define CACHE_INVALIDATION(x) ((x)<<0) -+#define VC_ONLY 0 -+#define TC_ONLY 1 -+#define VC_AND_TC 2 -+#define VGT_DMA_BASE 0x287E8 -+#define VGT_DMA_BASE_HI 0x287E4 -+#define VGT_ES_PER_GS 0x88CC -+#define VGT_GS_PER_ES 0x88C8 -+#define VGT_GS_PER_VS 0x88E8 -+#define VGT_GS_VERTEX_REUSE 0x88D4 -+#define VGT_PRIMITIVE_TYPE 0x8958 -+#define VGT_NUM_INSTANCES 0x8974 -+#define VGT_OUT_DEALLOC_CNTL 0x28C5C -+#define DEALLOC_DIST_MASK 0x0000007F -+#define VGT_STRMOUT_BASE_OFFSET_0 0x28B10 -+#define VGT_STRMOUT_BASE_OFFSET_1 0x28B14 -+#define VGT_STRMOUT_BASE_OFFSET_2 0x28B18 -+#define VGT_STRMOUT_BASE_OFFSET_3 0x28B1c -+#define VGT_STRMOUT_BASE_OFFSET_HI_0 0x28B44 -+#define VGT_STRMOUT_BASE_OFFSET_HI_1 0x28B48 -+#define VGT_STRMOUT_BASE_OFFSET_HI_2 0x28B4c -+#define VGT_STRMOUT_BASE_OFFSET_HI_3 0x28B50 -+#define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8 -+#define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8 -+#define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8 -+#define VGT_STRMOUT_BUFFER_BASE_3 0x28B08 -+#define VGT_STRMOUT_BUFFER_OFFSET_0 0x28ADC -+#define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC -+#define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC -+#define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C -+#define VGT_STRMOUT_EN 0x28AB0 -+#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 -+#define VTX_REUSE_DEPTH_MASK 0x000000FF -+#define VGT_EVENT_INITIATOR 0x28a90 -+# define CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) -+ -+#define VM_CONTEXT0_CNTL 0x1410 -+#define ENABLE_CONTEXT (1 << 0) -+#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -+#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -+#define VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 -+#define VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14B0 -+#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 -+#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 -+#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15B4 -+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1554 -+#define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 -+#define REQUEST_TYPE(x) (((x) & 0xf) << 0) -+#define RESPONSE_TYPE_MASK 0x000000F0 -+#define RESPONSE_TYPE_SHIFT 4 -+#define VM_L2_CNTL 0x1400 -+#define ENABLE_L2_CACHE (1 << 0) -+#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -+#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -+#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 13) -+#define VM_L2_CNTL2 0x1404 -+#define INVALIDATE_ALL_L1_TLBS (1 << 0) -+#define INVALIDATE_L2_CACHE (1 << 1) -+#define VM_L2_CNTL3 0x1408 -+#define BANK_SELECT_0(x) (((x) & 0x1f) << 0) -+#define BANK_SELECT_1(x) (((x) & 0x1f) << 5) -+#define L2_CACHE_UPDATE_MODE(x) (((x) & 3) << 10) -+#define VM_L2_STATUS 0x140C -+#define L2_BUSY (1 << 0) -+ -+#define WAIT_UNTIL 0x8040 -+#define WAIT_2D_IDLE_bit (1 << 14) -+#define WAIT_3D_IDLE_bit (1 << 15) -+#define WAIT_2D_IDLECLEAN_bit (1 << 16) -+#define WAIT_3D_IDLECLEAN_bit (1 << 17) -+ -+ -+ -+/* -+ * PM4 -+ */ -+#define PACKET_TYPE0 0 -+#define PACKET_TYPE1 1 -+#define PACKET_TYPE2 2 -+#define PACKET_TYPE3 3 -+ -+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -+#define CP_PACKET0_GET_REG(h) (((h) & 0xFFFF) << 2) -+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -+#define PACKET0(reg, n) ((PACKET_TYPE0 << 30) | \ -+ (((reg) >> 2) & 0xFFFF) | \ -+ ((n) & 0x3FFF) << 16) -+#define PACKET3(op, n) ((PACKET_TYPE3 << 30) | \ -+ (((op) & 0xFF) << 8) | \ -+ ((n) & 0x3FFF) << 16) -+ -+/* Packet 3 types */ -+#define PACKET3_NOP 0x10 -+#define PACKET3_INDIRECT_BUFFER_END 0x17 -+#define PACKET3_SET_PREDICATION 0x20 -+#define PACKET3_REG_RMW 0x21 -+#define PACKET3_COND_EXEC 0x22 -+#define PACKET3_PRED_EXEC 0x23 -+#define PACKET3_START_3D_CMDBUF 0x24 -+#define PACKET3_DRAW_INDEX_2 0x27 -+#define PACKET3_CONTEXT_CONTROL 0x28 -+#define PACKET3_DRAW_INDEX_IMMD_BE 0x29 -+#define PACKET3_INDEX_TYPE 0x2A -+#define PACKET3_DRAW_INDEX 0x2B -+#define PACKET3_DRAW_INDEX_AUTO 0x2D -+#define PACKET3_DRAW_INDEX_IMMD 0x2E -+#define PACKET3_NUM_INSTANCES 0x2F -+#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 -+#define PACKET3_INDIRECT_BUFFER_MP 0x38 -+#define PACKET3_MEM_SEMAPHORE 0x39 -+#define PACKET3_MPEG_INDEX 0x3A -+#define PACKET3_WAIT_REG_MEM 0x3C -+#define PACKET3_MEM_WRITE 0x3D -+#define PACKET3_INDIRECT_BUFFER 0x32 -+#define PACKET3_CP_INTERRUPT 0x40 -+#define PACKET3_SURFACE_SYNC 0x43 -+# define PACKET3_CB0_DEST_BASE_ENA (1 << 6) -+# define PACKET3_TC_ACTION_ENA (1 << 23) -+# define PACKET3_VC_ACTION_ENA (1 << 24) -+# define PACKET3_CB_ACTION_ENA (1 << 25) -+# define PACKET3_DB_ACTION_ENA (1 << 26) -+# define PACKET3_SH_ACTION_ENA (1 << 27) -+# define PACKET3_SMX_ACTION_ENA (1 << 28) -+#define PACKET3_ME_INITIALIZE 0x44 -+#define PACKET3_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) -+#define PACKET3_COND_WRITE 0x45 -+#define PACKET3_EVENT_WRITE 0x46 -+#define PACKET3_EVENT_WRITE_EOP 0x47 -+#define PACKET3_ONE_REG_WRITE 0x57 -+#define PACKET3_SET_CONFIG_REG 0x68 -+#define PACKET3_SET_CONFIG_REG_OFFSET 0x00008000 -+#define PACKET3_SET_CONFIG_REG_END 0x0000ac00 -+#define PACKET3_SET_CONTEXT_REG 0x69 -+#define PACKET3_SET_CONTEXT_REG_OFFSET 0x00028000 -+#define PACKET3_SET_CONTEXT_REG_END 0x00029000 -+#define PACKET3_SET_ALU_CONST 0x6A -+#define PACKET3_SET_ALU_CONST_OFFSET 0x00030000 -+#define PACKET3_SET_ALU_CONST_END 0x00032000 -+#define PACKET3_SET_BOOL_CONST 0x6B -+#define PACKET3_SET_BOOL_CONST_OFFSET 0x0003e380 -+#define PACKET3_SET_BOOL_CONST_END 0x00040000 -+#define PACKET3_SET_LOOP_CONST 0x6C -+#define PACKET3_SET_LOOP_CONST_OFFSET 0x0003e200 -+#define PACKET3_SET_LOOP_CONST_END 0x0003e380 -+#define PACKET3_SET_RESOURCE 0x6D -+#define PACKET3_SET_RESOURCE_OFFSET 0x00038000 -+#define PACKET3_SET_RESOURCE_END 0x0003c000 -+#define PACKET3_SET_SAMPLER 0x6E -+#define PACKET3_SET_SAMPLER_OFFSET 0x0003c000 -+#define PACKET3_SET_SAMPLER_END 0x0003cff0 -+#define PACKET3_SET_CTL_CONST 0x6F -+#define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 -+#define PACKET3_SET_CTL_CONST_END 0x0003e200 -+#define PACKET3_SURFACE_BASE_UPDATE 0x73 -+ -+ -+#define R_008020_GRBM_SOFT_RESET 0x8020 -+#define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0) -+#define S_008020_SOFT_RESET_CB(x) (((x) & 1) << 1) -+#define S_008020_SOFT_RESET_CR(x) (((x) & 1) << 2) -+#define S_008020_SOFT_RESET_DB(x) (((x) & 1) << 3) -+#define S_008020_SOFT_RESET_PA(x) (((x) & 1) << 5) -+#define S_008020_SOFT_RESET_SC(x) (((x) & 1) << 6) -+#define S_008020_SOFT_RESET_SMX(x) (((x) & 1) << 7) -+#define S_008020_SOFT_RESET_SPI(x) (((x) & 1) << 8) -+#define S_008020_SOFT_RESET_SH(x) (((x) & 1) << 9) -+#define S_008020_SOFT_RESET_SX(x) (((x) & 1) << 10) -+#define S_008020_SOFT_RESET_TC(x) (((x) & 1) << 11) -+#define S_008020_SOFT_RESET_TA(x) (((x) & 1) << 12) -+#define S_008020_SOFT_RESET_VC(x) (((x) & 1) << 13) -+#define S_008020_SOFT_RESET_VGT(x) (((x) & 1) << 14) -+#define R_008010_GRBM_STATUS 0x8010 -+#define S_008010_CMDFIFO_AVAIL(x) (((x) & 0x1F) << 0) -+#define S_008010_CP_RQ_PENDING(x) (((x) & 1) << 6) -+#define S_008010_CF_RQ_PENDING(x) (((x) & 1) << 7) -+#define S_008010_PF_RQ_PENDING(x) (((x) & 1) << 8) -+#define S_008010_GRBM_EE_BUSY(x) (((x) & 1) << 10) -+#define S_008010_VC_BUSY(x) (((x) & 1) << 11) -+#define S_008010_DB03_CLEAN(x) (((x) & 1) << 12) -+#define S_008010_CB03_CLEAN(x) (((x) & 1) << 13) -+#define S_008010_VGT_BUSY_NO_DMA(x) (((x) & 1) << 16) -+#define S_008010_VGT_BUSY(x) (((x) & 1) << 17) -+#define S_008010_TA03_BUSY(x) (((x) & 1) << 18) -+#define S_008010_TC_BUSY(x) (((x) & 1) << 19) -+#define S_008010_SX_BUSY(x) (((x) & 1) << 20) -+#define S_008010_SH_BUSY(x) (((x) & 1) << 21) -+#define S_008010_SPI03_BUSY(x) (((x) & 1) << 22) -+#define S_008010_SMX_BUSY(x) (((x) & 1) << 23) -+#define S_008010_SC_BUSY(x) (((x) & 1) << 24) -+#define S_008010_PA_BUSY(x) (((x) & 1) << 25) -+#define S_008010_DB03_BUSY(x) (((x) & 1) << 26) -+#define S_008010_CR_BUSY(x) (((x) & 1) << 27) -+#define S_008010_CP_COHERENCY_BUSY(x) (((x) & 1) << 28) -+#define S_008010_CP_BUSY(x) (((x) & 1) << 29) -+#define S_008010_CB03_BUSY(x) (((x) & 1) << 30) -+#define S_008010_GUI_ACTIVE(x) (((x) & 1) << 31) -+#define G_008010_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x1F) -+#define G_008010_CP_RQ_PENDING(x) (((x) >> 6) & 1) -+#define G_008010_CF_RQ_PENDING(x) (((x) >> 7) & 1) -+#define G_008010_PF_RQ_PENDING(x) (((x) >> 8) & 1) -+#define G_008010_GRBM_EE_BUSY(x) (((x) >> 10) & 1) -+#define G_008010_VC_BUSY(x) (((x) >> 11) & 1) -+#define G_008010_DB03_CLEAN(x) (((x) >> 12) & 1) -+#define G_008010_CB03_CLEAN(x) (((x) >> 13) & 1) -+#define G_008010_VGT_BUSY_NO_DMA(x) (((x) >> 16) & 1) -+#define G_008010_VGT_BUSY(x) (((x) >> 17) & 1) -+#define G_008010_TA03_BUSY(x) (((x) >> 18) & 1) -+#define G_008010_TC_BUSY(x) (((x) >> 19) & 1) -+#define G_008010_SX_BUSY(x) (((x) >> 20) & 1) -+#define G_008010_SH_BUSY(x) (((x) >> 21) & 1) -+#define G_008010_SPI03_BUSY(x) (((x) >> 22) & 1) -+#define G_008010_SMX_BUSY(x) (((x) >> 23) & 1) -+#define G_008010_SC_BUSY(x) (((x) >> 24) & 1) -+#define G_008010_PA_BUSY(x) (((x) >> 25) & 1) -+#define G_008010_DB03_BUSY(x) (((x) >> 26) & 1) -+#define G_008010_CR_BUSY(x) (((x) >> 27) & 1) -+#define G_008010_CP_COHERENCY_BUSY(x) (((x) >> 28) & 1) -+#define G_008010_CP_BUSY(x) (((x) >> 29) & 1) -+#define G_008010_CB03_BUSY(x) (((x) >> 30) & 1) -+#define G_008010_GUI_ACTIVE(x) (((x) >> 31) & 1) -+#define R_008014_GRBM_STATUS2 0x8014 -+#define S_008014_CR_CLEAN(x) (((x) & 1) << 0) -+#define S_008014_SMX_CLEAN(x) (((x) & 1) << 1) -+#define S_008014_SPI0_BUSY(x) (((x) & 1) << 8) -+#define S_008014_SPI1_BUSY(x) (((x) & 1) << 9) -+#define S_008014_SPI2_BUSY(x) (((x) & 1) << 10) -+#define S_008014_SPI3_BUSY(x) (((x) & 1) << 11) -+#define S_008014_TA0_BUSY(x) (((x) & 1) << 12) -+#define S_008014_TA1_BUSY(x) (((x) & 1) << 13) -+#define S_008014_TA2_BUSY(x) (((x) & 1) << 14) -+#define S_008014_TA3_BUSY(x) (((x) & 1) << 15) -+#define S_008014_DB0_BUSY(x) (((x) & 1) << 16) -+#define S_008014_DB1_BUSY(x) (((x) & 1) << 17) -+#define S_008014_DB2_BUSY(x) (((x) & 1) << 18) -+#define S_008014_DB3_BUSY(x) (((x) & 1) << 19) -+#define S_008014_CB0_BUSY(x) (((x) & 1) << 20) -+#define S_008014_CB1_BUSY(x) (((x) & 1) << 21) -+#define S_008014_CB2_BUSY(x) (((x) & 1) << 22) -+#define S_008014_CB3_BUSY(x) (((x) & 1) << 23) -+#define G_008014_CR_CLEAN(x) (((x) >> 0) & 1) -+#define G_008014_SMX_CLEAN(x) (((x) >> 1) & 1) -+#define G_008014_SPI0_BUSY(x) (((x) >> 8) & 1) -+#define G_008014_SPI1_BUSY(x) (((x) >> 9) & 1) -+#define G_008014_SPI2_BUSY(x) (((x) >> 10) & 1) -+#define G_008014_SPI3_BUSY(x) (((x) >> 11) & 1) -+#define G_008014_TA0_BUSY(x) (((x) >> 12) & 1) -+#define G_008014_TA1_BUSY(x) (((x) >> 13) & 1) -+#define G_008014_TA2_BUSY(x) (((x) >> 14) & 1) -+#define G_008014_TA3_BUSY(x) (((x) >> 15) & 1) -+#define G_008014_DB0_BUSY(x) (((x) >> 16) & 1) -+#define G_008014_DB1_BUSY(x) (((x) >> 17) & 1) -+#define G_008014_DB2_BUSY(x) (((x) >> 18) & 1) -+#define G_008014_DB3_BUSY(x) (((x) >> 19) & 1) -+#define G_008014_CB0_BUSY(x) (((x) >> 20) & 1) -+#define G_008014_CB1_BUSY(x) (((x) >> 21) & 1) -+#define G_008014_CB2_BUSY(x) (((x) >> 22) & 1) -+#define G_008014_CB3_BUSY(x) (((x) >> 23) & 1) -+#define R_000E50_SRBM_STATUS 0x0E50 -+#define G_000E50_RLC_RQ_PENDING(x) (((x) >> 3) & 1) -+#define G_000E50_RCU_RQ_PENDING(x) (((x) >> 4) & 1) -+#define G_000E50_GRBM_RQ_PENDING(x) (((x) >> 5) & 1) -+#define G_000E50_HI_RQ_PENDING(x) (((x) >> 6) & 1) -+#define G_000E50_IO_EXTERN_SIGNAL(x) (((x) >> 7) & 1) -+#define G_000E50_VMC_BUSY(x) (((x) >> 8) & 1) -+#define G_000E50_MCB_BUSY(x) (((x) >> 9) & 1) -+#define G_000E50_MCDZ_BUSY(x) (((x) >> 10) & 1) -+#define G_000E50_MCDY_BUSY(x) (((x) >> 11) & 1) -+#define G_000E50_MCDX_BUSY(x) (((x) >> 12) & 1) -+#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1) -+#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1) -+#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1) -+#define R_000E60_SRBM_SOFT_RESET 0x0E60 -+#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1) -+#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2) -+#define S_000E60_SOFT_RESET_CMC(x) (((x) & 1) << 3) -+#define S_000E60_SOFT_RESET_CSC(x) (((x) & 1) << 4) -+#define S_000E60_SOFT_RESET_DC(x) (((x) & 1) << 5) -+#define S_000E60_SOFT_RESET_GRBM(x) (((x) & 1) << 8) -+#define S_000E60_SOFT_RESET_HDP(x) (((x) & 1) << 9) -+#define S_000E60_SOFT_RESET_IH(x) (((x) & 1) << 10) -+#define S_000E60_SOFT_RESET_MC(x) (((x) & 1) << 11) -+#define S_000E60_SOFT_RESET_RLC(x) (((x) & 1) << 13) -+#define S_000E60_SOFT_RESET_ROM(x) (((x) & 1) << 14) -+#define S_000E60_SOFT_RESET_SEM(x) (((x) & 1) << 15) -+#define S_000E60_SOFT_RESET_TSC(x) (((x) & 1) << 16) -+#define S_000E60_SOFT_RESET_VMC(x) (((x) & 1) << 17) -+ -+#endif -diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h -index b519fb2..3299733 100644 ---- a/drivers/gpu/drm/radeon/radeon.h -+++ b/drivers/gpu/drm/radeon/radeon.h -@@ -50,8 +50,8 @@ - #include - - #include "radeon_mode.h" -+#include "radeon_share.h" - #include "radeon_reg.h" --#include "r300.h" - - /* - * Modules parameters. -@@ -66,6 +66,7 @@ extern int radeon_gart_size; - extern int radeon_benchmarking; - extern int radeon_testing; - extern int radeon_connector_table; -+extern int radeon_tv; - - /* - * Copy from radeon_drv.h so we don't have to include both and have conflicting -@@ -111,10 +112,11 @@ enum radeon_family { - CHIP_RV635, - CHIP_RV670, - CHIP_RS780, -+ CHIP_RS880, - CHIP_RV770, - CHIP_RV730, - CHIP_RV710, -- CHIP_RS880, -+ CHIP_RV740, - CHIP_LAST, - }; - -@@ -151,10 +153,21 @@ struct radeon_device; - */ - bool radeon_get_bios(struct radeon_device *rdev); - -+ - /* -- * Clocks -+ * Dummy page - */ -+struct radeon_dummy_page { -+ struct page *page; -+ dma_addr_t addr; -+}; -+int radeon_dummy_page_init(struct radeon_device *rdev); -+void radeon_dummy_page_fini(struct radeon_device *rdev); -+ - -+/* -+ * Clocks -+ */ - struct radeon_clock { - struct radeon_pll p1pll; - struct radeon_pll p2pll; -@@ -165,6 +178,7 @@ struct radeon_clock { - uint32_t default_sclk; - }; - -+ - /* - * Fences. - */ -@@ -331,14 +345,18 @@ struct radeon_mc { - resource_size_t aper_size; - resource_size_t aper_base; - resource_size_t agp_base; -- unsigned gtt_location; -- unsigned gtt_size; -- unsigned vram_location; - /* for some chips with <= 32MB we need to lie - * about vram size near mc fb location */ -- unsigned mc_vram_size; -+ u64 mc_vram_size; -+ u64 gtt_location; -+ u64 gtt_size; -+ u64 gtt_start; -+ u64 gtt_end; -+ u64 vram_location; -+ u64 vram_start; -+ u64 vram_end; - unsigned vram_width; -- unsigned real_vram_size; -+ u64 real_vram_size; - int vram_mtrr; - bool vram_is_ddr; - }; -@@ -410,6 +428,16 @@ struct radeon_cp { - bool ready; - }; - -+struct r600_blit { -+ struct radeon_object *shader_obj; -+ u64 shader_gpu_addr; -+ u32 vs_offset, ps_offset; -+ u32 state_offset; -+ u32 state_len; -+ u32 vb_used, vb_total; -+ struct radeon_ib *vb_ib; -+}; -+ - int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib); - void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); - int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); -@@ -462,6 +490,7 @@ struct radeon_cs_parser { - int chunk_relocs_idx; - struct radeon_ib *ib; - void *track; -+ unsigned family; - }; - - struct radeon_cs_packet { -@@ -558,6 +587,9 @@ int r100_debugfs_cp_init(struct radeon_device *rdev); - */ - struct radeon_asic { - int (*init)(struct radeon_device *rdev); -+ void (*fini)(struct radeon_device *rdev); -+ int (*resume)(struct radeon_device *rdev); -+ int (*suspend)(struct radeon_device *rdev); - void (*errata)(struct radeon_device *rdev); - void (*vram_info)(struct radeon_device *rdev); - int (*gpu_reset)(struct radeon_device *rdev); -@@ -572,7 +604,11 @@ struct radeon_asic { - int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); - void (*cp_fini)(struct radeon_device *rdev); - void (*cp_disable)(struct radeon_device *rdev); -+ void (*cp_commit)(struct radeon_device *rdev); - void (*ring_start)(struct radeon_device *rdev); -+ int (*ring_test)(struct radeon_device *rdev); -+ void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); -+ int (*ib_test)(struct radeon_device *rdev); - int (*irq_set)(struct radeon_device *rdev); - int (*irq_process)(struct radeon_device *rdev); - u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); -@@ -604,8 +640,16 @@ struct radeon_asic { - void (*bandwidth_update)(struct radeon_device *rdev); - }; - -+struct r100_asic { -+ const unsigned *reg_safe_bm; -+ unsigned reg_safe_bm_size; -+}; -+ - union radeon_asic_config { - struct r300_asic r300; -+ struct r100_asic r100; -+ struct r600_asic r600; -+ struct rv770_asic rv770; - }; - - -@@ -691,11 +735,16 @@ struct radeon_device { - struct radeon_pm pm; - struct mutex cs_mutex; - struct radeon_wb wb; -+ struct radeon_dummy_page dummy_page; - bool gpu_lockup; - bool shutdown; - bool suspend; - bool need_dma32; -+ bool new_init_path; - struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; -+ const struct firmware *me_fw; /* all family ME firmware */ -+ const struct firmware *pfp_fw; /* r6/700 PFP firmware */ -+ struct r600_blit r600_blit; - }; - - int radeon_device_init(struct radeon_device *rdev, -@@ -705,6 +754,13 @@ int radeon_device_init(struct radeon_device *rdev, - void radeon_device_fini(struct radeon_device *rdev); - int radeon_gpu_wait_for_idle(struct radeon_device *rdev); - -+/* r600 blit */ -+int r600_blit_prepare_copy(struct radeon_device *rdev, int size_bytes); -+void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence); -+void r600_kms_blit_copy(struct radeon_device *rdev, -+ u64 src_gpu_addr, u64 dst_gpu_addr, -+ int size_bytes); -+ - static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) - { - if (reg < 0x10000) -@@ -732,6 +788,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 - #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) - #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) - #define RREG32(reg) r100_mm_rreg(rdev, (reg)) -+#define DREG32(reg) printk(KERN_INFO "REGISTER: " #reg " : 0x%08X\n", r100_mm_rreg(rdev, (reg))) - #define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) - #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) - #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) -@@ -755,6 +812,7 @@ static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32 - tmp_ |= ((val) & ~(mask)); \ - WREG32_PLL(reg, tmp_); \ - } while (0) -+#define DREG32_SYS(sqf, rdev, reg) seq_printf((sqf), #reg " : 0x%08X\n", r100_mm_rreg((rdev), (reg))) - - /* - * Indirect registers accessor -@@ -819,51 +877,6 @@ void radeon_atombios_fini(struct radeon_device *rdev); - /* - * RING helpers. - */ --#define CP_PACKET0 0x00000000 --#define PACKET0_BASE_INDEX_SHIFT 0 --#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) --#define PACKET0_COUNT_SHIFT 16 --#define PACKET0_COUNT_MASK (0x3fff << 16) --#define CP_PACKET1 0x40000000 --#define CP_PACKET2 0x80000000 --#define PACKET2_PAD_SHIFT 0 --#define PACKET2_PAD_MASK (0x3fffffff << 0) --#define CP_PACKET3 0xC0000000 --#define PACKET3_IT_OPCODE_SHIFT 8 --#define PACKET3_IT_OPCODE_MASK (0xff << 8) --#define PACKET3_COUNT_SHIFT 16 --#define PACKET3_COUNT_MASK (0x3fff << 16) --/* PACKET3 op code */ --#define PACKET3_NOP 0x10 --#define PACKET3_3D_DRAW_VBUF 0x28 --#define PACKET3_3D_DRAW_IMMD 0x29 --#define PACKET3_3D_DRAW_INDX 0x2A --#define PACKET3_3D_LOAD_VBPNTR 0x2F --#define PACKET3_INDX_BUFFER 0x33 --#define PACKET3_3D_DRAW_VBUF_2 0x34 --#define PACKET3_3D_DRAW_IMMD_2 0x35 --#define PACKET3_3D_DRAW_INDX_2 0x36 --#define PACKET3_BITBLT_MULTI 0x9B -- --#define PACKET0(reg, n) (CP_PACKET0 | \ -- REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ -- REG_SET(PACKET0_COUNT, (n))) --#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) --#define PACKET3(op, n) (CP_PACKET3 | \ -- REG_SET(PACKET3_IT_OPCODE, (op)) | \ -- REG_SET(PACKET3_COUNT, (n))) -- --#define PACKET_TYPE0 0 --#define PACKET_TYPE1 1 --#define PACKET_TYPE2 2 --#define PACKET_TYPE3 3 -- --#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) --#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) --#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) --#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) --#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -- - static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) - { - #if DRM_DEBUG_CODE -@@ -882,6 +895,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) - * ASICs macro. - */ - #define radeon_init(rdev) (rdev)->asic->init((rdev)) -+#define radeon_fini(rdev) (rdev)->asic->fini((rdev)) -+#define radeon_resume(rdev) (rdev)->asic->resume((rdev)) -+#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) - #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) - #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) - #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) -@@ -897,7 +913,11 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) - #define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize)) - #define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev)) - #define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev)) -+#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) - #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) -+#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev)) -+#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib)) -+#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev)) - #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) - #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) - #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) -diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h -index 93d8f88..e87bb91 100644 ---- a/drivers/gpu/drm/radeon/radeon_asic.h -+++ b/drivers/gpu/drm/radeon/radeon_asic.h -@@ -42,6 +42,7 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); - * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 - */ - int r100_init(struct radeon_device *rdev); -+int r200_init(struct radeon_device *rdev); - uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); - void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); - void r100_errata(struct radeon_device *rdev); -@@ -59,6 +60,7 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); - int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); - void r100_cp_fini(struct radeon_device *rdev); - void r100_cp_disable(struct radeon_device *rdev); -+void r100_cp_commit(struct radeon_device *rdev); - void r100_ring_start(struct radeon_device *rdev); - int r100_irq_set(struct radeon_device *rdev); - int r100_irq_process(struct radeon_device *rdev); -@@ -77,6 +79,9 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, - uint32_t offset, uint32_t obj_size); - int r100_clear_surface_reg(struct radeon_device *rdev, int reg); - void r100_bandwidth_update(struct radeon_device *rdev); -+void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -+int r100_ib_test(struct radeon_device *rdev); -+int r100_ring_test(struct radeon_device *rdev); - - static struct radeon_asic r100_asic = { - .init = &r100_init, -@@ -94,7 +99,11 @@ static struct radeon_asic r100_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r100_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, -@@ -155,7 +164,11 @@ static struct radeon_asic r300_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, -@@ -196,7 +209,11 @@ static struct radeon_asic r420_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, -@@ -244,7 +261,11 @@ static struct radeon_asic rs400_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &r100_irq_set, - .irq_process = &r100_irq_process, - .get_vblank_counter = &r100_get_vblank_counter, -@@ -266,7 +287,7 @@ static struct radeon_asic rs400_asic = { - /* - * rs600. - */ --int rs600_init(struct radeon_device *dev); -+int rs600_init(struct radeon_device *rdev); - void rs600_errata(struct radeon_device *rdev); - void rs600_vram_info(struct radeon_device *rdev); - int rs600_mc_init(struct radeon_device *rdev); -@@ -297,7 +318,11 @@ static struct radeon_asic rs600_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, -@@ -340,7 +365,11 @@ static struct radeon_asic rs690_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &r300_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, -@@ -390,7 +419,11 @@ static struct radeon_asic rv515_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &rv515_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, -@@ -433,7 +466,11 @@ static struct radeon_asic r520_asic = { - .cp_init = &r100_cp_init, - .cp_fini = &r100_cp_fini, - .cp_disable = &r100_cp_disable, -+ .cp_commit = &r100_cp_commit, - .ring_start = &rv515_ring_start, -+ .ring_test = &r100_ring_test, -+ .ring_ib_execute = &r100_ring_ib_execute, -+ .ib_test = &r100_ib_test, - .irq_set = &rs600_irq_set, - .irq_process = &rs600_irq_process, - .get_vblank_counter = &rs600_get_vblank_counter, -@@ -452,9 +489,127 @@ static struct radeon_asic r520_asic = { - }; - - /* -- * r600,rv610,rv630,rv620,rv635,rv670,rs780,rv770,rv730,rv710 -+ * r600,rv610,rv630,rv620,rv635,rv670,rs780,rs880 - */ -+int r600_init(struct radeon_device *rdev); -+void r600_fini(struct radeon_device *rdev); -+int r600_suspend(struct radeon_device *rdev); -+int r600_resume(struct radeon_device *rdev); -+int r600_wb_init(struct radeon_device *rdev); -+void r600_wb_fini(struct radeon_device *rdev); -+void r600_cp_commit(struct radeon_device *rdev); -+void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); - uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); - void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); -+int r600_cs_parse(struct radeon_cs_parser *p); -+void r600_fence_ring_emit(struct radeon_device *rdev, -+ struct radeon_fence *fence); -+int r600_copy_dma(struct radeon_device *rdev, -+ uint64_t src_offset, -+ uint64_t dst_offset, -+ unsigned num_pages, -+ struct radeon_fence *fence); -+int r600_irq_process(struct radeon_device *rdev); -+int r600_irq_set(struct radeon_device *rdev); -+int r600_gpu_reset(struct radeon_device *rdev); -+int r600_set_surface_reg(struct radeon_device *rdev, int reg, -+ uint32_t tiling_flags, uint32_t pitch, -+ uint32_t offset, uint32_t obj_size); -+int r600_clear_surface_reg(struct radeon_device *rdev, int reg); -+void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -+int r600_ib_test(struct radeon_device *rdev); -+int r600_ring_test(struct radeon_device *rdev); -+int r600_copy_blit(struct radeon_device *rdev, -+ uint64_t src_offset, uint64_t dst_offset, -+ unsigned num_pages, struct radeon_fence *fence); -+ -+static struct radeon_asic r600_asic = { -+ .errata = NULL, -+ .init = &r600_init, -+ .fini = &r600_fini, -+ .suspend = &r600_suspend, -+ .resume = &r600_resume, -+ .cp_commit = &r600_cp_commit, -+ .vram_info = NULL, -+ .gpu_reset = &r600_gpu_reset, -+ .mc_init = NULL, -+ .mc_fini = NULL, -+ .wb_init = &r600_wb_init, -+ .wb_fini = &r600_wb_fini, -+ .gart_enable = NULL, -+ .gart_disable = NULL, -+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush, -+ .gart_set_page = &rs600_gart_set_page, -+ .cp_init = NULL, -+ .cp_fini = NULL, -+ .cp_disable = NULL, -+ .ring_start = NULL, -+ .ring_test = &r600_ring_test, -+ .ring_ib_execute = &r600_ring_ib_execute, -+ .ib_test = &r600_ib_test, -+ .irq_set = &r600_irq_set, -+ .irq_process = &r600_irq_process, -+ .fence_ring_emit = &r600_fence_ring_emit, -+ .cs_parse = &r600_cs_parse, -+ .copy_blit = &r600_copy_blit, -+ .copy_dma = &r600_copy_blit, -+ .copy = NULL, -+ .set_engine_clock = &radeon_atom_set_engine_clock, -+ .set_memory_clock = &radeon_atom_set_memory_clock, -+ .set_pcie_lanes = NULL, -+ .set_clock_gating = &radeon_atom_set_clock_gating, -+ .set_surface_reg = r600_set_surface_reg, -+ .clear_surface_reg = r600_clear_surface_reg, -+ .bandwidth_update = &r520_bandwidth_update, -+}; -+ -+/* -+ * rv770,rv730,rv710,rv740 -+ */ -+int rv770_init(struct radeon_device *rdev); -+void rv770_fini(struct radeon_device *rdev); -+int rv770_suspend(struct radeon_device *rdev); -+int rv770_resume(struct radeon_device *rdev); -+int rv770_gpu_reset(struct radeon_device *rdev); -+ -+static struct radeon_asic rv770_asic = { -+ .errata = NULL, -+ .init = &rv770_init, -+ .fini = &rv770_fini, -+ .suspend = &rv770_suspend, -+ .resume = &rv770_resume, -+ .cp_commit = &r600_cp_commit, -+ .vram_info = NULL, -+ .gpu_reset = &rv770_gpu_reset, -+ .mc_init = NULL, -+ .mc_fini = NULL, -+ .wb_init = &r600_wb_init, -+ .wb_fini = &r600_wb_fini, -+ .gart_enable = NULL, -+ .gart_disable = NULL, -+ .gart_tlb_flush = &r600_pcie_gart_tlb_flush, -+ .gart_set_page = &rs600_gart_set_page, -+ .cp_init = NULL, -+ .cp_fini = NULL, -+ .cp_disable = NULL, -+ .ring_start = NULL, -+ .ring_test = &r600_ring_test, -+ .ring_ib_execute = &r600_ring_ib_execute, -+ .ib_test = &r600_ib_test, -+ .irq_set = &r600_irq_set, -+ .irq_process = &r600_irq_process, -+ .fence_ring_emit = &r600_fence_ring_emit, -+ .cs_parse = &r600_cs_parse, -+ .copy_blit = &r600_copy_blit, -+ .copy_dma = &r600_copy_blit, -+ .copy = NULL, -+ .set_engine_clock = &radeon_atom_set_engine_clock, -+ .set_memory_clock = &radeon_atom_set_memory_clock, -+ .set_pcie_lanes = NULL, -+ .set_clock_gating = &radeon_atom_set_clock_gating, -+ .set_surface_reg = r600_set_surface_reg, -+ .clear_surface_reg = r600_clear_surface_reg, -+ .bandwidth_update = &r520_bandwidth_update, -+}; - - #endif -diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c -index fcfe5c0..a8fb392 100644 ---- a/drivers/gpu/drm/radeon/radeon_atombios.c -+++ b/drivers/gpu/drm/radeon/radeon_atombios.c -@@ -370,10 +370,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) - && record-> - ucRecordType <= - ATOM_MAX_OBJECT_RECORD_NUMBER) { -- DRM_ERROR -- ("record type %d\n", -- record-> -- ucRecordType); - switch (record-> - ucRecordType) { - case ATOM_I2C_RECORD_TYPE: -@@ -471,11 +467,6 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct - continue; - } - -- if (i == ATOM_DEVICE_TV1_INDEX) { -- DRM_DEBUG("Skipping TV Out\n"); -- continue; -- } -- - bios_connectors[i].connector_type = - supported_devices_connector_convert[ci.sucConnectorInfo. - sbfAccess. -@@ -858,6 +849,72 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) - return p_dac; - } - -+bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, -+ SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, -+ int32_t *pixel_clock) -+{ -+ struct radeon_mode_info *mode_info = &rdev->mode_info; -+ ATOM_ANALOG_TV_INFO *tv_info; -+ ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2; -+ ATOM_DTD_FORMAT *dtd_timings; -+ int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info); -+ u8 frev, crev; -+ uint16_t data_offset; -+ -+ atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset); -+ -+ switch (crev) { -+ case 1: -+ tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset); -+ if (index > MAX_SUPPORTED_TV_TIMING) -+ return false; -+ -+ crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); -+ crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); -+ crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); -+ crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); -+ -+ crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); -+ crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); -+ crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); -+ crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); -+ -+ crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; -+ -+ crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); -+ crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); -+ crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); -+ crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); -+ *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; -+ -+ if (index == 1) { -+ /* PAL timings appear to have wrong values for totals */ -+ crtc_timing->usH_Total -= 1; -+ crtc_timing->usV_Total -= 1; -+ } -+ break; -+ case 2: -+ tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset); -+ if (index > MAX_SUPPORTED_TV_TIMING_V1_2) -+ return false; -+ -+ dtd_timings = &tv_info_v1_2->aModeTimings[index]; -+ crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); -+ crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); -+ crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); -+ crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); -+ crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); -+ crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); -+ crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); -+ crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); -+ -+ crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); -+ *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; -+ break; -+ } -+ return true; -+} -+ - struct radeon_encoder_tv_dac * - radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) - { -@@ -948,10 +1005,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) - uint32_t bios_2_scratch, bios_6_scratch; - - if (rdev->family >= CHIP_R600) { -- bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH); -+ bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); - bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); - } else { -- bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH); -+ bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH); - bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); - } - -diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c -index a37cbce..152eef1 100644 ---- a/drivers/gpu/drm/radeon/radeon_clocks.c -+++ b/drivers/gpu/drm/radeon/radeon_clocks.c -@@ -102,10 +102,12 @@ void radeon_get_clock_info(struct drm_device *dev) - p1pll->reference_div = 12; - if (p2pll->reference_div < 2) - p2pll->reference_div = 12; -- if (spll->reference_div < 2) -- spll->reference_div = -- RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & -- RADEON_M_SPLL_REF_DIV_MASK; -+ if (rdev->family < CHIP_RS600) { -+ if (spll->reference_div < 2) -+ spll->reference_div = -+ RREG32_PLL(RADEON_M_SPLL_REF_FB_DIV) & -+ RADEON_M_SPLL_REF_DIV_MASK; -+ } - if (mpll->reference_div < 2) - mpll->reference_div = spll->reference_div; - } else { -diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c -index 70ede6a..6a2b029 100644 ---- a/drivers/gpu/drm/radeon/radeon_connectors.c -+++ b/drivers/gpu/drm/radeon/radeon_connectors.c -@@ -94,6 +94,54 @@ struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) - return NULL; - } - -+ -+/* -+ * radeon_connector_analog_encoder_conflict_solve -+ * - search for other connectors sharing this encoder -+ * if priority is true, then set them disconnected if this is connected -+ * if priority is false, set us disconnected if they are connected -+ */ -+static enum drm_connector_status -+radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector, -+ struct drm_encoder *encoder, -+ enum drm_connector_status current_status, -+ bool priority) -+{ -+ struct drm_device *dev = connector->dev; -+ struct drm_connector *conflict; -+ int i; -+ -+ list_for_each_entry(conflict, &dev->mode_config.connector_list, head) { -+ if (conflict == connector) -+ continue; -+ -+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { -+ if (conflict->encoder_ids[i] == 0) -+ break; -+ -+ /* if the IDs match */ -+ if (conflict->encoder_ids[i] == encoder->base.id) { -+ if (conflict->status != connector_status_connected) -+ continue; -+ -+ if (priority == true) { -+ DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict)); -+ DRM_INFO("in favor of %s\n", drm_get_connector_name(connector)); -+ conflict->status = connector_status_disconnected; -+ radeon_connector_update_scratch_regs(conflict, connector_status_disconnected); -+ } else { -+ DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector)); -+ DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict)); -+ current_status = connector_status_disconnected; -+ } -+ break; -+ } -+ } -+ } -+ return current_status; -+ -+} -+ - static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder) - { - struct drm_device *dev = encoder->dev; -@@ -213,7 +261,6 @@ static int radeon_vga_get_modes(struct drm_connector *connector) - static int radeon_vga_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) - { -- - return MODE_OK; - } - -@@ -225,22 +272,22 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect - bool dret; - enum drm_connector_status ret = connector_status_disconnected; - -+ encoder = radeon_best_single_encoder(connector); -+ if (!encoder) -+ ret = connector_status_disconnected; -+ - radeon_i2c_do_lock(radeon_connector, 1); - dret = radeon_ddc_probe(radeon_connector); - radeon_i2c_do_lock(radeon_connector, 0); - if (dret) - ret = connector_status_connected; - else { -- /* if EDID fails to a load detect */ -- encoder = radeon_best_single_encoder(connector); -- if (!encoder) -- ret = connector_status_disconnected; -- else { -- encoder_funcs = encoder->helper_private; -- ret = encoder_funcs->detect(encoder, connector); -- } -+ encoder_funcs = encoder->helper_private; -+ ret = encoder_funcs->detect(encoder, connector); - } - -+ if (ret == connector_status_connected) -+ ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); - radeon_connector_update_scratch_regs(connector, ret); - return ret; - } -@@ -259,21 +306,87 @@ struct drm_connector_funcs radeon_vga_connector_funcs = { - .set_property = radeon_connector_set_property, - }; - -+static struct drm_display_mode tv_fixed_mode = { -+ DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 38250, 800, 832, -+ 912, 1024, 0, 600, 603, 607, 624, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC), -+}; -+ -+static int radeon_tv_get_modes(struct drm_connector *connector) -+{ -+ struct drm_device *dev = connector->dev; -+ struct drm_display_mode *tv_mode; -+ -+ tv_mode = drm_mode_duplicate(dev, &tv_fixed_mode); -+ tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; -+ -+ drm_mode_probed_add(connector, tv_mode); -+ -+ return 1; -+} -+ -+static int radeon_tv_mode_valid(struct drm_connector *connector, -+ struct drm_display_mode *mode) -+{ -+ return MODE_OK; -+} -+ -+static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) -+{ -+ struct drm_encoder *encoder; -+ struct drm_encoder_helper_funcs *encoder_funcs; -+ int ret; -+ -+ encoder = radeon_best_single_encoder(connector); -+ if (!encoder) -+ ret = connector_status_disconnected; -+ else { -+ encoder_funcs = encoder->helper_private; -+ ret = encoder_funcs->detect(encoder, connector); -+ } -+ if (ret == connector_status_connected) -+ ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false); -+ radeon_connector_update_scratch_regs(connector, ret); -+ return ret; -+} -+ -+struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = { -+ .get_modes = radeon_tv_get_modes, -+ .mode_valid = radeon_tv_mode_valid, -+ .best_encoder = radeon_best_single_encoder, -+}; -+ -+struct drm_connector_funcs radeon_tv_connector_funcs = { -+ .dpms = drm_helper_connector_dpms, -+ .detect = radeon_tv_detect, -+ .fill_modes = drm_helper_probe_single_connector_modes, -+ .destroy = radeon_connector_destroy, -+ .set_property = radeon_connector_set_property, -+}; -+ - static int radeon_dvi_get_modes(struct drm_connector *connector) - { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - int ret; - - ret = radeon_ddc_get_modes(radeon_connector); -- /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */ -- radeon_connector_update_scratch_regs(connector, connector_status_connected); - return ret; - } - -+/* -+ * DVI is complicated -+ * Do a DDC probe, if DDC probe passes, get the full EDID so -+ * we can do analog/digital monitor detection at this point. -+ * If the monitor is an analog monitor or we got no DDC, -+ * we need to find the DAC encoder object for this connector. -+ * If we got no DDC, we do load detection on the DAC encoder object. -+ * If we got analog DDC or load detection passes on the DAC encoder -+ * we have to check if this analog encoder is shared with anyone else (TV) -+ * if its shared we have to set the other connector to disconnected. -+ */ - static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) - { - struct radeon_connector *radeon_connector = to_radeon_connector(connector); -- struct drm_encoder *encoder; -+ struct drm_encoder *encoder = NULL; - struct drm_encoder_helper_funcs *encoder_funcs; - struct drm_mode_object *obj; - int i; -@@ -283,32 +396,58 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect - radeon_i2c_do_lock(radeon_connector, 1); - dret = radeon_ddc_probe(radeon_connector); - radeon_i2c_do_lock(radeon_connector, 0); -- if (dret) -- ret = connector_status_connected; -- else { -- for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { -- if (connector->encoder_ids[i] == 0) -- break; -+ if (dret) { -+ radeon_i2c_do_lock(radeon_connector, 1); -+ radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); -+ radeon_i2c_do_lock(radeon_connector, 0); -+ -+ if (!radeon_connector->edid) { -+ DRM_ERROR("DDC responded but not EDID found for %s\n", -+ drm_get_connector_name(connector)); -+ } else { -+ radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); -+ -+ /* if this isn't a digital monitor -+ then we need to make sure we don't have any -+ TV conflicts */ -+ ret = connector_status_connected; -+ } -+ } -+ -+ if ((ret == connector_status_connected) && (radeon_connector->use_digital == true)) -+ goto out; -+ -+ /* find analog encoder */ -+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { -+ if (connector->encoder_ids[i] == 0) -+ break; - -- obj = drm_mode_object_find(connector->dev, -- connector->encoder_ids[i], -- DRM_MODE_OBJECT_ENCODER); -- if (!obj) -- continue; -+ obj = drm_mode_object_find(connector->dev, -+ connector->encoder_ids[i], -+ DRM_MODE_OBJECT_ENCODER); -+ if (!obj) -+ continue; - -- encoder = obj_to_encoder(obj); -+ encoder = obj_to_encoder(obj); - -- encoder_funcs = encoder->helper_private; -- if (encoder_funcs->detect) { -+ encoder_funcs = encoder->helper_private; -+ if (encoder_funcs->detect) { -+ if (ret != connector_status_connected) { - ret = encoder_funcs->detect(encoder, connector); - if (ret == connector_status_connected) { -- radeon_connector->use_digital = 0; -- break; -+ radeon_connector->use_digital = false; - } - } -+ break; - } - } - -+ if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) && -+ encoder) { -+ ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true); -+ } -+ -+out: - /* updated in get modes as well since we need to know if it's analog or digital */ - radeon_connector_update_scratch_regs(connector, ret); - return ret; -@@ -332,7 +471,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) - - encoder = obj_to_encoder(obj); - -- if (radeon_connector->use_digital) { -+ if (radeon_connector->use_digital == true) { - if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS) - return encoder; - } else { -@@ -385,10 +524,7 @@ radeon_add_atom_connector(struct drm_device *dev, - uint32_t subpixel_order = SubPixelNone; - - /* fixme - tv/cv/din */ -- if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || -- (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || -- (connector_type == DRM_MODE_CONNECTOR_Composite) || -- (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) -+ if (connector_type == DRM_MODE_CONNECTOR_Unknown) - return; - - /* see if we already added it */ -@@ -480,6 +616,10 @@ radeon_add_atom_connector(struct drm_device *dev, - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_9PinDIN: -+ if (radeon_tv == 1) { -+ drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); -+ drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); -+ } - break; - case DRM_MODE_CONNECTOR_LVDS: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); -@@ -522,10 +662,7 @@ radeon_add_legacy_connector(struct drm_device *dev, - uint32_t subpixel_order = SubPixelNone; - - /* fixme - tv/cv/din */ -- if ((connector_type == DRM_MODE_CONNECTOR_Unknown) || -- (connector_type == DRM_MODE_CONNECTOR_SVIDEO) || -- (connector_type == DRM_MODE_CONNECTOR_Composite) || -- (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) -+ if (connector_type == DRM_MODE_CONNECTOR_Unknown) - return; - - /* see if we already added it */ -@@ -578,6 +715,10 @@ radeon_add_legacy_connector(struct drm_device *dev, - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_9PinDIN: -+ if (radeon_tv == 1) { -+ drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); -+ drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); -+ } - break; - case DRM_MODE_CONNECTOR_LVDS: - drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); -diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c -index 7a52c46..fa063d0 100644 ---- a/drivers/gpu/drm/radeon/radeon_cp.c -+++ b/drivers/gpu/drm/radeon/radeon_cp.c -@@ -36,10 +36,25 @@ - #include "radeon_drv.h" - #include "r300_reg.h" - --#include "radeon_microcode.h" -- - #define RADEON_FIFO_DEBUG 0 - -+/* Firmware Names */ -+#define FIRMWARE_R100 "radeon/R100_cp.bin" -+#define FIRMWARE_R200 "radeon/R200_cp.bin" -+#define FIRMWARE_R300 "radeon/R300_cp.bin" -+#define FIRMWARE_R420 "radeon/R420_cp.bin" -+#define FIRMWARE_RS690 "radeon/RS690_cp.bin" -+#define FIRMWARE_RS600 "radeon/RS600_cp.bin" -+#define FIRMWARE_R520 "radeon/R520_cp.bin" -+ -+MODULE_FIRMWARE(FIRMWARE_R100); -+MODULE_FIRMWARE(FIRMWARE_R200); -+MODULE_FIRMWARE(FIRMWARE_R300); -+MODULE_FIRMWARE(FIRMWARE_R420); -+MODULE_FIRMWARE(FIRMWARE_RS690); -+MODULE_FIRMWARE(FIRMWARE_RS600); -+MODULE_FIRMWARE(FIRMWARE_R520); -+ - static int radeon_do_cleanup_cp(struct drm_device * dev); - static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); - -@@ -460,37 +475,34 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) - */ - - /* Load the microcode for the CP */ --static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) -+static int radeon_cp_init_microcode(drm_radeon_private_t *dev_priv) - { -- int i; -+ struct platform_device *pdev; -+ const char *fw_name = NULL; -+ int err; -+ - DRM_DEBUG("\n"); - -- radeon_do_wait_for_idle(dev_priv); -+ pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); -+ err = IS_ERR(pdev); -+ if (err) { -+ printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); -+ return -EINVAL; -+ } - -- RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) { - DRM_INFO("Loading R100 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- R100_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- R100_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R100; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) { - DRM_INFO("Loading R200 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- R200_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- R200_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R200; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) || -@@ -498,39 +510,19 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { - DRM_INFO("Loading R300 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- R300_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- R300_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R300; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) { - DRM_INFO("Loading R400 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- R420_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- R420_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_R420; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { - DRM_INFO("Loading RS690/RS740 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- RS690_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- RS690_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_RS690; - } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { - DRM_INFO("Loading RS600 Microcode\n"); -- for (i = 0; i < 256; i++) { -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- RS600_cp_microcode[i][1]); -- RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- RS600_cp_microcode[i][0]); -- } -+ fw_name = FIRMWARE_RS600; - } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || -@@ -538,11 +530,41 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) { - DRM_INFO("Loading R500 Microcode\n"); -- for (i = 0; i < 256; i++) { -+ fw_name = FIRMWARE_R520; -+ } -+ -+ err = request_firmware(&dev_priv->me_fw, fw_name, &pdev->dev); -+ platform_device_unregister(pdev); -+ if (err) { -+ printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", -+ fw_name); -+ } else if (dev_priv->me_fw->size % 8) { -+ printk(KERN_ERR -+ "radeon_cp: Bogus length %zu in firmware \"%s\"\n", -+ dev_priv->me_fw->size, fw_name); -+ err = -EINVAL; -+ release_firmware(dev_priv->me_fw); -+ dev_priv->me_fw = NULL; -+ } -+ return err; -+} -+ -+static void radeon_cp_load_microcode(drm_radeon_private_t *dev_priv) -+{ -+ const __be32 *fw_data; -+ int i, size; -+ -+ radeon_do_wait_for_idle(dev_priv); -+ -+ if (dev_priv->me_fw) { -+ size = dev_priv->me_fw->size / 4; -+ fw_data = (const __be32 *)&dev_priv->me_fw->data[0]; -+ RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); -+ for (i = 0; i < size; i += 2) { - RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, -- R520_cp_microcode[i][1]); -+ be32_to_cpup(&fw_data[i])); - RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, -- R520_cp_microcode[i][0]); -+ be32_to_cpup(&fw_data[i + 1])); - } - } - } -@@ -1495,6 +1517,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, - radeon_set_pcigart(dev_priv, 1); - } - -+ if (!dev_priv->me_fw) { -+ int err = radeon_cp_init_microcode(dev_priv); -+ if (err) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ radeon_do_cleanup_cp(dev); -+ return err; -+ } -+ } - radeon_cp_load_microcode(dev_priv); - radeon_cp_init_ring_buffer(dev, dev_priv, file_priv); - -@@ -1764,6 +1794,14 @@ void radeon_do_release(struct drm_device * dev) - r600_do_cleanup_cp(dev); - else - radeon_do_cleanup_cp(dev); -+ if (dev_priv->me_fw) { -+ release_firmware(dev_priv->me_fw); -+ dev_priv->me_fw = NULL; -+ } -+ if (dev_priv->pfp_fw) { -+ release_firmware(dev_priv->pfp_fw); -+ dev_priv->pfp_fw = NULL; -+ } - } - } - -diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c -index 7693f7c..f2469c5 100644 ---- a/drivers/gpu/drm/radeon/radeon_device.c -+++ b/drivers/gpu/drm/radeon/radeon_device.c -@@ -37,7 +37,7 @@ - /* - * Clear GPU surface registers. - */ --static void radeon_surface_init(struct radeon_device *rdev) -+void radeon_surface_init(struct radeon_device *rdev) - { - /* FIXME: check this out */ - if (rdev->family < CHIP_R600) { -@@ -56,7 +56,7 @@ static void radeon_surface_init(struct radeon_device *rdev) - /* - * GPU scratch registers helpers function. - */ --static void radeon_scratch_init(struct radeon_device *rdev) -+void radeon_scratch_init(struct radeon_device *rdev) - { - int i; - -@@ -156,16 +156,14 @@ int radeon_mc_setup(struct radeon_device *rdev) - tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1); - rdev->mc.gtt_location = tmp; - } -- DRM_INFO("radeon: VRAM %uM\n", rdev->mc.real_vram_size >> 20); -+ DRM_INFO("radeon: VRAM %uM\n", (unsigned)(rdev->mc.mc_vram_size >> 20)); - DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n", -- rdev->mc.vram_location, -- rdev->mc.vram_location + rdev->mc.mc_vram_size - 1); -- if (rdev->mc.real_vram_size != rdev->mc.mc_vram_size) -- DRM_INFO("radeon: VRAM less than aperture workaround enabled\n"); -- DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20); -+ (unsigned)rdev->mc.vram_location, -+ (unsigned)(rdev->mc.vram_location + rdev->mc.mc_vram_size - 1)); -+ DRM_INFO("radeon: GTT %uM\n", (unsigned)(rdev->mc.gtt_size >> 20)); - DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n", -- rdev->mc.gtt_location, -- rdev->mc.gtt_location + rdev->mc.gtt_size - 1); -+ (unsigned)rdev->mc.gtt_location, -+ (unsigned)(rdev->mc.gtt_location + rdev->mc.gtt_size - 1)); - return 0; - } - -@@ -205,6 +203,31 @@ static bool radeon_card_posted(struct radeon_device *rdev) - - } - -+int radeon_dummy_page_init(struct radeon_device *rdev) -+{ -+ rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); -+ if (rdev->dummy_page.page == NULL) -+ return -ENOMEM; -+ rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page, -+ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); -+ if (!rdev->dummy_page.addr) { -+ __free_page(rdev->dummy_page.page); -+ rdev->dummy_page.page = NULL; -+ return -ENOMEM; -+ } -+ return 0; -+} -+ -+void radeon_dummy_page_fini(struct radeon_device *rdev) -+{ -+ if (rdev->dummy_page.page == NULL) -+ return; -+ pci_unmap_page(rdev->pdev, rdev->dummy_page.addr, -+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); -+ __free_page(rdev->dummy_page.page); -+ rdev->dummy_page.page = NULL; -+} -+ - - /* - * Registers accessors functions. -@@ -323,9 +346,15 @@ int radeon_asic_init(struct radeon_device *rdev) - case CHIP_RV635: - case CHIP_RV670: - case CHIP_RS780: -+ case CHIP_RS880: -+ rdev->asic = &r600_asic; -+ break; - case CHIP_RV770: - case CHIP_RV730: - case CHIP_RV710: -+ case CHIP_RV740: -+ rdev->asic = &rv770_asic; -+ break; - default: - /* FIXME: not supported yet */ - return -EINVAL; -@@ -448,7 +477,7 @@ int radeon_device_init(struct radeon_device *rdev, - struct pci_dev *pdev, - uint32_t flags) - { -- int r, ret; -+ int r, ret = 0; - int dma_bits; - - DRM_INFO("radeon: Initializing kernel modesetting.\n"); -@@ -487,10 +516,6 @@ int radeon_device_init(struct radeon_device *rdev, - if (r) { - return r; - } -- r = radeon_init(rdev); -- if (r) { -- return r; -- } - - /* set DMA mask + need_dma32 flags. - * PCIE - can handle 40-bits. -@@ -521,111 +546,118 @@ int radeon_device_init(struct radeon_device *rdev, - DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); - DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); - -- /* Setup errata flags */ -- radeon_errata(rdev); -- /* Initialize scratch registers */ -- radeon_scratch_init(rdev); -- /* Initialize surface registers */ -- radeon_surface_init(rdev); -- -- /* TODO: disable VGA need to use VGA request */ -- /* BIOS*/ -- if (!radeon_get_bios(rdev)) { -- if (ASIC_IS_AVIVO(rdev)) -- return -EINVAL; -- } -- if (rdev->is_atom_bios) { -- r = radeon_atombios_init(rdev); -+ rdev->new_init_path = false; -+ r = radeon_init(rdev); -+ if (r) { -+ return r; -+ } -+ if (!rdev->new_init_path) { -+ /* Setup errata flags */ -+ radeon_errata(rdev); -+ /* Initialize scratch registers */ -+ radeon_scratch_init(rdev); -+ /* Initialize surface registers */ -+ radeon_surface_init(rdev); -+ -+ /* TODO: disable VGA need to use VGA request */ -+ /* BIOS*/ -+ if (!radeon_get_bios(rdev)) { -+ if (ASIC_IS_AVIVO(rdev)) -+ return -EINVAL; -+ } -+ if (rdev->is_atom_bios) { -+ r = radeon_atombios_init(rdev); -+ if (r) { -+ return r; -+ } -+ } else { -+ r = radeon_combios_init(rdev); -+ if (r) { -+ return r; -+ } -+ } -+ /* Reset gpu before posting otherwise ATOM will enter infinite loop */ -+ if (radeon_gpu_reset(rdev)) { -+ /* FIXME: what do we want to do here ? */ -+ } -+ /* check if cards are posted or not */ -+ if (!radeon_card_posted(rdev) && rdev->bios) { -+ DRM_INFO("GPU not posted. posting now...\n"); -+ if (rdev->is_atom_bios) { -+ atom_asic_init(rdev->mode_info.atom_context); -+ } else { -+ radeon_combios_asic_init(rdev->ddev); -+ } -+ } -+ /* Initialize clocks */ -+ r = radeon_clocks_init(rdev); - if (r) { - return r; - } -- } else { -- r = radeon_combios_init(rdev); -+ /* Get vram informations */ -+ radeon_vram_info(rdev); -+ -+ /* Add an MTRR for the VRAM */ -+ rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, -+ MTRR_TYPE_WRCOMB, 1); -+ DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n", -+ (unsigned)(rdev->mc.mc_vram_size >> 20), -+ (unsigned)(rdev->mc.aper_size >> 20)); -+ DRM_INFO("RAM width %dbits %cDR\n", -+ rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S'); -+ /* Initialize memory controller (also test AGP) */ -+ r = radeon_mc_init(rdev); - if (r) { - return r; - } -- } -- /* Reset gpu before posting otherwise ATOM will enter infinite loop */ -- if (radeon_gpu_reset(rdev)) { -- /* FIXME: what do we want to do here ? */ -- } -- /* check if cards are posted or not */ -- if (!radeon_card_posted(rdev) && rdev->bios) { -- DRM_INFO("GPU not posted. posting now...\n"); -- if (rdev->is_atom_bios) { -- atom_asic_init(rdev->mode_info.atom_context); -- } else { -- radeon_combios_asic_init(rdev->ddev); -- } -- } -- /* Initialize clocks */ -- r = radeon_clocks_init(rdev); -- if (r) { -- return r; -- } -- /* Get vram informations */ -- radeon_vram_info(rdev); -- -- /* Add an MTRR for the VRAM */ -- rdev->mc.vram_mtrr = mtrr_add(rdev->mc.aper_base, rdev->mc.aper_size, -- MTRR_TYPE_WRCOMB, 1); -- DRM_INFO("Detected VRAM RAM=%uM, BAR=%uM\n", -- rdev->mc.real_vram_size >> 20, -- (unsigned)rdev->mc.aper_size >> 20); -- DRM_INFO("RAM width %dbits %cDR\n", -- rdev->mc.vram_width, rdev->mc.vram_is_ddr ? 'D' : 'S'); -- /* Initialize memory controller (also test AGP) */ -- r = radeon_mc_init(rdev); -- if (r) { -- return r; -- } -- /* Fence driver */ -- r = radeon_fence_driver_init(rdev); -- if (r) { -- return r; -- } -- r = radeon_irq_kms_init(rdev); -- if (r) { -- return r; -- } -- /* Memory manager */ -- r = radeon_object_init(rdev); -- if (r) { -- return r; -- } -- /* Initialize GART (initialize after TTM so we can allocate -- * memory through TTM but finalize after TTM) */ -- r = radeon_gart_enable(rdev); -- if (!r) { -- r = radeon_gem_init(rdev); -- } -- -- /* 1M ring buffer */ -- if (!r) { -- r = radeon_cp_init(rdev, 1024 * 1024); -- } -- if (!r) { -- r = radeon_wb_init(rdev); -+ /* Fence driver */ -+ r = radeon_fence_driver_init(rdev); - if (r) { -- DRM_ERROR("radeon: failled initializing WB (%d).\n", r); - return r; - } -- } -- if (!r) { -- r = radeon_ib_pool_init(rdev); -+ r = radeon_irq_kms_init(rdev); - if (r) { -- DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); - return r; - } -- } -- if (!r) { -- r = radeon_ib_test(rdev); -+ /* Memory manager */ -+ r = radeon_object_init(rdev); - if (r) { -- DRM_ERROR("radeon: failled testing IB (%d).\n", r); - return r; - } -+ /* Initialize GART (initialize after TTM so we can allocate -+ * memory through TTM but finalize after TTM) */ -+ r = radeon_gart_enable(rdev); -+ if (!r) { -+ r = radeon_gem_init(rdev); -+ } -+ -+ /* 1M ring buffer */ -+ if (!r) { -+ r = radeon_cp_init(rdev, 1024 * 1024); -+ } -+ if (!r) { -+ r = radeon_wb_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled initializing WB (%d).\n", r); -+ return r; -+ } -+ } -+ if (!r) { -+ r = radeon_ib_pool_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); -+ return r; -+ } -+ } -+ if (!r) { -+ r = radeon_ib_test(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled testing IB (%d).\n", r); -+ return r; -+ } -+ } -+ ret = r; - } -- ret = r; - r = radeon_modeset_init(rdev); - if (r) { - return r; -@@ -651,26 +683,29 @@ void radeon_device_fini(struct radeon_device *rdev) - rdev->shutdown = true; - /* Order matter so becarefull if you rearrange anythings */ - radeon_modeset_fini(rdev); -- radeon_ib_pool_fini(rdev); -- radeon_cp_fini(rdev); -- radeon_wb_fini(rdev); -- radeon_gem_fini(rdev); -- radeon_object_fini(rdev); -- /* mc_fini must be after object_fini */ -- radeon_mc_fini(rdev); -+ if (!rdev->new_init_path) { -+ radeon_ib_pool_fini(rdev); -+ radeon_cp_fini(rdev); -+ radeon_wb_fini(rdev); -+ radeon_gem_fini(rdev); -+ radeon_mc_fini(rdev); - #if __OS_HAS_AGP -- radeon_agp_fini(rdev); -+ radeon_agp_fini(rdev); - #endif -- radeon_irq_kms_fini(rdev); -- radeon_fence_driver_fini(rdev); -- radeon_clocks_fini(rdev); -- if (rdev->is_atom_bios) { -- radeon_atombios_fini(rdev); -+ radeon_irq_kms_fini(rdev); -+ radeon_fence_driver_fini(rdev); -+ radeon_clocks_fini(rdev); -+ radeon_object_fini(rdev); -+ if (rdev->is_atom_bios) { -+ radeon_atombios_fini(rdev); -+ } else { -+ radeon_combios_fini(rdev); -+ } -+ kfree(rdev->bios); -+ rdev->bios = NULL; - } else { -- radeon_combios_fini(rdev); -+ radeon_fini(rdev); - } -- kfree(rdev->bios); -- rdev->bios = NULL; - iounmap(rdev->rmmio); - rdev->rmmio = NULL; - } -@@ -708,9 +743,12 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) - /* wait for gpu to finish processing current batch */ - radeon_fence_wait_last(rdev); - -- radeon_cp_disable(rdev); -- radeon_gart_disable(rdev); -- -+ if (!rdev->new_init_path) { -+ radeon_cp_disable(rdev); -+ radeon_gart_disable(rdev); -+ } else { -+ radeon_suspend(rdev); -+ } - /* evict remaining vram memory */ - radeon_object_evict_vram(rdev); - -@@ -746,33 +784,37 @@ int radeon_resume_kms(struct drm_device *dev) - if (radeon_gpu_reset(rdev)) { - /* FIXME: what do we want to do here ? */ - } -- /* post card */ -- if (rdev->is_atom_bios) { -- atom_asic_init(rdev->mode_info.atom_context); -+ if (!rdev->new_init_path) { -+ /* post card */ -+ if (rdev->is_atom_bios) { -+ atom_asic_init(rdev->mode_info.atom_context); -+ } else { -+ radeon_combios_asic_init(rdev->ddev); -+ } -+ /* Initialize clocks */ -+ r = radeon_clocks_init(rdev); -+ if (r) { -+ release_console_sem(); -+ return r; -+ } -+ /* Enable IRQ */ -+ rdev->irq.sw_int = true; -+ radeon_irq_set(rdev); -+ /* Initialize GPU Memory Controller */ -+ r = radeon_mc_init(rdev); -+ if (r) { -+ goto out; -+ } -+ r = radeon_gart_enable(rdev); -+ if (r) { -+ goto out; -+ } -+ r = radeon_cp_init(rdev, rdev->cp.ring_size); -+ if (r) { -+ goto out; -+ } - } else { -- radeon_combios_asic_init(rdev->ddev); -- } -- /* Initialize clocks */ -- r = radeon_clocks_init(rdev); -- if (r) { -- release_console_sem(); -- return r; -- } -- /* Enable IRQ */ -- rdev->irq.sw_int = true; -- radeon_irq_set(rdev); -- /* Initialize GPU Memory Controller */ -- r = radeon_mc_init(rdev); -- if (r) { -- goto out; -- } -- r = radeon_gart_enable(rdev); -- if (r) { -- goto out; -- } -- r = radeon_cp_init(rdev, rdev->cp.ring_size); -- if (r) { -- goto out; -+ radeon_resume(rdev); - } - out: - fb_set_suspend(rdev->fbdev_info, 0); -diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c -index a8fa1bb..9d817a6 100644 ---- a/drivers/gpu/drm/radeon/radeon_display.c -+++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -158,9 +158,6 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc) - { - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); - -- if (radeon_crtc->mode_set.mode) { -- drm_mode_destroy(crtc->dev, radeon_crtc->mode_set.mode); -- } - drm_crtc_cleanup(crtc); - kfree(radeon_crtc); - } -@@ -189,9 +186,11 @@ static void radeon_crtc_init(struct drm_device *dev, int index) - radeon_crtc->crtc_id = index; - rdev->mode_info.crtcs[index] = radeon_crtc; - -+#if 0 - radeon_crtc->mode_set.crtc = &radeon_crtc->base; - radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1); - radeon_crtc->mode_set.num_connectors = 0; -+#endif - - for (i = 0; i < 256; i++) { - radeon_crtc->lut_r[i] = i << 2; -@@ -313,7 +312,7 @@ static void radeon_print_display_setup(struct drm_device *dev) - } - } - --bool radeon_setup_enc_conn(struct drm_device *dev) -+static bool radeon_setup_enc_conn(struct drm_device *dev) - { - struct radeon_device *rdev = dev->dev_private; - struct drm_connector *drm_connector; -@@ -347,9 +346,13 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) - - if (!radeon_connector->ddc_bus) - return -1; -- radeon_i2c_do_lock(radeon_connector, 1); -- edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); -- radeon_i2c_do_lock(radeon_connector, 0); -+ if (!radeon_connector->edid) { -+ radeon_i2c_do_lock(radeon_connector, 1); -+ edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); -+ radeon_i2c_do_lock(radeon_connector, 0); -+ } else -+ edid = radeon_connector->edid; -+ - if (edid) { - /* update digital bits here */ - if (edid->input & DRM_EDID_INPUT_DIGITAL) -@@ -678,7 +681,6 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - continue; - if (first) { - radeon_crtc->rmx_type = radeon_encoder->rmx_type; -- radeon_crtc->devices = radeon_encoder->devices; - memcpy(&radeon_crtc->native_mode, - &radeon_encoder->native_mode, - sizeof(struct radeon_native_mode)); -diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c -index 0bd5879..29f040a 100644 ---- a/drivers/gpu/drm/radeon/radeon_drv.c -+++ b/drivers/gpu/drm/radeon/radeon_drv.c -@@ -38,7 +38,6 @@ - #include - - --#if defined(CONFIG_DRM_RADEON_KMS) - /* - * KMS wrapper. - */ -@@ -77,11 +76,9 @@ int radeon_mmap(struct file *filp, struct vm_area_struct *vma); - int radeon_debugfs_init(struct drm_minor *minor); - void radeon_debugfs_cleanup(struct drm_minor *minor); - #endif --#endif - - - int radeon_no_wb; --#if defined(CONFIG_DRM_RADEON_KMS) - int radeon_modeset = -1; - int radeon_dynclks = -1; - int radeon_r4xx_atom = 0; -@@ -91,12 +88,11 @@ int radeon_gart_size = 512; /* default gart size */ - int radeon_benchmarking = 0; - int radeon_testing = 0; - int radeon_connector_table = 0; --#endif -+int radeon_tv = 1; - - MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); - module_param_named(no_wb, radeon_no_wb, int, 0444); - --#if defined(CONFIG_DRM_RADEON_KMS) - MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); - module_param_named(modeset, radeon_modeset, int, 0400); - -@@ -123,7 +119,9 @@ module_param_named(test, radeon_testing, int, 0444); - - MODULE_PARM_DESC(connector_table, "Force connector table"); - module_param_named(connector_table, radeon_connector_table, int, 0444); --#endif -+ -+MODULE_PARM_DESC(tv, "TV enable (0 = disable)"); -+module_param_named(tv, radeon_tv, int, 0444); - - static int radeon_suspend(struct drm_device *dev, pm_message_t state) - { -@@ -215,7 +213,6 @@ static struct drm_driver driver_old = { - .patchlevel = DRIVER_PATCHLEVEL, - }; - --#if defined(CONFIG_DRM_RADEON_KMS) - static struct drm_driver kms_driver; - - static int __devinit -@@ -309,7 +306,6 @@ static struct drm_driver kms_driver = { - .minor = KMS_DRIVER_MINOR, - .patchlevel = KMS_DRIVER_PATCHLEVEL, - }; --#endif - - static struct drm_driver *driver; - -@@ -317,7 +313,6 @@ static int __init radeon_init(void) - { - driver = &driver_old; - driver->num_ioctls = radeon_max_ioctl; --#if defined(CONFIG_DRM_RADEON_KMS) - #ifdef CONFIG_VGA_CONSOLE - if (vgacon_text_force() && radeon_modeset == -1) { - DRM_INFO("VGACON disable radeon kernel modesetting.\n"); -@@ -328,8 +323,13 @@ static int __init radeon_init(void) - #endif - /* if enabled by default */ - if (radeon_modeset == -1) { -- DRM_INFO("radeon default to kernel modesetting.\n"); -+#ifdef CONFIG_DRM_RADEON_KMS -+ DRM_INFO("radeon defaulting to kernel modesetting.\n"); - radeon_modeset = 1; -+#else -+ DRM_INFO("radeon defaulting to userspace modesetting.\n"); -+ radeon_modeset = 0; -+#endif - } - if (radeon_modeset == 1) { - DRM_INFO("radeon kernel modesetting enabled.\n"); -@@ -339,7 +339,6 @@ static int __init radeon_init(void) - } - /* if the vga console setting is enabled still - * let modprobe override it */ --#endif - return drm_init(driver); - } - -diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h -index 6fa32da..c7b1859 100644 ---- a/drivers/gpu/drm/radeon/radeon_drv.h -+++ b/drivers/gpu/drm/radeon/radeon_drv.h -@@ -31,6 +31,9 @@ - #ifndef __RADEON_DRV_H__ - #define __RADEON_DRV_H__ - -+#include -+#include -+ - /* General customization: - */ - -@@ -353,6 +356,14 @@ typedef struct drm_radeon_private { - int r700_sc_hiz_tile_fifo_size; - int r700_sc_earlyz_tile_fifo_fize; - -+ struct mutex cs_mutex; -+ u32 cs_id_scnt; -+ u32 cs_id_wcnt; -+ /* r6xx/r7xx drm blit vertex buffer */ -+ struct drm_buf *blit_vb; -+ -+ /* firmware */ -+ const struct firmware *me_fw, *pfp_fw; - } drm_radeon_private_t; - - typedef struct drm_radeon_buf_priv { -@@ -391,6 +402,9 @@ static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv, - (off >= gart_start && off <= gart_end)); - } - -+/* radeon_state.c */ -+extern void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf); -+ - /* radeon_cp.c */ - extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv); - extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv); -@@ -482,6 +496,22 @@ extern int r600_cp_dispatch_indirect(struct drm_device *dev, - struct drm_buf *buf, int start, int end); - extern int r600_page_table_init(struct drm_device *dev); - extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); -+extern int r600_cs_legacy_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); -+extern void r600_cp_dispatch_swap(struct drm_device *dev, struct drm_file *file_priv); -+extern int r600_cp_dispatch_texture(struct drm_device *dev, -+ struct drm_file *file_priv, -+ drm_radeon_texture_t *tex, -+ drm_radeon_tex_image_t *image); -+/* r600_blit.c */ -+extern int r600_prepare_blit_copy(struct drm_device *dev, struct drm_file *file_priv); -+extern void r600_done_blit_copy(struct drm_device *dev); -+extern void r600_blit_copy(struct drm_device *dev, -+ uint64_t src_gpu_addr, uint64_t dst_gpu_addr, -+ int size_bytes); -+extern void r600_blit_swap(struct drm_device *dev, -+ uint64_t src_gpu_addr, uint64_t dst_gpu_addr, -+ int sx, int sy, int dx, int dy, -+ int w, int h, int src_pitch, int dst_pitch, int cpp); - - /* Flags for stats.boxes - */ -@@ -1109,13 +1139,71 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); - # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 - # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 - --# define R600_IT_INDIRECT_BUFFER 0x00003200 --# define R600_IT_ME_INITIALIZE 0x00004400 -+# define R600_IT_INDIRECT_BUFFER_END 0x00001700 -+# define R600_IT_SET_PREDICATION 0x00002000 -+# define R600_IT_REG_RMW 0x00002100 -+# define R600_IT_COND_EXEC 0x00002200 -+# define R600_IT_PRED_EXEC 0x00002300 -+# define R600_IT_START_3D_CMDBUF 0x00002400 -+# define R600_IT_DRAW_INDEX_2 0x00002700 -+# define R600_IT_CONTEXT_CONTROL 0x00002800 -+# define R600_IT_DRAW_INDEX_IMMD_BE 0x00002900 -+# define R600_IT_INDEX_TYPE 0x00002A00 -+# define R600_IT_DRAW_INDEX 0x00002B00 -+# define R600_IT_DRAW_INDEX_AUTO 0x00002D00 -+# define R600_IT_DRAW_INDEX_IMMD 0x00002E00 -+# define R600_IT_NUM_INSTANCES 0x00002F00 -+# define R600_IT_STRMOUT_BUFFER_UPDATE 0x00003400 -+# define R600_IT_INDIRECT_BUFFER_MP 0x00003800 -+# define R600_IT_MEM_SEMAPHORE 0x00003900 -+# define R600_IT_MPEG_INDEX 0x00003A00 -+# define R600_IT_WAIT_REG_MEM 0x00003C00 -+# define R600_IT_MEM_WRITE 0x00003D00 -+# define R600_IT_INDIRECT_BUFFER 0x00003200 -+# define R600_IT_CP_INTERRUPT 0x00004000 -+# define R600_IT_SURFACE_SYNC 0x00004300 -+# define R600_CB0_DEST_BASE_ENA (1 << 6) -+# define R600_TC_ACTION_ENA (1 << 23) -+# define R600_VC_ACTION_ENA (1 << 24) -+# define R600_CB_ACTION_ENA (1 << 25) -+# define R600_DB_ACTION_ENA (1 << 26) -+# define R600_SH_ACTION_ENA (1 << 27) -+# define R600_SMX_ACTION_ENA (1 << 28) -+# define R600_IT_ME_INITIALIZE 0x00004400 - # define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) --# define R600_IT_EVENT_WRITE 0x00004600 --# define R600_IT_SET_CONFIG_REG 0x00006800 --# define R600_SET_CONFIG_REG_OFFSET 0x00008000 --# define R600_SET_CONFIG_REG_END 0x0000ac00 -+# define R600_IT_COND_WRITE 0x00004500 -+# define R600_IT_EVENT_WRITE 0x00004600 -+# define R600_IT_EVENT_WRITE_EOP 0x00004700 -+# define R600_IT_ONE_REG_WRITE 0x00005700 -+# define R600_IT_SET_CONFIG_REG 0x00006800 -+# define R600_SET_CONFIG_REG_OFFSET 0x00008000 -+# define R600_SET_CONFIG_REG_END 0x0000ac00 -+# define R600_IT_SET_CONTEXT_REG 0x00006900 -+# define R600_SET_CONTEXT_REG_OFFSET 0x00028000 -+# define R600_SET_CONTEXT_REG_END 0x00029000 -+# define R600_IT_SET_ALU_CONST 0x00006A00 -+# define R600_SET_ALU_CONST_OFFSET 0x00030000 -+# define R600_SET_ALU_CONST_END 0x00032000 -+# define R600_IT_SET_BOOL_CONST 0x00006B00 -+# define R600_SET_BOOL_CONST_OFFSET 0x0003e380 -+# define R600_SET_BOOL_CONST_END 0x00040000 -+# define R600_IT_SET_LOOP_CONST 0x00006C00 -+# define R600_SET_LOOP_CONST_OFFSET 0x0003e200 -+# define R600_SET_LOOP_CONST_END 0x0003e380 -+# define R600_IT_SET_RESOURCE 0x00006D00 -+# define R600_SET_RESOURCE_OFFSET 0x00038000 -+# define R600_SET_RESOURCE_END 0x0003c000 -+# define R600_SQ_TEX_VTX_INVALID_TEXTURE 0x0 -+# define R600_SQ_TEX_VTX_INVALID_BUFFER 0x1 -+# define R600_SQ_TEX_VTX_VALID_TEXTURE 0x2 -+# define R600_SQ_TEX_VTX_VALID_BUFFER 0x3 -+# define R600_IT_SET_SAMPLER 0x00006E00 -+# define R600_SET_SAMPLER_OFFSET 0x0003c000 -+# define R600_SET_SAMPLER_END 0x0003cff0 -+# define R600_IT_SET_CTL_CONST 0x00006F00 -+# define R600_SET_CTL_CONST_OFFSET 0x0003cff0 -+# define R600_SET_CTL_CONST_END 0x0003e200 -+# define R600_IT_SURFACE_BASE_UPDATE 0x00007300 - - #define RADEON_CP_PACKET_MASK 0xC0000000 - #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 -@@ -1593,6 +1681,52 @@ extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index); - #define R600_CB_COLOR7_BASE 0x2805c - #define R600_CB_COLOR7_FRAG 0x280fc - -+#define R600_CB_COLOR0_SIZE 0x28060 -+#define R600_CB_COLOR0_VIEW 0x28080 -+#define R600_CB_COLOR0_INFO 0x280a0 -+#define R600_CB_COLOR0_TILE 0x280c0 -+#define R600_CB_COLOR0_FRAG 0x280e0 -+#define R600_CB_COLOR0_MASK 0x28100 -+ -+#define AVIVO_D1MODE_VLINE_START_END 0x6538 -+#define AVIVO_D2MODE_VLINE_START_END 0x6d38 -+#define R600_CP_COHER_BASE 0x85f8 -+#define R600_DB_DEPTH_BASE 0x2800c -+#define R600_SQ_PGM_START_FS 0x28894 -+#define R600_SQ_PGM_START_ES 0x28880 -+#define R600_SQ_PGM_START_VS 0x28858 -+#define R600_SQ_PGM_RESOURCES_VS 0x28868 -+#define R600_SQ_PGM_CF_OFFSET_VS 0x288d0 -+#define R600_SQ_PGM_START_GS 0x2886c -+#define R600_SQ_PGM_START_PS 0x28840 -+#define R600_SQ_PGM_RESOURCES_PS 0x28850 -+#define R600_SQ_PGM_EXPORTS_PS 0x28854 -+#define R600_SQ_PGM_CF_OFFSET_PS 0x288cc -+#define R600_VGT_DMA_BASE 0x287e8 -+#define R600_VGT_DMA_BASE_HI 0x287e4 -+#define R600_VGT_STRMOUT_BASE_OFFSET_0 0x28b10 -+#define R600_VGT_STRMOUT_BASE_OFFSET_1 0x28b14 -+#define R600_VGT_STRMOUT_BASE_OFFSET_2 0x28b18 -+#define R600_VGT_STRMOUT_BASE_OFFSET_3 0x28b1c -+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_0 0x28b44 -+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_1 0x28b48 -+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_2 0x28b4c -+#define R600_VGT_STRMOUT_BASE_OFFSET_HI_3 0x28b50 -+#define R600_VGT_STRMOUT_BUFFER_BASE_0 0x28ad8 -+#define R600_VGT_STRMOUT_BUFFER_BASE_1 0x28ae8 -+#define R600_VGT_STRMOUT_BUFFER_BASE_2 0x28af8 -+#define R600_VGT_STRMOUT_BUFFER_BASE_3 0x28b08 -+#define R600_VGT_STRMOUT_BUFFER_OFFSET_0 0x28adc -+#define R600_VGT_STRMOUT_BUFFER_OFFSET_1 0x28aec -+#define R600_VGT_STRMOUT_BUFFER_OFFSET_2 0x28afc -+#define R600_VGT_STRMOUT_BUFFER_OFFSET_3 0x28b0c -+ -+#define R600_VGT_PRIMITIVE_TYPE 0x8958 -+ -+#define R600_PA_SC_SCREEN_SCISSOR_TL 0x28030 -+#define R600_PA_SC_GENERIC_SCISSOR_TL 0x28240 -+#define R600_PA_SC_WINDOW_SCISSOR_TL 0x28204 -+ - #define R600_TC_CNTL 0x9608 - # define R600_TC_L2_SIZE(x) ((x) << 5) - # define R600_L2_DISABLE_LATE_HIT (1 << 9) -diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c -index 0a92706..9ad2035 100644 ---- a/drivers/gpu/drm/radeon/radeon_encoders.c -+++ b/drivers/gpu/drm/radeon/radeon_encoders.c -@@ -126,6 +126,23 @@ radeon_link_encoder_connector(struct drm_device *dev) - } - } - -+void radeon_encoder_set_active_device(struct drm_encoder *encoder) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct drm_connector *connector; -+ -+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { -+ if (connector->encoder == encoder) { -+ struct radeon_connector *radeon_connector = to_radeon_connector(connector); -+ radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices; -+ DRM_DEBUG("setting active device to %08x from %08x %08x for encoder %d\n", -+ radeon_encoder->active_device, radeon_encoder->devices, -+ radeon_connector->devices, encoder->encoder_type); -+ } -+ } -+} -+ - static struct drm_connector * - radeon_get_connector_for_encoder(struct drm_encoder *encoder) - { -@@ -244,9 +261,9 @@ atombios_dac_setup(struct drm_encoder *encoder, int action) - - args.ucAction = action; - -- if (radeon_encoder->devices & (ATOM_DEVICE_CRT_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_CRT_SUPPORT)) - args.ucDacStandard = ATOM_DAC1_PS2; -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.ucDacStandard = ATOM_DAC1_CV; - else { - switch (tv_std) { -@@ -288,7 +305,7 @@ atombios_tv_setup(struct drm_encoder *encoder, int action) - - args.sTVEncoder.ucAction = action; - -- if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.sTVEncoder.ucTvStandard = ATOM_TV_CV; - else { - switch (tv_std) { -@@ -825,10 +842,10 @@ atombios_yuv_setup(struct drm_encoder *encoder, bool enable) - - /* XXX: fix up scratch reg handling */ - temp = RREG32(reg); -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - WREG32(reg, (ATOM_S3_TV1_ACTIVE | - (radeon_crtc->crtc_id << 18))); -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - WREG32(reg, (ATOM_S3_CV_ACTIVE | (radeon_crtc->crtc_id << 24))); - else - WREG32(reg, 0); -@@ -851,9 +868,19 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) - DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION args; - int index = 0; - bool is_dig = false; -+ int devices; - - memset(&args, 0, sizeof(args)); - -+ /* on DPMS off we have no idea if active device is meaningful */ -+ if (mode != DRM_MODE_DPMS_ON && !radeon_encoder->active_device) -+ devices = radeon_encoder->devices; -+ else -+ devices = radeon_encoder->active_device; -+ -+ DRM_DEBUG("encoder dpms %d to mode %d, devices %08x, active_devices %08x\n", -+ radeon_encoder->encoder_id, mode, radeon_encoder->devices, -+ radeon_encoder->active_device); - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_TMDS1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: -@@ -881,18 +908,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (devices & (ATOM_DEVICE_TV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (devices & (ATOM_DEVICE_CV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (devices & (ATOM_DEVICE_TV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (devices & (ATOM_DEVICE_CV_SUPPORT)) - index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); - else - index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); -@@ -979,18 +1006,18 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; - else - args.v1.ucDevice = ATOM_DEVICE_CRT1_INDEX; - break; - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_TV1_INDEX; -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v1.ucDevice = ATOM_DEVICE_CV_INDEX; - else - args.v1.ucDevice = ATOM_DEVICE_CRT2_INDEX; -@@ -1019,17 +1046,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) - args.v2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID; - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else - args.v2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID; - break; - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; -- else if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT)) -+ else if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT)) - args.v2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; - else - args.v2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID; -@@ -1097,7 +1124,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, - atombios_set_encoder_crtc_source(encoder); - - if (ASIC_IS_AVIVO(rdev)) { -- if (radeon_encoder->devices & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) - atombios_yuv_setup(encoder, true); - else - atombios_yuv_setup(encoder, false); -@@ -1135,7 +1162,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, - case ENCODER_OBJECT_ID_INTERNAL_DAC2: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - atombios_dac_setup(encoder, ATOM_ENABLE); -- if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) -+ if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) - atombios_tv_setup(encoder, ATOM_ENABLE); - break; - } -@@ -1143,11 +1170,12 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, - } - - static bool --atombios_dac_load_detect(struct drm_encoder *encoder) -+atombios_dac_load_detect(struct drm_encoder *encoder, struct drm_connector *connector) - { - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_connector *radeon_connector = to_radeon_connector(connector); - - if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT | - ATOM_DEVICE_CV_SUPPORT | -@@ -1168,15 +1196,15 @@ atombios_dac_load_detect(struct drm_encoder *encoder) - else - args.sDacload.ucDacType = ATOM_DAC_B; - -- if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) -+ if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT); -- else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) -+ else if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT); -- else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { -+ else if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT); - if (crev >= 3) - args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; -- } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { -+ } else if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { - args.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT); - if (crev >= 3) - args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb; -@@ -1195,9 +1223,10 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_connector *radeon_connector = to_radeon_connector(connector); - uint32_t bios_0_scratch; - -- if (!atombios_dac_load_detect(encoder)) { -+ if (!atombios_dac_load_detect(encoder, connector)) { - DRM_DEBUG("detect returned false \n"); - return connector_status_unknown; - } -@@ -1207,17 +1236,20 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec - else - bios_0_scratch = RREG32(RADEON_BIOS_0_SCRATCH); - -- DRM_DEBUG("Bios 0 scratch %x\n", bios_0_scratch); -- if (radeon_encoder->devices & ATOM_DEVICE_CRT1_SUPPORT) { -+ DRM_DEBUG("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices); -+ if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT1_MASK) - return connector_status_connected; -- } else if (radeon_encoder->devices & ATOM_DEVICE_CRT2_SUPPORT) { -+ } -+ if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT2_MASK) - return connector_status_connected; -- } else if (radeon_encoder->devices & ATOM_DEVICE_CV_SUPPORT) { -+ } -+ if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A)) - return connector_status_connected; -- } else if (radeon_encoder->devices & ATOM_DEVICE_TV1_SUPPORT) { -+ } -+ if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) { - if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) - return connector_status_connected; /* CTV */ - else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) -@@ -1230,6 +1262,8 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) - { - radeon_atom_output_lock(encoder, true); - radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -+ -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_atom_encoder_commit(struct drm_encoder *encoder) -@@ -1238,12 +1272,20 @@ static void radeon_atom_encoder_commit(struct drm_encoder *encoder) - radeon_atom_output_lock(encoder, false); - } - -+static void radeon_atom_encoder_disable(struct drm_encoder *encoder) -+{ -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder->active_device = 0; -+} -+ - static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = { - .dpms = radeon_atom_encoder_dpms, - .mode_fixup = radeon_atom_mode_fixup, - .prepare = radeon_atom_encoder_prepare, - .mode_set = radeon_atom_encoder_mode_set, - .commit = radeon_atom_encoder_commit, -+ .disable = radeon_atom_encoder_disable, - /* no detect for TMDS/LVDS yet */ - }; - -@@ -1268,6 +1310,18 @@ static const struct drm_encoder_funcs radeon_atom_enc_funcs = { - .destroy = radeon_enc_destroy, - }; - -+struct radeon_encoder_atom_dac * -+radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) -+{ -+ struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); -+ -+ if (!dac) -+ return NULL; -+ -+ dac->tv_std = TV_STD_NTSC; -+ return dac; -+} -+ - struct radeon_encoder_atom_dig * - radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) - { -@@ -1336,6 +1390,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1: - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2: - drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TVDAC); -+ radeon_encoder->enc_priv = radeon_atombios_set_dac_info(radeon_encoder); - drm_encoder_helper_add(encoder, &radeon_atom_dac_helper_funcs); - break; - case ENCODER_OBJECT_ID_INTERNAL_DVO1: -@@ -1345,8 +1400,14 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: -- drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); -- radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); -+ if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { -+ radeon_encoder->rmx_type = RMX_FULL; -+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS); -+ radeon_encoder->enc_priv = radeon_atombios_get_lvds_info(radeon_encoder); -+ } else { -+ drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS); -+ radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder); -+ } - drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); - break; - } -diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c -index ec383ed..ebb5895 100644 ---- a/drivers/gpu/drm/radeon/radeon_fb.c -+++ b/drivers/gpu/drm/radeon/radeon_fb.c -@@ -28,15 +28,7 @@ - */ - - #include --#include --#include --#include --#include --#include --#include --#include - #include --#include - - #include "drmP.h" - #include "drm.h" -@@ -45,375 +37,86 @@ - #include "radeon_drm.h" - #include "radeon.h" - -+#include "drm_fb_helper.h" -+ - struct radeon_fb_device { -- struct radeon_device *rdev; -- struct drm_display_mode *mode; -+ struct drm_fb_helper helper; - struct radeon_framebuffer *rfb; -- int crtc_count; -- /* crtc currently bound to this */ -- uint32_t crtc_ids[2]; -+ struct radeon_device *rdev; - }; - --static int radeonfb_setcolreg(unsigned regno, -- unsigned red, -- unsigned green, -- unsigned blue, -- unsigned transp, -- struct fb_info *info) --{ -- struct radeon_fb_device *rfbdev = info->par; -- struct drm_device *dev = rfbdev->rdev->ddev; -- struct drm_crtc *crtc; -- int i; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); -- struct drm_mode_set *modeset = &radeon_crtc->mode_set; -- struct drm_framebuffer *fb = modeset->fb; -- -- for (i = 0; i < rfbdev->crtc_count; i++) { -- if (crtc->base.id == rfbdev->crtc_ids[i]) { -- break; -- } -- } -- if (i == rfbdev->crtc_count) { -- continue; -- } -- if (regno > 255) { -- return 1; -- } -- if (fb->depth == 8) { -- radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno); -- return 0; -- } -- -- if (regno < 16) { -- switch (fb->depth) { -- case 15: -- fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | -- ((green & 0xf800) >> 6) | -- ((blue & 0xf800) >> 11); -- break; -- case 16: -- fb->pseudo_palette[regno] = (red & 0xf800) | -- ((green & 0xfc00) >> 5) | -- ((blue & 0xf800) >> 11); -- break; -- case 24: -- case 32: -- fb->pseudo_palette[regno] = -- (((red >> 8) & 0xff) << info->var.red.offset) | -- (((green >> 8) & 0xff) << info->var.green.offset) | -- (((blue >> 8) & 0xff) << info->var.blue.offset); -- break; -- } -- } -- } -- return 0; --} -- --static int radeonfb_check_var(struct fb_var_screeninfo *var, -- struct fb_info *info) -+static int radeon_fb_check_var(struct fb_var_screeninfo *var, -+ struct fb_info *info) - { -- struct radeon_fb_device *rfbdev = info->par; -- struct radeon_framebuffer *rfb = rfbdev->rfb; -- struct drm_framebuffer *fb = &rfb->base; -- int depth; -- -- if (var->pixclock == -1 || !var->pixclock) { -- return -EINVAL; -- } -- /* Need to resize the fb object !!! */ -- if (var->xres > fb->width || var->yres > fb->height) { -- DRM_ERROR("Requested width/height is greater than current fb " -- "object %dx%d > %dx%d\n", var->xres, var->yres, -- fb->width, fb->height); -- DRM_ERROR("Need resizing code.\n"); -- return -EINVAL; -- } -- -- switch (var->bits_per_pixel) { -- case 16: -- depth = (var->green.length == 6) ? 16 : 15; -- break; -- case 32: -- depth = (var->transp.length > 0) ? 32 : 24; -- break; -- default: -- depth = var->bits_per_pixel; -- break; -- } -- -- switch (depth) { -- case 8: -- var->red.offset = 0; -- var->green.offset = 0; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; --#ifdef __LITTLE_ENDIAN -- case 15: -- var->red.offset = 10; -- var->green.offset = 5; -- var->blue.offset = 0; -- var->red.length = 5; -- var->green.length = 5; -- var->blue.length = 5; -- var->transp.length = 1; -- var->transp.offset = 15; -- break; -- case 16: -- var->red.offset = 11; -- var->green.offset = 5; -- var->blue.offset = 0; -- var->red.length = 5; -- var->green.length = 6; -- var->blue.length = 5; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 24: -- var->red.offset = 16; -- var->green.offset = 8; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 32: -- var->red.offset = 16; -- var->green.offset = 8; -- var->blue.offset = 0; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 8; -- var->transp.offset = 24; -- break; --#else -- case 24: -- var->red.offset = 8; -- var->green.offset = 16; -- var->blue.offset = 24; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 0; -- var->transp.offset = 0; -- break; -- case 32: -- var->red.offset = 8; -- var->green.offset = 16; -- var->blue.offset = 24; -- var->red.length = 8; -- var->green.length = 8; -- var->blue.length = 8; -- var->transp.length = 8; -- var->transp.offset = 0; -- break; --#endif -- default: -- return -EINVAL; -- } -- return 0; --} -- --/* this will let fbcon do the mode init */ --static int radeonfb_set_par(struct fb_info *info) --{ -- struct radeon_fb_device *rfbdev = info->par; -- struct drm_device *dev = rfbdev->rdev->ddev; -- struct fb_var_screeninfo *var = &info->var; -- struct drm_crtc *crtc; - int ret; -- int i; -- -- if (var->pixclock != -1) { -- DRM_ERROR("PIXEL CLCOK SET\n"); -- return -EINVAL; -- } -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); -- -- for (i = 0; i < rfbdev->crtc_count; i++) { -- if (crtc->base.id == rfbdev->crtc_ids[i]) { -- break; -- } -- } -- if (i == rfbdev->crtc_count) { -- continue; -- } -- if (crtc->fb == radeon_crtc->mode_set.fb) { -- mutex_lock(&dev->mode_config.mutex); -- ret = crtc->funcs->set_config(&radeon_crtc->mode_set); -- mutex_unlock(&dev->mode_config.mutex); -- if (ret) { -- return ret; -- } -- } -- } -- return 0; --} -- --static int radeonfb_pan_display(struct fb_var_screeninfo *var, -- struct fb_info *info) --{ -- struct radeon_fb_device *rfbdev = info->par; -- struct drm_device *dev = rfbdev->rdev->ddev; -- struct drm_mode_set *modeset; -- struct drm_crtc *crtc; -- struct radeon_crtc *radeon_crtc; -- int ret = 0; -- int i; -- -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- for (i = 0; i < rfbdev->crtc_count; i++) { -- if (crtc->base.id == rfbdev->crtc_ids[i]) { -- break; -- } -- } -- -- if (i == rfbdev->crtc_count) { -- continue; -- } -- -- radeon_crtc = to_radeon_crtc(crtc); -- modeset = &radeon_crtc->mode_set; -- -- modeset->x = var->xoffset; -- modeset->y = var->yoffset; -- -- if (modeset->num_connectors) { -- mutex_lock(&dev->mode_config.mutex); -- ret = crtc->funcs->set_config(modeset); -- mutex_unlock(&dev->mode_config.mutex); -- if (!ret) { -- info->var.xoffset = var->xoffset; -- info->var.yoffset = var->yoffset; -- } -+ ret = drm_fb_helper_check_var(var, info); -+ if (ret) -+ return ret; -+ -+ /* big endian override for radeon endian workaround */ -+#ifdef __BIG_ENDIAN -+ { -+ int depth; -+ switch (var->bits_per_pixel) { -+ case 16: -+ depth = (var->green.length == 6) ? 16 : 15; -+ break; -+ case 32: -+ depth = (var->transp.length > 0) ? 32 : 24; -+ break; -+ default: -+ depth = var->bits_per_pixel; -+ break; - } -- } -- return ret; --} -- --static void radeonfb_on(struct fb_info *info) --{ -- struct radeon_fb_device *rfbdev = info->par; -- struct drm_device *dev = rfbdev->rdev->ddev; -- struct drm_crtc *crtc; -- struct drm_encoder *encoder; -- int i; -- -- /* -- * For each CRTC in this fb, find all associated encoders -- * and turn them off, then turn off the CRTC. -- */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -- -- for (i = 0; i < rfbdev->crtc_count; i++) { -- if (crtc->base.id == rfbdev->crtc_ids[i]) { -- break; -- } -- } -- -- mutex_lock(&dev->mode_config.mutex); -- crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); -- mutex_unlock(&dev->mode_config.mutex); -- -- /* Found a CRTC on this fb, now find encoders */ -- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -- if (encoder->crtc == crtc) { -- struct drm_encoder_helper_funcs *encoder_funcs; -- -- encoder_funcs = encoder->helper_private; -- mutex_lock(&dev->mode_config.mutex); -- encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); -- mutex_unlock(&dev->mode_config.mutex); -- } -- } -- } --} -- --static void radeonfb_off(struct fb_info *info, int dpms_mode) --{ -- struct radeon_fb_device *rfbdev = info->par; -- struct drm_device *dev = rfbdev->rdev->ddev; -- struct drm_crtc *crtc; -- struct drm_encoder *encoder; -- int i; -- -- /* -- * For each CRTC in this fb, find all associated encoders -- * and turn them off, then turn off the CRTC. -- */ -- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { -- struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; -- -- for (i = 0; i < rfbdev->crtc_count; i++) { -- if (crtc->base.id == rfbdev->crtc_ids[i]) { -- break; -- } -- } -- -- /* Found a CRTC on this fb, now find encoders */ -- list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -- if (encoder->crtc == crtc) { -- struct drm_encoder_helper_funcs *encoder_funcs; -- -- encoder_funcs = encoder->helper_private; -- mutex_lock(&dev->mode_config.mutex); -- encoder_funcs->dpms(encoder, dpms_mode); -- mutex_unlock(&dev->mode_config.mutex); -- } -- } -- if (dpms_mode == DRM_MODE_DPMS_OFF) { -- mutex_lock(&dev->mode_config.mutex); -- crtc_funcs->dpms(crtc, dpms_mode); -- mutex_unlock(&dev->mode_config.mutex); -+ switch (depth) { -+ case 8: -+ var->red.offset = 0; -+ var->green.offset = 0; -+ var->blue.offset = 0; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 0; -+ var->transp.offset = 0; -+ break; -+ case 24: -+ var->red.offset = 8; -+ var->green.offset = 16; -+ var->blue.offset = 24; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 0; -+ var->transp.offset = 0; -+ break; -+ case 32: -+ var->red.offset = 8; -+ var->green.offset = 16; -+ var->blue.offset = 24; -+ var->red.length = 8; -+ var->green.length = 8; -+ var->blue.length = 8; -+ var->transp.length = 8; -+ var->transp.offset = 0; -+ break; -+ default: -+ return -EINVAL; - } - } --} -- --int radeonfb_blank(int blank, struct fb_info *info) --{ -- switch (blank) { -- case FB_BLANK_UNBLANK: -- radeonfb_on(info); -- break; -- case FB_BLANK_NORMAL: -- radeonfb_off(info, DRM_MODE_DPMS_STANDBY); -- break; -- case FB_BLANK_HSYNC_SUSPEND: -- radeonfb_off(info, DRM_MODE_DPMS_STANDBY); -- break; -- case FB_BLANK_VSYNC_SUSPEND: -- radeonfb_off(info, DRM_MODE_DPMS_SUSPEND); -- break; -- case FB_BLANK_POWERDOWN: -- radeonfb_off(info, DRM_MODE_DPMS_OFF); -- break; -- } -+#endif - return 0; - } - - static struct fb_ops radeonfb_ops = { - .owner = THIS_MODULE, -- .fb_check_var = radeonfb_check_var, -- .fb_set_par = radeonfb_set_par, -- .fb_setcolreg = radeonfb_setcolreg, -+ .fb_check_var = radeon_fb_check_var, -+ .fb_set_par = drm_fb_helper_set_par, -+ .fb_setcolreg = drm_fb_helper_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -- .fb_pan_display = radeonfb_pan_display, -- .fb_blank = radeonfb_blank, -+ .fb_pan_display = drm_fb_helper_pan_display, -+ .fb_blank = drm_fb_helper_blank, - }; - - /** -@@ -456,21 +159,6 @@ int radeonfb_resize(struct drm_device *dev, struct drm_crtc *crtc) - } - EXPORT_SYMBOL(radeonfb_resize); - --static struct drm_mode_set panic_mode; -- --int radeonfb_panic(struct notifier_block *n, unsigned long ununsed, -- void *panic_str) --{ -- DRM_ERROR("panic occurred, switching back to text console\n"); -- drm_crtc_helper_set_config(&panic_mode); -- return 0; --} --EXPORT_SYMBOL(radeonfb_panic); -- --static struct notifier_block paniced = { -- .notifier_call = radeonfb_panic, --}; -- - static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) - { - int aligned = width; -@@ -495,11 +183,16 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo - return aligned; - } - --int radeonfb_create(struct radeon_device *rdev, -+static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { -+ .gamma_set = radeon_crtc_fb_gamma_set, -+}; -+ -+int radeonfb_create(struct drm_device *dev, - uint32_t fb_width, uint32_t fb_height, - uint32_t surface_width, uint32_t surface_height, -- struct radeon_framebuffer **rfb_p) -+ struct drm_framebuffer **fb_p) - { -+ struct radeon_device *rdev = dev->dev_private; - struct fb_info *info; - struct radeon_fb_device *rfbdev; - struct drm_framebuffer *fb = NULL; -@@ -554,8 +247,8 @@ int radeonfb_create(struct radeon_device *rdev, - - list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); - -+ *fb_p = fb; - rfb = to_radeon_framebuffer(fb); -- *rfb_p = rfb; - rdev->fbdev_rfb = rfb; - rdev->fbdev_robj = robj; - -@@ -564,7 +257,14 @@ int radeonfb_create(struct radeon_device *rdev, - ret = -ENOMEM; - goto out_unref; - } -+ - rfbdev = info->par; -+ rfbdev->helper.funcs = &radeon_fb_helper_funcs; -+ rfbdev->helper.dev = dev; -+ ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2, -+ RADEONFB_CONN_LIMIT); -+ if (ret) -+ goto out_unref; - - if (fb_tiled) - radeon_object_check_tiling(robj, 0, 0); -@@ -577,33 +277,19 @@ int radeonfb_create(struct radeon_device *rdev, - memset_io(fbptr, 0, aligned_size); - - strcpy(info->fix.id, "radeondrmfb"); -- info->fix.type = FB_TYPE_PACKED_PIXELS; -- info->fix.visual = FB_VISUAL_TRUECOLOR; -- info->fix.type_aux = 0; -- info->fix.xpanstep = 1; /* doing it in hw */ -- info->fix.ypanstep = 1; /* doing it in hw */ -- info->fix.ywrapstep = 0; -- info->fix.accel = FB_ACCEL_NONE; -- info->fix.type_aux = 0; -+ -+ drm_fb_helper_fill_fix(info, fb->pitch); -+ - info->flags = FBINFO_DEFAULT; - info->fbops = &radeonfb_ops; -- info->fix.line_length = fb->pitch; -+ - tmp = fb_gpuaddr - rdev->mc.vram_location; - info->fix.smem_start = rdev->mc.aper_base + tmp; - info->fix.smem_len = size; - info->screen_base = fbptr; - info->screen_size = size; -- info->pseudo_palette = fb->pseudo_palette; -- info->var.xres_virtual = fb->width; -- info->var.yres_virtual = fb->height; -- info->var.bits_per_pixel = fb->bits_per_pixel; -- info->var.xoffset = 0; -- info->var.yoffset = 0; -- info->var.activate = FB_ACTIVATE_NOW; -- info->var.height = -1; -- info->var.width = -1; -- info->var.xres = fb_width; -- info->var.yres = fb_height; -+ -+ drm_fb_helper_fill_var(info, fb, fb_width, fb_height); - - /* setup aperture base/size for vesafb takeover */ - info->aperture_base = rdev->ddev->mode_config.fb_base; -@@ -626,6 +312,9 @@ int radeonfb_create(struct radeon_device *rdev, - DRM_INFO("fb depth is %d\n", fb->depth); - DRM_INFO(" pitch is %d\n", fb->pitch); - -+#ifdef __BIG_ENDIAN -+ /* fill var sets defaults for this stuff - override -+ on big endian */ - switch (fb->depth) { - case 8: - info->var.red.offset = 0; -@@ -637,47 +326,6 @@ int radeonfb_create(struct radeon_device *rdev, - info->var.transp.offset = 0; - info->var.transp.length = 0; - break; --#ifdef __LITTLE_ENDIAN -- case 15: -- info->var.red.offset = 10; -- info->var.green.offset = 5; -- info->var.blue.offset = 0; -- info->var.red.length = 5; -- info->var.green.length = 5; -- info->var.blue.length = 5; -- info->var.transp.offset = 15; -- info->var.transp.length = 1; -- break; -- case 16: -- info->var.red.offset = 11; -- info->var.green.offset = 5; -- info->var.blue.offset = 0; -- info->var.red.length = 5; -- info->var.green.length = 6; -- info->var.blue.length = 5; -- info->var.transp.offset = 0; -- break; -- case 24: -- info->var.red.offset = 16; -- info->var.green.offset = 8; -- info->var.blue.offset = 0; -- info->var.red.length = 8; -- info->var.green.length = 8; -- info->var.blue.length = 8; -- info->var.transp.offset = 0; -- info->var.transp.length = 0; -- break; -- case 32: -- info->var.red.offset = 16; -- info->var.green.offset = 8; -- info->var.blue.offset = 0; -- info->var.red.length = 8; -- info->var.green.length = 8; -- info->var.blue.length = 8; -- info->var.transp.offset = 24; -- info->var.transp.length = 8; -- break; --#else - case 24: - info->var.red.offset = 8; - info->var.green.offset = 16; -@@ -699,9 +347,9 @@ int radeonfb_create(struct radeon_device *rdev, - info->var.transp.length = 8; - break; - default: --#endif - break; - } -+#endif - - fb->fbdev = info; - rfbdev->rfb = rfb; -@@ -726,145 +374,10 @@ out: - return ret; - } - --static int radeonfb_single_fb_probe(struct radeon_device *rdev) --{ -- struct drm_crtc *crtc; -- struct drm_connector *connector; -- unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; -- unsigned int surface_width = 0, surface_height = 0; -- int new_fb = 0; -- int crtc_count = 0; -- int ret, i, conn_count = 0; -- struct radeon_framebuffer *rfb; -- struct fb_info *info; -- struct radeon_fb_device *rfbdev; -- struct drm_mode_set *modeset = NULL; -- -- /* first up get a count of crtcs now in use and new min/maxes width/heights */ -- list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) { -- if (drm_helper_crtc_in_use(crtc)) { -- if (crtc->desired_mode) { -- if (crtc->desired_mode->hdisplay < fb_width) -- fb_width = crtc->desired_mode->hdisplay; -- -- if (crtc->desired_mode->vdisplay < fb_height) -- fb_height = crtc->desired_mode->vdisplay; -- -- if (crtc->desired_mode->hdisplay > surface_width) -- surface_width = crtc->desired_mode->hdisplay; -- -- if (crtc->desired_mode->vdisplay > surface_height) -- surface_height = crtc->desired_mode->vdisplay; -- } -- crtc_count++; -- } -- } -- -- if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { -- /* hmm everyone went away - assume VGA cable just fell out -- and will come back later. */ -- return 0; -- } -- -- /* do we have an fb already? */ -- if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) { -- /* create an fb if we don't have one */ -- ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb); -- if (ret) { -- return -EINVAL; -- } -- new_fb = 1; -- } else { -- struct drm_framebuffer *fb; -- fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head); -- rfb = to_radeon_framebuffer(fb); -- -- /* if someone hotplugs something bigger than we have already allocated, we are pwned. -- As really we can't resize an fbdev that is in the wild currently due to fbdev -- not really being designed for the lower layers moving stuff around under it. -- - so in the grand style of things - punt. */ -- if ((fb->width < surface_width) || (fb->height < surface_height)) { -- DRM_ERROR("Framebuffer not large enough to scale console onto.\n"); -- return -EINVAL; -- } -- } -- -- info = rfb->base.fbdev; -- rdev->fbdev_info = info; -- rfbdev = info->par; -- -- crtc_count = 0; -- /* okay we need to setup new connector sets in the crtcs */ -- list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) { -- struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); -- modeset = &radeon_crtc->mode_set; -- modeset->fb = &rfb->base; -- conn_count = 0; -- list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) { -- if (connector->encoder) -- if (connector->encoder->crtc == modeset->crtc) { -- modeset->connectors[conn_count] = connector; -- conn_count++; -- if (conn_count > RADEONFB_CONN_LIMIT) -- BUG(); -- } -- } -- -- for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++) -- modeset->connectors[i] = NULL; -- -- -- rfbdev->crtc_ids[crtc_count++] = crtc->base.id; -- -- modeset->num_connectors = conn_count; -- if (modeset->crtc->desired_mode) { -- if (modeset->mode) { -- drm_mode_destroy(rdev->ddev, modeset->mode); -- } -- modeset->mode = drm_mode_duplicate(rdev->ddev, -- modeset->crtc->desired_mode); -- } -- } -- rfbdev->crtc_count = crtc_count; -- -- if (new_fb) { -- info->var.pixclock = -1; -- if (register_framebuffer(info) < 0) -- return -EINVAL; -- } else { -- radeonfb_set_par(info); -- } -- printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -- info->fix.id); -- -- /* Switch back to kernel console on panic */ -- panic_mode = *modeset; -- atomic_notifier_chain_register(&panic_notifier_list, &paniced); -- printk(KERN_INFO "registered panic notifier\n"); -- -- return 0; --} -- - int radeonfb_probe(struct drm_device *dev) - { - int ret; -- -- /* something has changed in the lower levels of hell - deal with it -- here */ -- -- /* two modes : a) 1 fb to rule all crtcs. -- b) one fb per crtc. -- two actions 1) new connected device -- 2) device removed. -- case a/1 : if the fb surface isn't big enough - resize the surface fb. -- if the fb size isn't big enough - resize fb into surface. -- if everything big enough configure the new crtc/etc. -- case a/2 : undo the configuration -- possibly resize down the fb to fit the new configuration. -- case b/1 : see if it is on a new crtc - setup a new fb and add it. -- case b/2 : teardown the new fb. -- */ -- ret = radeonfb_single_fb_probe(dev->dev_private); -+ ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create); - return ret; - } - EXPORT_SYMBOL(radeonfb_probe); -@@ -880,16 +393,17 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) - } - info = fb->fbdev; - if (info) { -+ struct radeon_fb_device *rfbdev = info->par; - robj = rfb->obj->driver_private; - unregister_framebuffer(info); - radeon_object_kunmap(robj); - radeon_object_unpin(robj); -+ drm_fb_helper_free(&rfbdev->helper); - framebuffer_release(info); - } - - printk(KERN_INFO "unregistered panic notifier\n"); -- atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); -- memset(&panic_mode, 0, sizeof(struct drm_mode_set)); -+ - return 0; - } - EXPORT_SYMBOL(radeonfb_remove); -diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c -index b4e48dd..3beb26d 100644 ---- a/drivers/gpu/drm/radeon/radeon_fence.c -+++ b/drivers/gpu/drm/radeon/radeon_fence.c -@@ -53,9 +53,9 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) - * away - */ - WREG32(rdev->fence_drv.scratch_reg, fence->seq); -- } else { -+ } else - radeon_fence_ring_emit(rdev, fence); -- } -+ - fence->emited = true; - fence->timeout = jiffies + ((2000 * HZ) / 1000); - list_del(&fence->list); -@@ -168,7 +168,38 @@ bool radeon_fence_signaled(struct radeon_fence *fence) - return signaled; - } - --int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) -+int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy) -+{ -+ struct radeon_device *rdev; -+ int ret = 0; -+ -+ rdev = fence->rdev; -+ -+ __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); -+ -+ while (1) { -+ if (radeon_fence_signaled(fence)) -+ break; -+ -+ if (time_after_eq(jiffies, fence->timeout)) { -+ ret = -EBUSY; -+ break; -+ } -+ -+ if (lazy) -+ schedule_timeout(1); -+ -+ if (intr && signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ } -+ __set_current_state(TASK_RUNNING); -+ return ret; -+} -+ -+ -+int radeon_fence_wait(struct radeon_fence *fence, bool intr) - { - struct radeon_device *rdev; - unsigned long cur_jiffies; -@@ -176,7 +207,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) - bool expired = false; - int r; - -- - if (fence == NULL) { - WARN(1, "Querying an invalid fence : %p !\n", fence); - return 0; -@@ -185,13 +215,22 @@ int radeon_fence_wait(struct radeon_fence *fence, bool interruptible) - if (radeon_fence_signaled(fence)) { - return 0; - } -+ -+ if (rdev->family >= CHIP_R600) { -+ r = r600_fence_wait(fence, intr, 0); -+ if (r == -ERESTARTSYS) -+ return -EBUSY; -+ return r; -+ } -+ - retry: - cur_jiffies = jiffies; - timeout = HZ / 100; - if (time_after(fence->timeout, cur_jiffies)) { - timeout = fence->timeout - cur_jiffies; - } -- if (interruptible) { -+ -+ if (intr) { - r = wait_event_interruptible_timeout(rdev->fence_drv.queue, - radeon_fence_signaled(fence), timeout); - if (unlikely(r == -ERESTARTSYS)) { -diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c -index 9805e4b..1841145 100644 ---- a/drivers/gpu/drm/radeon/radeon_irq_kms.c -+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c -@@ -28,7 +28,6 @@ - #include "drmP.h" - #include "radeon_drm.h" - #include "radeon_reg.h" --#include "radeon_microcode.h" - #include "radeon.h" - #include "atom.h" - -diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c -index 0da72f1..0d29d15 100644 ---- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c -+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c -@@ -28,6 +28,7 @@ - #include - #include "radeon_fixed.h" - #include "radeon.h" -+#include "atom.h" - - static void radeon_legacy_rmx_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, -@@ -501,6 +502,7 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod - struct drm_device *dev = crtc->dev; - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); -+ struct drm_encoder *encoder; - int format; - int hsync_start; - int hsync_wid; -@@ -509,8 +511,19 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod - uint32_t crtc_h_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_v_sync_strt_wid; -+ bool is_tv = false; - - DRM_DEBUG("\n"); -+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { -+ if (encoder->crtc == crtc) { -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { -+ is_tv = true; -+ DRM_INFO("crtc %d is connected to a TV\n", radeon_crtc->crtc_id); -+ break; -+ } -+ } -+ } - - switch (crtc->fb->bits_per_pixel) { - case 15: /* 555 */ -@@ -642,6 +655,11 @@ static bool radeon_set_crtc_timing(struct drm_crtc *crtc, struct drm_display_mod - WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); - } - -+ if (is_tv) -+ radeon_legacy_tv_adjust_crtc_reg(encoder, &crtc_h_total_disp, -+ &crtc_h_sync_strt_wid, &crtc_v_total_disp, -+ &crtc_v_sync_strt_wid); -+ - WREG32(RADEON_CRTC_H_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_h_total_disp); - WREG32(RADEON_CRTC_H_SYNC_STRT_WID + radeon_crtc->crtc_offset, crtc_h_sync_strt_wid); - WREG32(RADEON_CRTC_V_TOTAL_DISP + radeon_crtc->crtc_offset, crtc_v_total_disp); -@@ -668,7 +686,7 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - uint32_t pll_ref_div = 0; - uint32_t pll_fb_post_div = 0; - uint32_t htotal_cntl = 0; -- -+ bool is_tv = false; - struct radeon_pll *pll; - - struct { -@@ -703,6 +721,13 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ -+ if (radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT) { -+ is_tv = true; -+ break; -+ } -+ - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) - pll_flags |= RADEON_PLL_NO_ODD_POST_DIV; - if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) { -@@ -766,6 +791,12 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | - RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); - -+ if (is_tv) { -+ radeon_legacy_tv_adjust_pll2(encoder, &htotal_cntl, -+ &pll_ref_div, &pll_fb_post_div, -+ &pixclks_cntl); -+ } -+ - WREG32_PLL_P(RADEON_PIXCLKS_CNTL, - RADEON_PIX2CLK_SRC_SEL_CPUCLK, - ~(RADEON_PIX2CLK_SRC_SEL_MASK)); -@@ -820,6 +851,15 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - } else { -+ uint32_t pixclks_cntl; -+ -+ -+ if (is_tv) { -+ pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); -+ radeon_legacy_tv_adjust_pll1(encoder, &htotal_cntl, &pll_ref_div, -+ &pll_fb_post_div, &pixclks_cntl); -+ } -+ - if (rdev->flags & RADEON_IS_MOBILITY) { - /* A temporal workaround for the occational blanking on certain laptop panels. - This appears to related to the PLL divider registers (fail to lock?). -@@ -914,6 +954,8 @@ static void radeon_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) - RADEON_VCLK_SRC_SEL_PPLLCLK, - ~(RADEON_VCLK_SRC_SEL_MASK)); - -+ if (is_tv) -+ WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - } - } - -diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c -index 9322675..0aaafcd 100644 ---- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c -+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c -@@ -29,6 +29,15 @@ - #include "radeon.h" - #include "atom.h" - -+static void radeon_legacy_encoder_disable(struct drm_encoder *encoder) -+{ -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct drm_encoder_helper_funcs *encoder_funcs; -+ -+ encoder_funcs = encoder->helper_private; -+ encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder->active_device = 0; -+} - - static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) - { -@@ -98,6 +107,8 @@ static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); -+ -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) -@@ -195,6 +206,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { - .prepare = radeon_legacy_lvds_prepare, - .mode_set = radeon_legacy_lvds_mode_set, - .commit = radeon_legacy_lvds_commit, -+ .disable = radeon_legacy_encoder_disable, - }; - - -@@ -260,6 +272,7 @@ static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) -@@ -402,6 +415,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_fu - .mode_set = radeon_legacy_primary_dac_mode_set, - .commit = radeon_legacy_primary_dac_commit, - .detect = radeon_legacy_primary_dac_detect, -+ .disable = radeon_legacy_encoder_disable, - }; - - -@@ -454,6 +468,7 @@ static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) -@@ -566,6 +581,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_int_helper_funcs - .prepare = radeon_legacy_tmds_int_prepare, - .mode_set = radeon_legacy_tmds_int_mode_set, - .commit = radeon_legacy_tmds_int_commit, -+ .disable = radeon_legacy_encoder_disable, - }; - - -@@ -620,6 +636,7 @@ static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) -@@ -706,6 +723,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tmds_ext_helper_funcs - .prepare = radeon_legacy_tmds_ext_prepare, - .mode_set = radeon_legacy_tmds_ext_mode_set, - .commit = radeon_legacy_tmds_ext_commit, -+ .disable = radeon_legacy_encoder_disable, - }; - - -@@ -727,17 +745,21 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) - { - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); - uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; -- /* uint32_t tv_master_cntl = 0; */ -- -+ uint32_t tv_master_cntl = 0; -+ bool is_tv; - DRM_DEBUG("\n"); - -+ is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; -+ - if (rdev->family == CHIP_R200) - fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - else { -- crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); -- /* FIXME TV */ -- /* tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); */ -+ if (is_tv) -+ tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); -+ else -+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - } - -@@ -746,20 +768,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) - if (rdev->family == CHIP_R200) { - fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); - } else { -- crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; -- /* tv_master_cntl |= RADEON_TV_ON; */ -+ if (is_tv) -+ tv_master_cntl |= RADEON_TV_ON; -+ else -+ crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON; -+ - if (rdev->family == CHIP_R420 || -- rdev->family == CHIP_R423 || -- rdev->family == CHIP_RV410) -+ rdev->family == CHIP_R423 || -+ rdev->family == CHIP_RV410) - tv_dac_cntl &= ~(R420_TV_DAC_RDACPD | -- R420_TV_DAC_GDACPD | -- R420_TV_DAC_BDACPD | -- RADEON_TV_DAC_BGSLEEP); -+ R420_TV_DAC_GDACPD | -+ R420_TV_DAC_BDACPD | -+ RADEON_TV_DAC_BGSLEEP); - else - tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD | -- RADEON_TV_DAC_GDACPD | -- RADEON_TV_DAC_BDACPD | -- RADEON_TV_DAC_BGSLEEP); -+ RADEON_TV_DAC_GDACPD | -+ RADEON_TV_DAC_BDACPD | -+ RADEON_TV_DAC_BGSLEEP); - } - break; - case DRM_MODE_DPMS_STANDBY: -@@ -768,8 +793,11 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) - if (rdev->family == CHIP_R200) - fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); - else { -- crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; -- /* tv_master_cntl &= ~RADEON_TV_ON; */ -+ if (is_tv) -+ tv_master_cntl &= ~RADEON_TV_ON; -+ else -+ crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; -+ - if (rdev->family == CHIP_R420 || - rdev->family == CHIP_R423 || - rdev->family == CHIP_RV410) -@@ -789,8 +817,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) - if (rdev->family == CHIP_R200) { - WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); - } else { -- WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); -- /* WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); */ -+ if (is_tv) -+ WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); -+ else -+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); - WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); - } - -@@ -809,6 +839,7 @@ static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) - else - radeon_combios_output_lock(encoder, true); - radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); -+ radeon_encoder_set_active_device(encoder); - } - - static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) -@@ -831,11 +862,15 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, - struct radeon_device *rdev = dev->dev_private; - struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); - struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - uint32_t tv_dac_cntl, gpiopad_a = 0, dac2_cntl, disp_output_cntl = 0; -- uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0; -+ uint32_t disp_hw_debug = 0, fp2_gen_cntl = 0, disp_tv_out_cntl = 0; -+ bool is_tv = false; - - DRM_DEBUG("\n"); - -+ is_tv = radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT ? true : false; -+ - if (rdev->family != CHIP_R200) { - tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); - if (rdev->family == CHIP_R420 || -@@ -858,7 +893,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, - } - - /* FIXME TV */ -- if (radeon_encoder->enc_priv) { -+ if (tv_dac) { - struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | - RADEON_TV_DAC_NHOLD | -@@ -875,44 +910,93 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, - if (ASIC_IS_R300(rdev)) { - gpiopad_a = RREG32(RADEON_GPIOPAD_A) | 1; - disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); -- } else if (rdev->family == CHIP_R200) -- fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); -+ } -+ -+ if (rdev->family == CHIP_R200 || ASIC_IS_R300(rdev)) -+ disp_tv_out_cntl = RREG32(RADEON_DISP_TV_OUT_CNTL); - else - disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); - -- dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; -+ if (rdev->family == CHIP_R200) -+ fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); - -- if (radeon_crtc->crtc_id == 0) { -- if (ASIC_IS_R300(rdev)) { -- disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -- disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; -- } else if (rdev->family == CHIP_R200) { -- fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | -- RADEON_FP2_DVO_RATE_SEL_SDR); -- } else -- disp_hw_debug |= RADEON_CRT2_DISP1_SEL; -+ if (is_tv) { -+ uint32_t dac_cntl; -+ -+ dac_cntl = RREG32(RADEON_DAC_CNTL); -+ dac_cntl &= ~RADEON_DAC_TVO_EN; -+ WREG32(RADEON_DAC_CNTL, dac_cntl); -+ -+ if (ASIC_IS_R300(rdev)) -+ gpiopad_a = RREG32(RADEON_GPIOPAD_A) & ~1; -+ -+ dac2_cntl = RREG32(RADEON_DAC_CNTL2) & ~RADEON_DAC2_DAC2_CLK_SEL; -+ if (radeon_crtc->crtc_id == 0) { -+ if (ASIC_IS_R300(rdev)) { -+ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -+ disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC | -+ RADEON_DISP_TV_SOURCE_CRTC); -+ } -+ if (rdev->family >= CHIP_R200) { -+ disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2; -+ } else { -+ disp_hw_debug |= RADEON_CRT2_DISP1_SEL; -+ } -+ } else { -+ if (ASIC_IS_R300(rdev)) { -+ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -+ disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC; -+ } -+ if (rdev->family >= CHIP_R200) { -+ disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2; -+ } else { -+ disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; -+ } -+ } -+ WREG32(RADEON_DAC_CNTL2, dac2_cntl); - } else { -- if (ASIC_IS_R300(rdev)) { -- disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -- disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; -- } else if (rdev->family == CHIP_R200) { -- fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | -- RADEON_FP2_DVO_RATE_SEL_SDR); -- fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; -- } else -- disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; -- } - -- WREG32(RADEON_DAC_CNTL2, dac2_cntl); -+ dac2_cntl = RREG32(RADEON_DAC_CNTL2) | RADEON_DAC2_DAC2_CLK_SEL; -+ -+ if (radeon_crtc->crtc_id == 0) { -+ if (ASIC_IS_R300(rdev)) { -+ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -+ disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC; -+ } else if (rdev->family == CHIP_R200) { -+ fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | -+ RADEON_FP2_DVO_RATE_SEL_SDR); -+ } else -+ disp_hw_debug |= RADEON_CRT2_DISP1_SEL; -+ } else { -+ if (ASIC_IS_R300(rdev)) { -+ disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK; -+ disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2; -+ } else if (rdev->family == CHIP_R200) { -+ fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | -+ RADEON_FP2_DVO_RATE_SEL_SDR); -+ fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2; -+ } else -+ disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL; -+ } -+ WREG32(RADEON_DAC_CNTL2, dac2_cntl); -+ } - - if (ASIC_IS_R300(rdev)) { - WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); -- WREG32(RADEON_DISP_TV_OUT_CNTL, disp_output_cntl); -- } else if (rdev->family == CHIP_R200) -- WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); -+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); -+ } -+ -+ if (rdev->family >= CHIP_R200) -+ WREG32(RADEON_DISP_TV_OUT_CNTL, disp_tv_out_cntl); - else - WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); - -+ if (rdev->family == CHIP_R200) -+ WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); -+ -+ if (is_tv) -+ radeon_legacy_tv_mode_set(encoder, mode, adjusted_mode); -+ - if (rdev->is_atom_bios) - radeon_atombios_encoder_crtc_scratch_regs(encoder, radeon_crtc->crtc_id); - else -@@ -920,6 +1004,141 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, - - } - -+static bool r300_legacy_tv_detect(struct drm_encoder *encoder, -+ struct drm_connector *connector) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; -+ uint32_t disp_output_cntl, gpiopad_a, tmp; -+ bool found = false; -+ -+ /* save regs needed */ -+ gpiopad_a = RREG32(RADEON_GPIOPAD_A); -+ dac_cntl2 = RREG32(RADEON_DAC_CNTL2); -+ crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); -+ dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); -+ tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); -+ disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); -+ -+ WREG32_P(RADEON_GPIOPAD_A, 0, ~1); -+ -+ WREG32(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL); -+ -+ WREG32(RADEON_CRTC2_GEN_CNTL, -+ RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT); -+ -+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; -+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; -+ WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); -+ -+ WREG32(RADEON_DAC_EXT_CNTL, -+ RADEON_DAC2_FORCE_BLANK_OFF_EN | -+ RADEON_DAC2_FORCE_DATA_EN | -+ RADEON_DAC_FORCE_DATA_SEL_RGB | -+ (0xec << RADEON_DAC_FORCE_DATA_SHIFT)); -+ -+ WREG32(RADEON_TV_DAC_CNTL, -+ RADEON_TV_DAC_STD_NTSC | -+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) | -+ (6 << RADEON_TV_DAC_DACADJ_SHIFT)); -+ -+ RREG32(RADEON_TV_DAC_CNTL); -+ mdelay(4); -+ -+ WREG32(RADEON_TV_DAC_CNTL, -+ RADEON_TV_DAC_NBLANK | -+ RADEON_TV_DAC_NHOLD | -+ RADEON_TV_MONITOR_DETECT_EN | -+ RADEON_TV_DAC_STD_NTSC | -+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) | -+ (6 << RADEON_TV_DAC_DACADJ_SHIFT)); -+ -+ RREG32(RADEON_TV_DAC_CNTL); -+ mdelay(6); -+ -+ tmp = RREG32(RADEON_TV_DAC_CNTL); -+ if ((tmp & RADEON_TV_DAC_GDACDET) != 0) { -+ found = true; -+ DRM_DEBUG("S-video TV connection detected\n"); -+ } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { -+ found = true; -+ DRM_DEBUG("Composite TV connection detected\n"); -+ } -+ -+ WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); -+ WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); -+ WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); -+ WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); -+ WREG32(RADEON_DAC_CNTL2, dac_cntl2); -+ WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); -+ return found; -+} -+ -+static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, -+ struct drm_connector *connector) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t tv_dac_cntl, dac_cntl2; -+ uint32_t config_cntl, tv_pre_dac_mux_cntl, tv_master_cntl, tmp; -+ bool found = false; -+ -+ if (ASIC_IS_R300(rdev)) -+ return r300_legacy_tv_detect(encoder, connector); -+ -+ dac_cntl2 = RREG32(RADEON_DAC_CNTL2); -+ tv_master_cntl = RREG32(RADEON_TV_MASTER_CNTL); -+ tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); -+ config_cntl = RREG32(RADEON_CONFIG_CNTL); -+ tv_pre_dac_mux_cntl = RREG32(RADEON_TV_PRE_DAC_MUX_CNTL); -+ -+ tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL; -+ WREG32(RADEON_DAC_CNTL2, tmp); -+ -+ tmp = tv_master_cntl | RADEON_TV_ON; -+ tmp &= ~(RADEON_TV_ASYNC_RST | -+ RADEON_RESTART_PHASE_FIX | -+ RADEON_CRT_FIFO_CE_EN | -+ RADEON_TV_FIFO_CE_EN | -+ RADEON_RE_SYNC_NOW_SEL_MASK); -+ tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST; -+ WREG32(RADEON_TV_MASTER_CNTL, tmp); -+ -+ tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | -+ RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC | -+ (8 << RADEON_TV_DAC_BGADJ_SHIFT); -+ -+ if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK) -+ tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT); -+ else -+ tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT); -+ WREG32(RADEON_TV_DAC_CNTL, tmp); -+ -+ tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN | -+ RADEON_RED_MX_FORCE_DAC_DATA | -+ RADEON_GRN_MX_FORCE_DAC_DATA | -+ RADEON_BLU_MX_FORCE_DAC_DATA | -+ (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT); -+ WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tmp); -+ -+ mdelay(3); -+ tmp = RREG32(RADEON_TV_DAC_CNTL); -+ if (tmp & RADEON_TV_DAC_GDACDET) { -+ found = true; -+ DRM_DEBUG("S-video TV connection detected\n"); -+ } else if ((tmp & RADEON_TV_DAC_BDACDET) != 0) { -+ found = true; -+ DRM_DEBUG("Composite TV connection detected\n"); -+ } -+ -+ WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl); -+ WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); -+ WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); -+ WREG32(RADEON_DAC_CNTL2, dac_cntl2); -+ return found; -+} -+ - static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, - struct drm_connector *connector) - { -@@ -928,9 +1147,29 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder - uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; - uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; - enum drm_connector_status found = connector_status_disconnected; -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; - bool color = true; - -- /* FIXME tv */ -+ if (connector->connector_type == DRM_MODE_CONNECTOR_SVIDEO || -+ connector->connector_type == DRM_MODE_CONNECTOR_Composite || -+ connector->connector_type == DRM_MODE_CONNECTOR_9PinDIN) { -+ bool tv_detect; -+ -+ if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_TV_SUPPORT)) -+ return connector_status_disconnected; -+ -+ tv_detect = radeon_legacy_tv_detect(encoder, connector); -+ if (tv_detect && tv_dac) -+ found = connector_status_connected; -+ return found; -+ } -+ -+ /* don't probe if the encoder is being used for something else not CRT related */ -+ if (radeon_encoder->active_device && !(radeon_encoder->active_device & ATOM_DEVICE_CRT_SUPPORT)) { -+ DRM_INFO("not detecting due to %08x\n", radeon_encoder->active_device); -+ return connector_status_disconnected; -+ } - - /* save the regs we need */ - pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); -@@ -1013,8 +1252,7 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder - } - WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); - -- /* return found; */ -- return connector_status_disconnected; -+ return found; - - } - -@@ -1025,6 +1263,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_tv_dac_helper_funcs = - .mode_set = radeon_legacy_tv_dac_mode_set, - .commit = radeon_legacy_tv_dac_commit, - .detect = radeon_legacy_tv_dac_detect, -+ .disable = radeon_legacy_encoder_disable, - }; - - -diff --git a/drivers/gpu/drm/radeon/radeon_legacy_tv.c b/drivers/gpu/drm/radeon/radeon_legacy_tv.c -new file mode 100644 -index 0000000..3a12bb0 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/radeon_legacy_tv.c -@@ -0,0 +1,904 @@ -+#include "drmP.h" -+#include "drm_crtc_helper.h" -+#include "radeon.h" -+ -+/* -+ * Integrated TV out support based on the GATOS code by -+ * Federico Ulivi -+ */ -+ -+ -+/* -+ * Limits of h/v positions (hPos & vPos) -+ */ -+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */ -+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */ -+ -+/* -+ * Unit for hPos (in TV clock periods) -+ */ -+#define H_POS_UNIT 10 -+ -+/* -+ * Indexes in h. code timing table for horizontal line position adjustment -+ */ -+#define H_TABLE_POS1 6 -+#define H_TABLE_POS2 8 -+ -+/* -+ * Limits of hor. size (hSize) -+ */ -+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */ -+ -+/* tv standard constants */ -+#define NTSC_TV_CLOCK_T 233 -+#define NTSC_TV_VFTOTAL 1 -+#define NTSC_TV_LINES_PER_FRAME 525 -+#define NTSC_TV_ZERO_H_SIZE 479166 -+#define NTSC_TV_H_SIZE_UNIT 9478 -+ -+#define PAL_TV_CLOCK_T 188 -+#define PAL_TV_VFTOTAL 3 -+#define PAL_TV_LINES_PER_FRAME 625 -+#define PAL_TV_ZERO_H_SIZE 473200 -+#define PAL_TV_H_SIZE_UNIT 9360 -+ -+/* tv pll setting for 27 mhz ref clk */ -+#define NTSC_TV_PLL_M_27 22 -+#define NTSC_TV_PLL_N_27 175 -+#define NTSC_TV_PLL_P_27 5 -+ -+#define PAL_TV_PLL_M_27 113 -+#define PAL_TV_PLL_N_27 668 -+#define PAL_TV_PLL_P_27 3 -+ -+/* tv pll setting for 14 mhz ref clk */ -+#define NTSC_TV_PLL_M_14 33 -+#define NTSC_TV_PLL_N_14 693 -+#define NTSC_TV_PLL_P_14 7 -+ -+#define VERT_LEAD_IN_LINES 2 -+#define FRAC_BITS 0xe -+#define FRAC_MASK 0x3fff -+ -+struct radeon_tv_mode_constants { -+ uint16_t hor_resolution; -+ uint16_t ver_resolution; -+ enum radeon_tv_std standard; -+ uint16_t hor_total; -+ uint16_t ver_total; -+ uint16_t hor_start; -+ uint16_t hor_syncstart; -+ uint16_t ver_syncstart; -+ unsigned def_restart; -+ uint16_t crtcPLL_N; -+ uint8_t crtcPLL_M; -+ uint8_t crtcPLL_post_div; -+ unsigned pix_to_tv; -+}; -+ -+static const uint16_t hor_timing_NTSC[] = { -+ 0x0007, -+ 0x003f, -+ 0x0263, -+ 0x0a24, -+ 0x2a6b, -+ 0x0a36, -+ 0x126d, /* H_TABLE_POS1 */ -+ 0x1bfe, -+ 0x1a8f, /* H_TABLE_POS2 */ -+ 0x1ec7, -+ 0x3863, -+ 0x1bfe, -+ 0x1bfe, -+ 0x1a2a, -+ 0x1e95, -+ 0x0e31, -+ 0x201b, -+ 0 -+}; -+ -+static const uint16_t vert_timing_NTSC[] = { -+ 0x2001, -+ 0x200d, -+ 0x1006, -+ 0x0c06, -+ 0x1006, -+ 0x1818, -+ 0x21e3, -+ 0x1006, -+ 0x0c06, -+ 0x1006, -+ 0x1817, -+ 0x21d4, -+ 0x0002, -+ 0 -+}; -+ -+static const uint16_t hor_timing_PAL[] = { -+ 0x0007, -+ 0x0058, -+ 0x027c, -+ 0x0a31, -+ 0x2a77, -+ 0x0a95, -+ 0x124f, /* H_TABLE_POS1 */ -+ 0x1bfe, -+ 0x1b22, /* H_TABLE_POS2 */ -+ 0x1ef9, -+ 0x387c, -+ 0x1bfe, -+ 0x1bfe, -+ 0x1b31, -+ 0x1eb5, -+ 0x0e43, -+ 0x201b, -+ 0 -+}; -+ -+static const uint16_t vert_timing_PAL[] = { -+ 0x2001, -+ 0x200c, -+ 0x1005, -+ 0x0c05, -+ 0x1005, -+ 0x1401, -+ 0x1821, -+ 0x2240, -+ 0x1005, -+ 0x0c05, -+ 0x1005, -+ 0x1401, -+ 0x1822, -+ 0x2230, -+ 0x0002, -+ 0 -+}; -+ -+/********************************************************************** -+ * -+ * availableModes -+ * -+ * Table of all allowed modes for tv output -+ * -+ **********************************************************************/ -+static const struct radeon_tv_mode_constants available_tv_modes[] = { -+ { /* NTSC timing for 27 Mhz ref clk */ -+ 800, /* horResolution */ -+ 600, /* verResolution */ -+ TV_STD_NTSC, /* standard */ -+ 990, /* horTotal */ -+ 740, /* verTotal */ -+ 813, /* horStart */ -+ 824, /* horSyncStart */ -+ 632, /* verSyncStart */ -+ 625592, /* defRestart */ -+ 592, /* crtcPLL_N */ -+ 91, /* crtcPLL_M */ -+ 4, /* crtcPLL_postDiv */ -+ 1022, /* pixToTV */ -+ }, -+ { /* PAL timing for 27 Mhz ref clk */ -+ 800, /* horResolution */ -+ 600, /* verResolution */ -+ TV_STD_PAL, /* standard */ -+ 1144, /* horTotal */ -+ 706, /* verTotal */ -+ 812, /* horStart */ -+ 824, /* horSyncStart */ -+ 669, /* verSyncStart */ -+ 696700, /* defRestart */ -+ 1382, /* crtcPLL_N */ -+ 231, /* crtcPLL_M */ -+ 4, /* crtcPLL_postDiv */ -+ 759, /* pixToTV */ -+ }, -+ { /* NTSC timing for 14 Mhz ref clk */ -+ 800, /* horResolution */ -+ 600, /* verResolution */ -+ TV_STD_NTSC, /* standard */ -+ 1018, /* horTotal */ -+ 727, /* verTotal */ -+ 813, /* horStart */ -+ 840, /* horSyncStart */ -+ 633, /* verSyncStart */ -+ 630627, /* defRestart */ -+ 347, /* crtcPLL_N */ -+ 14, /* crtcPLL_M */ -+ 8, /* crtcPLL_postDiv */ -+ 1022, /* pixToTV */ -+ }, -+}; -+ -+#define N_AVAILABLE_MODES ARRAY_SIZE(available_tv_modes) -+ -+static const struct radeon_tv_mode_constants *radeon_legacy_tv_get_std_mode(struct radeon_encoder *radeon_encoder, -+ uint16_t *pll_ref_freq) -+{ -+ struct drm_device *dev = radeon_encoder->base.dev; -+ struct radeon_device *rdev = dev->dev_private; -+ struct radeon_crtc *radeon_crtc; -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -+ const struct radeon_tv_mode_constants *const_ptr; -+ struct radeon_pll *pll; -+ -+ radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); -+ if (radeon_crtc->crtc_id == 1) -+ pll = &rdev->clock.p2pll; -+ else -+ pll = &rdev->clock.p1pll; -+ -+ if (pll_ref_freq) -+ *pll_ref_freq = pll->reference_freq; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M) { -+ if (pll->reference_freq == 2700) -+ const_ptr = &available_tv_modes[0]; -+ else -+ const_ptr = &available_tv_modes[2]; -+ } else { -+ if (pll->reference_freq == 2700) -+ const_ptr = &available_tv_modes[1]; -+ else -+ const_ptr = &available_tv_modes[1]; /* FIX ME */ -+ } -+ return const_ptr; -+} -+ -+static long YCOEF_value[5] = { 2, 2, 0, 4, 0 }; -+static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 }; -+static long SLOPE_value[5] = { 1, 2, 2, 4, 8 }; -+static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 }; -+ -+static void radeon_wait_pll_lock(struct drm_encoder *encoder, unsigned n_tests, -+ unsigned n_wait_loops, unsigned cnt_threshold) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t save_pll_test; -+ unsigned int i, j; -+ -+ WREG32(RADEON_TEST_DEBUG_MUX, (RREG32(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100); -+ save_pll_test = RREG32_PLL(RADEON_PLL_TEST_CNTL); -+ WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test & ~RADEON_PLL_MASK_READ_B); -+ -+ WREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL); -+ for (i = 0; i < n_tests; i++) { -+ WREG8(RADEON_CLOCK_CNTL_DATA + 3, 0); -+ for (j = 0; j < n_wait_loops; j++) -+ if (RREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cnt_threshold) -+ break; -+ } -+ WREG32_PLL(RADEON_PLL_TEST_CNTL, save_pll_test); -+ WREG32(RADEON_TEST_DEBUG_MUX, RREG32(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff); -+} -+ -+ -+static void radeon_legacy_tv_write_fifo(struct radeon_encoder *radeon_encoder, -+ uint16_t addr, uint32_t value) -+{ -+ struct drm_device *dev = radeon_encoder->base.dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t tmp; -+ int i = 0; -+ -+ WREG32(RADEON_TV_HOST_WRITE_DATA, value); -+ -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT); -+ -+ do { -+ tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); -+ if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0) -+ break; -+ i++; -+ } while (i < 10000); -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); -+} -+ -+#if 0 /* included for completeness */ -+static uint32_t radeon_legacy_tv_read_fifo(struct radeon_encoder *radeon_encoder, uint16_t addr) -+{ -+ struct drm_device *dev = radeon_encoder->base.dev; -+ struct radeon_device *rdev = dev->dev_private; -+ uint32_t tmp; -+ int i = 0; -+ -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr); -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD); -+ -+ do { -+ tmp = RREG32(RADEON_TV_HOST_RD_WT_CNTL); -+ if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0) -+ break; -+ i++; -+ } while (i < 10000); -+ WREG32(RADEON_TV_HOST_RD_WT_CNTL, 0); -+ return RREG32(RADEON_TV_HOST_READ_DATA); -+} -+#endif -+ -+static uint16_t radeon_get_htiming_tables_addr(uint32_t tv_uv_adr) -+{ -+ uint16_t h_table; -+ -+ switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) { -+ case 0: -+ h_table = RADEON_TV_MAX_FIFO_ADDR_INTERNAL; -+ break; -+ case 1: -+ h_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2; -+ break; -+ case 2: -+ h_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2; -+ break; -+ default: -+ h_table = 0; -+ break; -+ } -+ return h_table; -+} -+ -+static uint16_t radeon_get_vtiming_tables_addr(uint32_t tv_uv_adr) -+{ -+ uint16_t v_table; -+ -+ switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) { -+ case 0: -+ v_table = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1; -+ break; -+ case 1: -+ v_table = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1; -+ break; -+ case 2: -+ v_table = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1; -+ break; -+ default: -+ v_table = 0; -+ break; -+ } -+ return v_table; -+} -+ -+static void radeon_restore_tv_timing_tables(struct radeon_encoder *radeon_encoder) -+{ -+ struct drm_device *dev = radeon_encoder->base.dev; -+ struct radeon_device *rdev = dev->dev_private; -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -+ uint16_t h_table, v_table; -+ uint32_t tmp; -+ int i; -+ -+ WREG32(RADEON_TV_UV_ADR, tv_dac->tv.tv_uv_adr); -+ h_table = radeon_get_htiming_tables_addr(tv_dac->tv.tv_uv_adr); -+ v_table = radeon_get_vtiming_tables_addr(tv_dac->tv.tv_uv_adr); -+ -+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, h_table--) { -+ tmp = ((uint32_t)tv_dac->tv.h_code_timing[i] << 14) | ((uint32_t)tv_dac->tv.h_code_timing[i+1]); -+ radeon_legacy_tv_write_fifo(radeon_encoder, h_table, tmp); -+ if (tv_dac->tv.h_code_timing[i] == 0 || tv_dac->tv.h_code_timing[i + 1] == 0) -+ break; -+ } -+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, v_table++) { -+ tmp = ((uint32_t)tv_dac->tv.v_code_timing[i+1] << 14) | ((uint32_t)tv_dac->tv.v_code_timing[i]); -+ radeon_legacy_tv_write_fifo(radeon_encoder, v_table, tmp); -+ if (tv_dac->tv.v_code_timing[i] == 0 || tv_dac->tv.v_code_timing[i + 1] == 0) -+ break; -+ } -+} -+ -+static void radeon_legacy_write_tv_restarts(struct radeon_encoder *radeon_encoder) -+{ -+ struct drm_device *dev = radeon_encoder->base.dev; -+ struct radeon_device *rdev = dev->dev_private; -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -+ WREG32(RADEON_TV_FRESTART, tv_dac->tv.frestart); -+ WREG32(RADEON_TV_HRESTART, tv_dac->tv.hrestart); -+ WREG32(RADEON_TV_VRESTART, tv_dac->tv.vrestart); -+} -+ -+static bool radeon_legacy_tv_init_restarts(struct drm_encoder *encoder) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -+ struct radeon_crtc *radeon_crtc; -+ int restart; -+ unsigned int h_total, v_total, f_total; -+ int v_offset, h_offset; -+ u16 p1, p2, h_inc; -+ bool h_changed; -+ const struct radeon_tv_mode_constants *const_ptr; -+ struct radeon_pll *pll; -+ -+ radeon_crtc = to_radeon_crtc(radeon_encoder->base.crtc); -+ if (radeon_crtc->crtc_id == 1) -+ pll = &rdev->clock.p2pll; -+ else -+ pll = &rdev->clock.p1pll; -+ -+ const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); -+ if (!const_ptr) -+ return false; -+ -+ h_total = const_ptr->hor_total; -+ v_total = const_ptr->ver_total; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) -+ f_total = NTSC_TV_VFTOTAL + 1; -+ else -+ f_total = PAL_TV_VFTOTAL + 1; -+ -+ /* adjust positions 1&2 in hor. cod timing table */ -+ h_offset = tv_dac->h_pos * H_POS_UNIT; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M) { -+ h_offset -= 50; -+ p1 = hor_timing_NTSC[H_TABLE_POS1]; -+ p2 = hor_timing_NTSC[H_TABLE_POS2]; -+ } else { -+ p1 = hor_timing_PAL[H_TABLE_POS1]; -+ p2 = hor_timing_PAL[H_TABLE_POS2]; -+ } -+ -+ p1 = (u16)((int)p1 + h_offset); -+ p2 = (u16)((int)p2 - h_offset); -+ -+ h_changed = (p1 != tv_dac->tv.h_code_timing[H_TABLE_POS1] || -+ p2 != tv_dac->tv.h_code_timing[H_TABLE_POS2]); -+ -+ tv_dac->tv.h_code_timing[H_TABLE_POS1] = p1; -+ tv_dac->tv.h_code_timing[H_TABLE_POS2] = p2; -+ -+ /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */ -+ h_offset = (h_offset * (int)(const_ptr->pix_to_tv)) / 1000; -+ -+ /* adjust restart */ -+ restart = const_ptr->def_restart; -+ -+ /* -+ * convert v_pos TV lines to n. of CRTC pixels -+ */ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) -+ v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(NTSC_TV_LINES_PER_FRAME); -+ else -+ v_offset = ((int)(v_total * h_total) * 2 * tv_dac->v_pos) / (int)(PAL_TV_LINES_PER_FRAME); -+ -+ restart -= v_offset + h_offset; -+ -+ DRM_DEBUG("compute_restarts: def = %u h = %d v = %d, p1 = %04x, p2 = %04x, restart = %d\n", -+ const_ptr->def_restart, tv_dac->h_pos, tv_dac->v_pos, p1, p2, restart); -+ -+ tv_dac->tv.hrestart = restart % h_total; -+ restart /= h_total; -+ tv_dac->tv.vrestart = restart % v_total; -+ restart /= v_total; -+ tv_dac->tv.frestart = restart % f_total; -+ -+ DRM_DEBUG("compute_restart: F/H/V=%u,%u,%u\n", -+ (unsigned)tv_dac->tv.frestart, -+ (unsigned)tv_dac->tv.vrestart, -+ (unsigned)tv_dac->tv.hrestart); -+ -+ /* compute h_inc from hsize */ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M) -+ h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * NTSC_TV_CLOCK_T) / -+ (tv_dac->h_size * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE))); -+ else -+ h_inc = (u16)((int)(const_ptr->hor_resolution * 4096 * PAL_TV_CLOCK_T) / -+ (tv_dac->h_size * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE))); -+ -+ tv_dac->tv.timing_cntl = (tv_dac->tv.timing_cntl & ~RADEON_H_INC_MASK) | -+ ((u32)h_inc << RADEON_H_INC_SHIFT); -+ -+ DRM_DEBUG("compute_restart: h_size = %d h_inc = %d\n", tv_dac->h_size, h_inc); -+ -+ return h_changed; -+} -+ -+void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode) -+{ -+ struct drm_device *dev = encoder->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; -+ const struct radeon_tv_mode_constants *const_ptr; -+ struct radeon_crtc *radeon_crtc; -+ int i; -+ uint16_t pll_ref_freq; -+ uint32_t vert_space, flicker_removal, tmp; -+ uint32_t tv_master_cntl, tv_rgb_cntl, tv_dac_cntl; -+ uint32_t tv_modulator_cntl1, tv_modulator_cntl2; -+ uint32_t tv_vscaler_cntl1, tv_vscaler_cntl2; -+ uint32_t tv_pll_cntl, tv_pll_cntl1, tv_ftotal; -+ uint32_t tv_y_fall_cntl, tv_y_rise_cntl, tv_y_saw_tooth_cntl; -+ uint32_t m, n, p; -+ const uint16_t *hor_timing; -+ const uint16_t *vert_timing; -+ -+ const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, &pll_ref_freq); -+ if (!const_ptr) -+ return; -+ -+ radeon_crtc = to_radeon_crtc(encoder->crtc); -+ -+ tv_master_cntl = (RADEON_VIN_ASYNC_RST | -+ RADEON_CRT_FIFO_CE_EN | -+ RADEON_TV_FIFO_CE_EN | -+ RADEON_TV_ON); -+ -+ if (!ASIC_IS_R300(rdev)) -+ tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J) -+ tv_master_cntl |= RADEON_RESTART_PHASE_FIX; -+ -+ tv_modulator_cntl1 = (RADEON_SLEW_RATE_LIMIT | -+ RADEON_SYNC_TIP_LEVEL | -+ RADEON_YFLT_EN | -+ RADEON_UVFLT_EN | -+ (6 << RADEON_CY_FILT_BLEND_SHIFT)); -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J) { -+ tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT) | -+ (0x3b << RADEON_BLANK_LEVEL_SHIFT); -+ tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) | -+ ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); -+ } else if (tv_dac->tv_std == TV_STD_SCART_PAL) { -+ tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN; -+ tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) | -+ ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); -+ } else { -+ tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN | -+ (0x3b << RADEON_SET_UP_LEVEL_SHIFT) | -+ (0x3b << RADEON_BLANK_LEVEL_SHIFT); -+ tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) | -+ ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT); -+ } -+ -+ -+ tv_rgb_cntl = (RADEON_RGB_DITHER_EN -+ | RADEON_TVOUT_SCALE_EN -+ | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT) -+ | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT) -+ | RADEON_RGB_ATTEN_SEL(0x3) -+ | RADEON_RGB_ATTEN_VAL(0xc)); -+ -+ if (radeon_crtc->crtc_id == 1) -+ tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2; -+ else { -+ if (radeon_crtc->rmx_type != RMX_OFF) -+ tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX; -+ else -+ tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1; -+ } -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) -+ vert_space = const_ptr->ver_total * 2 * 10000 / NTSC_TV_LINES_PER_FRAME; -+ else -+ vert_space = const_ptr->ver_total * 2 * 10000 / PAL_TV_LINES_PER_FRAME; -+ -+ tmp = RREG32(RADEON_TV_VSCALER_CNTL1); -+ tmp &= 0xe3ff0000; -+ tmp |= (vert_space * (1 << FRAC_BITS) / 10000); -+ tv_vscaler_cntl1 = tmp; -+ -+ if (pll_ref_freq == 2700) -+ tv_vscaler_cntl1 |= RADEON_RESTART_FIELD; -+ -+ if (const_ptr->hor_resolution == 1024) -+ tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT); -+ else -+ tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT); -+ -+ /* scale up for int divide */ -+ tmp = const_ptr->ver_total * 2 * 1000; -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) { -+ tmp /= NTSC_TV_LINES_PER_FRAME; -+ } else { -+ tmp /= PAL_TV_LINES_PER_FRAME; -+ } -+ flicker_removal = (tmp + 500) / 1000; -+ -+ if (flicker_removal < 3) -+ flicker_removal = 3; -+ for (i = 0; i < 6; ++i) { -+ if (flicker_removal == SLOPE_limit[i]) -+ break; -+ } -+ -+ tv_y_saw_tooth_cntl = (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + -+ 5001) / 10000 / 8 | ((SLOPE_value[i] * -+ (1 << (FRAC_BITS - 1)) / 8) << 16); -+ tv_y_fall_cntl = -+ (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) | -+ RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) / -+ 1024; -+ tv_y_rise_cntl = RADEON_Y_RISE_PING_PONG| -+ (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024; -+ -+ tv_vscaler_cntl2 = RREG32(RADEON_TV_VSCALER_CNTL2) & 0x00fffff0; -+ tv_vscaler_cntl2 |= (0x10 << 24) | -+ RADEON_DITHER_MODE | -+ RADEON_Y_OUTPUT_DITHER_EN | -+ RADEON_UV_OUTPUT_DITHER_EN | -+ RADEON_UV_TO_BUF_DITHER_EN; -+ -+ tmp = (tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK; -+ tmp = ((16384 * 256 * 10) / tmp + 5) / 10; -+ tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000; -+ tv_dac->tv.timing_cntl = tmp; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) -+ tv_dac_cntl = tv_dac->ntsc_tvdac_adj; -+ else -+ tv_dac_cntl = tv_dac->pal_tvdac_adj; -+ -+ tv_dac_cntl |= RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J) -+ tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC; -+ else -+ tv_dac_cntl |= RADEON_TV_DAC_STD_PAL; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J) { -+ if (pll_ref_freq == 2700) { -+ m = NTSC_TV_PLL_M_27; -+ n = NTSC_TV_PLL_N_27; -+ p = NTSC_TV_PLL_P_27; -+ } else { -+ m = NTSC_TV_PLL_M_14; -+ n = NTSC_TV_PLL_N_14; -+ p = NTSC_TV_PLL_P_14; -+ } -+ } else { -+ if (pll_ref_freq == 2700) { -+ m = PAL_TV_PLL_M_27; -+ n = PAL_TV_PLL_N_27; -+ p = PAL_TV_PLL_P_27; -+ } else { -+ m = PAL_TV_PLL_M_27; -+ n = PAL_TV_PLL_N_27; -+ p = PAL_TV_PLL_P_27; -+ } -+ } -+ -+ tv_pll_cntl = (m & RADEON_TV_M0LO_MASK) | -+ (((m >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) | -+ ((n & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) | -+ (((n >> 9) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) | -+ ((p & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT); -+ -+ tv_pll_cntl1 = (((4 & RADEON_TVPCP_MASK) << RADEON_TVPCP_SHIFT) | -+ ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) | -+ ((1 & RADEON_TVPDC_MASK) << RADEON_TVPDC_SHIFT) | -+ RADEON_TVCLK_SRC_SEL_TVPLL | -+ RADEON_TVPLL_TEST_DIS); -+ -+ tv_dac->tv.tv_uv_adr = 0xc8; -+ -+ if (tv_dac->tv_std == TV_STD_NTSC || -+ tv_dac->tv_std == TV_STD_NTSC_J || -+ tv_dac->tv_std == TV_STD_PAL_M || -+ tv_dac->tv_std == TV_STD_PAL_60) { -+ tv_ftotal = NTSC_TV_VFTOTAL; -+ hor_timing = hor_timing_NTSC; -+ vert_timing = vert_timing_NTSC; -+ } else { -+ hor_timing = hor_timing_PAL; -+ vert_timing = vert_timing_PAL; -+ tv_ftotal = PAL_TV_VFTOTAL; -+ } -+ -+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) { -+ if ((tv_dac->tv.h_code_timing[i] = hor_timing[i]) == 0) -+ break; -+ } -+ -+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) { -+ if ((tv_dac->tv.v_code_timing[i] = vert_timing[i]) == 0) -+ break; -+ } -+ -+ radeon_legacy_tv_init_restarts(encoder); -+ -+ /* play with DAC_CNTL */ -+ /* play with GPIOPAD_A */ -+ /* DISP_OUTPUT_CNTL */ -+ /* use reference freq */ -+ -+ /* program the TV registers */ -+ WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | -+ RADEON_CRT_ASYNC_RST | RADEON_TV_FIFO_ASYNC_RST)); -+ -+ tmp = RREG32(RADEON_TV_DAC_CNTL); -+ tmp &= ~RADEON_TV_DAC_NBLANK; -+ tmp |= RADEON_TV_DAC_BGSLEEP | -+ RADEON_TV_DAC_RDACPD | -+ RADEON_TV_DAC_GDACPD | -+ RADEON_TV_DAC_BDACPD; -+ WREG32(RADEON_TV_DAC_CNTL, tmp); -+ -+ /* TV PLL */ -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL); -+ WREG32_PLL(RADEON_TV_PLL_CNTL, tv_pll_cntl); -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET); -+ -+ radeon_wait_pll_lock(encoder, 200, 800, 135); -+ -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET); -+ -+ radeon_wait_pll_lock(encoder, 300, 160, 27); -+ radeon_wait_pll_lock(encoder, 200, 800, 135); -+ -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~0xf); -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL); -+ -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK); -+ WREG32_PLL_P(RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP); -+ -+ /* TV HV */ -+ WREG32(RADEON_TV_RGB_CNTL, tv_rgb_cntl); -+ WREG32(RADEON_TV_HTOTAL, const_ptr->hor_total - 1); -+ WREG32(RADEON_TV_HDISP, const_ptr->hor_resolution - 1); -+ WREG32(RADEON_TV_HSTART, const_ptr->hor_start); -+ -+ WREG32(RADEON_TV_VTOTAL, const_ptr->ver_total - 1); -+ WREG32(RADEON_TV_VDISP, const_ptr->ver_resolution - 1); -+ WREG32(RADEON_TV_FTOTAL, tv_ftotal); -+ WREG32(RADEON_TV_VSCALER_CNTL1, tv_vscaler_cntl1); -+ WREG32(RADEON_TV_VSCALER_CNTL2, tv_vscaler_cntl2); -+ -+ WREG32(RADEON_TV_Y_FALL_CNTL, tv_y_fall_cntl); -+ WREG32(RADEON_TV_Y_RISE_CNTL, tv_y_rise_cntl); -+ WREG32(RADEON_TV_Y_SAW_TOOTH_CNTL, tv_y_saw_tooth_cntl); -+ -+ WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST | -+ RADEON_CRT_ASYNC_RST)); -+ -+ /* TV restarts */ -+ radeon_legacy_write_tv_restarts(radeon_encoder); -+ -+ /* tv timings */ -+ radeon_restore_tv_timing_tables(radeon_encoder); -+ -+ WREG32(RADEON_TV_MASTER_CNTL, (tv_master_cntl | RADEON_TV_ASYNC_RST)); -+ -+ /* tv std */ -+ WREG32(RADEON_TV_SYNC_CNTL, (RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE)); -+ WREG32(RADEON_TV_TIMING_CNTL, tv_dac->tv.timing_cntl); -+ WREG32(RADEON_TV_MODULATOR_CNTL1, tv_modulator_cntl1); -+ WREG32(RADEON_TV_MODULATOR_CNTL2, tv_modulator_cntl2); -+ WREG32(RADEON_TV_PRE_DAC_MUX_CNTL, (RADEON_Y_RED_EN | -+ RADEON_C_GRN_EN | -+ RADEON_CMP_BLU_EN | -+ RADEON_DAC_DITHER_EN)); -+ -+ WREG32(RADEON_TV_CRC_CNTL, 0); -+ -+ WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); -+ -+ WREG32(RADEON_TV_GAIN_LIMIT_SETTINGS, ((0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) | -+ (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT))); -+ WREG32(RADEON_TV_LINEAR_GAIN_SETTINGS, ((0x100 << RADEON_UV_GAIN_SHIFT) | -+ (0x100 << RADEON_Y_GAIN_SHIFT))); -+ -+ WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); -+ -+} -+ -+void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, -+ uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, -+ uint32_t *v_total_disp, uint32_t *v_sync_strt_wid) -+{ -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ const struct radeon_tv_mode_constants *const_ptr; -+ uint32_t tmp; -+ -+ const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); -+ if (!const_ptr) -+ return; -+ -+ *h_total_disp = (((const_ptr->hor_resolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) | -+ (((const_ptr->hor_total / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT); -+ -+ tmp = *h_sync_strt_wid; -+ tmp &= ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR); -+ tmp |= (((const_ptr->hor_syncstart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) | -+ (const_ptr->hor_syncstart & 7); -+ *h_sync_strt_wid = tmp; -+ -+ *v_total_disp = ((const_ptr->ver_resolution - 1) << RADEON_CRTC_V_DISP_SHIFT) | -+ ((const_ptr->ver_total - 1) << RADEON_CRTC_V_TOTAL_SHIFT); -+ -+ tmp = *v_sync_strt_wid; -+ tmp &= ~RADEON_CRTC_V_SYNC_STRT; -+ tmp |= ((const_ptr->ver_syncstart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT); -+ *v_sync_strt_wid = tmp; -+} -+ -+static inline int get_post_div(int value) -+{ -+ int post_div; -+ switch (value) { -+ case 1: post_div = 0; break; -+ case 2: post_div = 1; break; -+ case 3: post_div = 4; break; -+ case 4: post_div = 2; break; -+ case 6: post_div = 6; break; -+ case 8: post_div = 3; break; -+ case 12: post_div = 7; break; -+ case 16: -+ default: post_div = 5; break; -+ } -+ return post_div; -+} -+ -+void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, -+ uint32_t *htotal_cntl, uint32_t *ppll_ref_div, -+ uint32_t *ppll_div_3, uint32_t *pixclks_cntl) -+{ -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ const struct radeon_tv_mode_constants *const_ptr; -+ -+ const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); -+ if (!const_ptr) -+ return; -+ -+ *htotal_cntl = (const_ptr->hor_total & 0x7) | RADEON_HTOT_CNTL_VGA_EN; -+ -+ *ppll_ref_div = const_ptr->crtcPLL_M; -+ -+ *ppll_div_3 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); -+ *pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL); -+ *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK; -+} -+ -+void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, -+ uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, -+ uint32_t *p2pll_div_0, uint32_t *pixclks_cntl) -+{ -+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); -+ const struct radeon_tv_mode_constants *const_ptr; -+ -+ const_ptr = radeon_legacy_tv_get_std_mode(radeon_encoder, NULL); -+ if (!const_ptr) -+ return; -+ -+ *htotal2_cntl = (const_ptr->hor_total & 0x7); -+ -+ *p2pll_ref_div = const_ptr->crtcPLL_M; -+ -+ *p2pll_div_0 = (const_ptr->crtcPLL_N & 0x7ff) | (get_post_div(const_ptr->crtcPLL_post_div) << 16); -+ *pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK; -+ *pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK | RADEON_PIXCLK_TV_SRC_SEL; -+} -+ -diff --git a/drivers/gpu/drm/radeon/radeon_microcode.h b/drivers/gpu/drm/radeon/radeon_microcode.h -deleted file mode 100644 -index a348c9e..0000000 ---- a/drivers/gpu/drm/radeon/radeon_microcode.h -+++ /dev/null -@@ -1,1844 +0,0 @@ --/* -- * Copyright 2007 Advanced Micro Devices, Inc. -- * All Rights Reserved. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice (including the next -- * paragraph) shall be included in all copies or substantial portions of the -- * Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- * -- */ -- --#ifndef RADEON_MICROCODE_H --#define RADEON_MICROCODE_H -- --/* production radeon ucode r1xx-r6xx */ --static const u32 R100_cp_microcode[][2] = { -- { 0x21007000, 0000000000 }, -- { 0x20007000, 0000000000 }, -- { 0x000000b4, 0x00000004 }, -- { 0x000000b8, 0x00000004 }, -- { 0x6f5b4d4c, 0000000000 }, -- { 0x4c4c427f, 0000000000 }, -- { 0x5b568a92, 0000000000 }, -- { 0x4ca09c6d, 0000000000 }, -- { 0xad4c4c4c, 0000000000 }, -- { 0x4ce1af3d, 0000000000 }, -- { 0xd8afafaf, 0000000000 }, -- { 0xd64c4cdc, 0000000000 }, -- { 0x4cd10d10, 0000000000 }, -- { 0x000f0000, 0x00000016 }, -- { 0x362f242d, 0000000000 }, -- { 0x00000012, 0x00000004 }, -- { 0x000f0000, 0x00000016 }, -- { 0x362f282d, 0000000000 }, -- { 0x000380e7, 0x00000002 }, -- { 0x04002c97, 0x00000002 }, -- { 0x000f0001, 0x00000016 }, -- { 0x333a3730, 0000000000 }, -- { 0x000077ef, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x00000021, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00061000, 0x00000002 }, -- { 0x00000021, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00061000, 0x00000002 }, -- { 0x00000021, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00000017, 0x00000004 }, -- { 0x0003802b, 0x00000002 }, -- { 0x040067e0, 0x00000002 }, -- { 0x00000017, 0x00000004 }, -- { 0x000077e0, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x000037e1, 0x00000002 }, -- { 0x040067e1, 0x00000006 }, -- { 0x000077e0, 0x00000002 }, -- { 0x000077e1, 0x00000002 }, -- { 0x000077e1, 0x00000006 }, -- { 0xffffffff, 0000000000 }, -- { 0x10000000, 0000000000 }, -- { 0x0003802b, 0x00000002 }, -- { 0x040067e0, 0x00000006 }, -- { 0x00007675, 0x00000002 }, -- { 0x00007676, 0x00000002 }, -- { 0x00007677, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0003802c, 0x00000002 }, -- { 0x04002676, 0x00000002 }, -- { 0x00007677, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0000002f, 0x00000018 }, -- { 0x0000002f, 0x00000018 }, -- { 0000000000, 0x00000006 }, -- { 0x00000030, 0x00000018 }, -- { 0x00000030, 0x00000018 }, -- { 0000000000, 0x00000006 }, -- { 0x01605000, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x00098000, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x64c0603e, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00080000, 0x00000016 }, -- { 0000000000, 0000000000 }, -- { 0x0400251d, 0x00000002 }, -- { 0x00007580, 0x00000002 }, -- { 0x00067581, 0x00000002 }, -- { 0x04002580, 0x00000002 }, -- { 0x00067581, 0x00000002 }, -- { 0x00000049, 0x00000004 }, -- { 0x00005000, 0000000000 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x0000750e, 0x00000002 }, -- { 0x00019000, 0x00000002 }, -- { 0x00011055, 0x00000014 }, -- { 0x00000055, 0x00000012 }, -- { 0x0400250f, 0x00000002 }, -- { 0x0000504f, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00007565, 0x00000002 }, -- { 0x00007566, 0x00000002 }, -- { 0x00000058, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x01e655b4, 0x00000002 }, -- { 0x4401b0e4, 0x00000002 }, -- { 0x01c110e4, 0x00000002 }, -- { 0x26667066, 0x00000018 }, -- { 0x040c2565, 0x00000002 }, -- { 0x00000066, 0x00000018 }, -- { 0x04002564, 0x00000002 }, -- { 0x00007566, 0x00000002 }, -- { 0x0000005d, 0x00000004 }, -- { 0x00401069, 0x00000008 }, -- { 0x00101000, 0x00000002 }, -- { 0x000d80ff, 0x00000002 }, -- { 0x0080006c, 0x00000008 }, -- { 0x000f9000, 0x00000002 }, -- { 0x000e00ff, 0x00000002 }, -- { 0000000000, 0x00000006 }, -- { 0x0000008f, 0x00000018 }, -- { 0x0000005b, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00007576, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x00009000, 0x00000002 }, -- { 0x00041000, 0x00000002 }, -- { 0x0c00350e, 0x00000002 }, -- { 0x00049000, 0x00000002 }, -- { 0x00051000, 0x00000002 }, -- { 0x01e785f8, 0x00000002 }, -- { 0x00200000, 0x00000002 }, -- { 0x0060007e, 0x0000000c }, -- { 0x00007563, 0x00000002 }, -- { 0x006075f0, 0x00000021 }, -- { 0x20007073, 0x00000004 }, -- { 0x00005073, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00007576, 0x00000002 }, -- { 0x00007577, 0x00000002 }, -- { 0x0000750e, 0x00000002 }, -- { 0x0000750f, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00600083, 0x0000000c }, -- { 0x006075f0, 0x00000021 }, -- { 0x000075f8, 0x00000002 }, -- { 0x00000083, 0x00000004 }, -- { 0x000a750e, 0x00000002 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x0020750f, 0x00000002 }, -- { 0x00600086, 0x00000004 }, -- { 0x00007570, 0x00000002 }, -- { 0x00007571, 0x00000002 }, -- { 0x00007572, 0x00000006 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00005000, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00007568, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x00000095, 0x0000000c }, -- { 0x00058000, 0x00000002 }, -- { 0x0c607562, 0x00000002 }, -- { 0x00000097, 0x00000004 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x00600096, 0x00000004 }, -- { 0x400070e5, 0000000000 }, -- { 0x000380e6, 0x00000002 }, -- { 0x040025c5, 0x00000002 }, -- { 0x000380e5, 0x00000002 }, -- { 0x000000a8, 0x0000001c }, -- { 0x000650aa, 0x00000018 }, -- { 0x040025bb, 0x00000002 }, -- { 0x000610ab, 0x00000018 }, -- { 0x040075bc, 0000000000 }, -- { 0x000075bb, 0x00000002 }, -- { 0x000075bc, 0000000000 }, -- { 0x00090000, 0x00000006 }, -- { 0x00090000, 0x00000002 }, -- { 0x000d8002, 0x00000006 }, -- { 0x00007832, 0x00000002 }, -- { 0x00005000, 0x00000002 }, -- { 0x000380e7, 0x00000002 }, -- { 0x04002c97, 0x00000002 }, -- { 0x00007820, 0x00000002 }, -- { 0x00007821, 0x00000002 }, -- { 0x00007800, 0000000000 }, -- { 0x01200000, 0x00000002 }, -- { 0x20077000, 0x00000002 }, -- { 0x01200000, 0x00000002 }, -- { 0x20007000, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x0120751b, 0x00000002 }, -- { 0x8040750a, 0x00000002 }, -- { 0x8040750b, 0x00000002 }, -- { 0x00110000, 0x00000002 }, -- { 0x000380e5, 0x00000002 }, -- { 0x000000c6, 0x0000001c }, -- { 0x000610ab, 0x00000018 }, -- { 0x844075bd, 0x00000002 }, -- { 0x000610aa, 0x00000018 }, -- { 0x840075bb, 0x00000002 }, -- { 0x000610ab, 0x00000018 }, -- { 0x844075bc, 0x00000002 }, -- { 0x000000c9, 0x00000004 }, -- { 0x804075bd, 0x00000002 }, -- { 0x800075bb, 0x00000002 }, -- { 0x804075bc, 0x00000002 }, -- { 0x00108000, 0x00000002 }, -- { 0x01400000, 0x00000002 }, -- { 0x006000cd, 0x0000000c }, -- { 0x20c07000, 0x00000020 }, -- { 0x000000cf, 0x00000012 }, -- { 0x00800000, 0x00000006 }, -- { 0x0080751d, 0x00000006 }, -- { 0000000000, 0000000000 }, -- { 0x0000775c, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00661000, 0x00000002 }, -- { 0x0460275d, 0x00000020 }, -- { 0x00004000, 0000000000 }, -- { 0x01e00830, 0x00000002 }, -- { 0x21007000, 0000000000 }, -- { 0x6464614d, 0000000000 }, -- { 0x69687420, 0000000000 }, -- { 0x00000073, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x00005000, 0x00000002 }, -- { 0x000380d0, 0x00000002 }, -- { 0x040025e0, 0x00000002 }, -- { 0x000075e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000380e0, 0x00000002 }, -- { 0x04002394, 0x00000002 }, -- { 0x00005000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x00000008, 0000000000 }, -- { 0x00000004, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 R200_cp_microcode[][2] = { -- { 0x21007000, 0000000000 }, -- { 0x20007000, 0000000000 }, -- { 0x000000bf, 0x00000004 }, -- { 0x000000c3, 0x00000004 }, -- { 0x7a685e5d, 0000000000 }, -- { 0x5d5d5588, 0000000000 }, -- { 0x68659197, 0000000000 }, -- { 0x5da19f78, 0000000000 }, -- { 0x5d5d5d5d, 0000000000 }, -- { 0x5dee5d50, 0000000000 }, -- { 0xf2acacac, 0000000000 }, -- { 0xe75df9e9, 0000000000 }, -- { 0xb1dd0e11, 0000000000 }, -- { 0xe2afafaf, 0000000000 }, -- { 0x000f0000, 0x00000016 }, -- { 0x452f232d, 0000000000 }, -- { 0x00000013, 0x00000004 }, -- { 0x000f0000, 0x00000016 }, -- { 0x452f272d, 0000000000 }, -- { 0x000f0001, 0x00000016 }, -- { 0x3e4d4a37, 0000000000 }, -- { 0x000077ef, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x00000020, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00061000, 0x00000002 }, -- { 0x00000020, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00061000, 0x00000002 }, -- { 0x00000020, 0x0000001a }, -- { 0x00004000, 0x0000001e }, -- { 0x00000016, 0x00000004 }, -- { 0x0003802a, 0x00000002 }, -- { 0x040067e0, 0x00000002 }, -- { 0x00000016, 0x00000004 }, -- { 0x000077e0, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x000037e1, 0x00000002 }, -- { 0x040067e1, 0x00000006 }, -- { 0x000077e0, 0x00000002 }, -- { 0x000077e1, 0x00000002 }, -- { 0x000077e1, 0x00000006 }, -- { 0xffffffff, 0000000000 }, -- { 0x10000000, 0000000000 }, -- { 0x07f007f0, 0000000000 }, -- { 0x0003802a, 0x00000002 }, -- { 0x040067e0, 0x00000006 }, -- { 0x0003802c, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002743, 0x00000002 }, -- { 0x00007675, 0x00000002 }, -- { 0x00007676, 0x00000002 }, -- { 0x00007677, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0003802c, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002743, 0x00000002 }, -- { 0x00007676, 0x00000002 }, -- { 0x00007677, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0003802b, 0x00000002 }, -- { 0x04002676, 0x00000002 }, -- { 0x00007677, 0x00000002 }, -- { 0x0003802c, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002743, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0003802c, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002741, 0x00000002 }, -- { 0x04002743, 0x00000002 }, -- { 0x00007678, 0x00000006 }, -- { 0x0000002f, 0x00000018 }, -- { 0x0000002f, 0x00000018 }, -- { 0000000000, 0x00000006 }, -- { 0x00000037, 0x00000018 }, -- { 0x00000037, 0x00000018 }, -- { 0000000000, 0x00000006 }, -- { 0x01605000, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x00098000, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x64c06051, 0x00000004 }, -- { 0x00080000, 0x00000016 }, -- { 0000000000, 0000000000 }, -- { 0x0400251d, 0x00000002 }, -- { 0x00007580, 0x00000002 }, -- { 0x00067581, 0x00000002 }, -- { 0x04002580, 0x00000002 }, -- { 0x00067581, 0x00000002 }, -- { 0x0000005a, 0x00000004 }, -- { 0x00005000, 0000000000 }, -- { 0x00061000, 0x00000002 }, -- { 0x0000750e, 0x00000002 }, -- { 0x00019000, 0x00000002 }, -- { 0x00011064, 0x00000014 }, -- { 0x00000064, 0x00000012 }, -- { 0x0400250f, 0x00000002 }, -- { 0x0000505e, 0x00000004 }, -- { 0x00007565, 0x00000002 }, -- { 0x00007566, 0x00000002 }, -- { 0x00000065, 0x00000004 }, -- { 0x01e655b4, 0x00000002 }, -- { 0x4401b0f0, 0x00000002 }, -- { 0x01c110f0, 0x00000002 }, -- { 0x26667071, 0x00000018 }, -- { 0x040c2565, 0x00000002 }, -- { 0x00000071, 0x00000018 }, -- { 0x04002564, 0x00000002 }, -- { 0x00007566, 0x00000002 }, -- { 0x00000068, 0x00000004 }, -- { 0x00401074, 0x00000008 }, -- { 0x00101000, 0x00000002 }, -- { 0x000d80ff, 0x00000002 }, -- { 0x00800077, 0x00000008 }, -- { 0x000f9000, 0x00000002 }, -- { 0x000e00ff, 0x00000002 }, -- { 0000000000, 0x00000006 }, -- { 0x00000094, 0x00000018 }, -- { 0x00000068, 0x00000004 }, -- { 0x00007576, 0x00000002 }, -- { 0x00065000, 0x00000002 }, -- { 0x00009000, 0x00000002 }, -- { 0x00041000, 0x00000002 }, -- { 0x0c00350e, 0x00000002 }, -- { 0x00049000, 0x00000002 }, -- { 0x00051000, 0x00000002 }, -- { 0x01e785f8, 0x00000002 }, -- { 0x00200000, 0x00000002 }, -- { 0x00600087, 0x0000000c }, -- { 0x00007563, 0x00000002 }, -- { 0x006075f0, 0x00000021 }, -- { 0x2000707c, 0x00000004 }, -- { 0x0000507c, 0x00000004 }, -- { 0x00007576, 0x00000002 }, -- { 0x00007577, 0x00000002 }, -- { 0x0000750e, 0x00000002 }, -- { 0x0000750f, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x0060008a, 0x0000000c }, -- { 0x006075f0, 0x00000021 }, -- { 0x000075f8, 0x00000002 }, -- { 0x0000008a, 0x00000004 }, -- { 0x000a750e, 0x00000002 }, -- { 0x0020750f, 0x00000002 }, -- { 0x0060008d, 0x00000004 }, -- { 0x00007570, 0x00000002 }, -- { 0x00007571, 0x00000002 }, -- { 0x00007572, 0x00000006 }, -- { 0x00005000, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00007568, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x00000098, 0x0000000c }, -- { 0x00058000, 0x00000002 }, -- { 0x0c607562, 0x00000002 }, -- { 0x0000009a, 0x00000004 }, -- { 0x00600099, 0x00000004 }, -- { 0x400070f1, 0000000000 }, -- { 0x000380f1, 0x00000002 }, -- { 0x000000a7, 0x0000001c }, -- { 0x000650a9, 0x00000018 }, -- { 0x040025bb, 0x00000002 }, -- { 0x000610aa, 0x00000018 }, -- { 0x040075bc, 0000000000 }, -- { 0x000075bb, 0x00000002 }, -- { 0x000075bc, 0000000000 }, -- { 0x00090000, 0x00000006 }, -- { 0x00090000, 0x00000002 }, -- { 0x000d8002, 0x00000006 }, -- { 0x00005000, 0x00000002 }, -- { 0x00007821, 0x00000002 }, -- { 0x00007800, 0000000000 }, -- { 0x00007821, 0x00000002 }, -- { 0x00007800, 0000000000 }, -- { 0x01665000, 0x00000002 }, -- { 0x000a0000, 0x00000002 }, -- { 0x000671cc, 0x00000002 }, -- { 0x0286f1cd, 0x00000002 }, -- { 0x000000b7, 0x00000010 }, -- { 0x21007000, 0000000000 }, -- { 0x000000be, 0x0000001c }, -- { 0x00065000, 0x00000002 }, -- { 0x000a0000, 0x00000002 }, -- { 0x00061000, 0x00000002 }, -- { 0x000b0000, 0x00000002 }, -- { 0x38067000, 0x00000002 }, -- { 0x000a00ba, 0x00000004 }, -- { 0x20007000, 0000000000 }, -- { 0x01200000, 0x00000002 }, -- { 0x20077000, 0x00000002 }, -- { 0x01200000, 0x00000002 }, -- { 0x20007000, 0000000000 }, -- { 0x00061000, 0x00000002 }, -- { 0x0120751b, 0x00000002 }, -- { 0x8040750a, 0x00000002 }, -- { 0x8040750b, 0x00000002 }, -- { 0x00110000, 0x00000002 }, -- { 0x000380f1, 0x00000002 }, -- { 0x000000d1, 0x0000001c }, -- { 0x000610aa, 0x00000018 }, -- { 0x844075bd, 0x00000002 }, -- { 0x000610a9, 0x00000018 }, -- { 0x840075bb, 0x00000002 }, -- { 0x000610aa, 0x00000018 }, -- { 0x844075bc, 0x00000002 }, -- { 0x000000d4, 0x00000004 }, -- { 0x804075bd, 0x00000002 }, -- { 0x800075bb, 0x00000002 }, -- { 0x804075bc, 0x00000002 }, -- { 0x00108000, 0x00000002 }, -- { 0x01400000, 0x00000002 }, -- { 0x006000d8, 0x0000000c }, -- { 0x20c07000, 0x00000020 }, -- { 0x000000da, 0x00000012 }, -- { 0x00800000, 0x00000006 }, -- { 0x0080751d, 0x00000006 }, -- { 0x000025bb, 0x00000002 }, -- { 0x000040d4, 0x00000004 }, -- { 0x0000775c, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00661000, 0x00000002 }, -- { 0x0460275d, 0x00000020 }, -- { 0x00004000, 0000000000 }, -- { 0x00007999, 0x00000002 }, -- { 0x00a05000, 0x00000002 }, -- { 0x00661000, 0x00000002 }, -- { 0x0460299b, 0x00000020 }, -- { 0x00004000, 0000000000 }, -- { 0x01e00830, 0x00000002 }, -- { 0x21007000, 0000000000 }, -- { 0x00005000, 0x00000002 }, -- { 0x00038056, 0x00000002 }, -- { 0x040025e0, 0x00000002 }, -- { 0x000075e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000380ed, 0x00000002 }, -- { 0x04007394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000078c4, 0x00000002 }, -- { 0x000078c5, 0x00000002 }, -- { 0x000078c6, 0x00000002 }, -- { 0x00007924, 0x00000002 }, -- { 0x00007925, 0x00000002 }, -- { 0x00007926, 0x00000002 }, -- { 0x000000f2, 0x00000004 }, -- { 0x00007924, 0x00000002 }, -- { 0x00007925, 0x00000002 }, -- { 0x00007926, 0x00000002 }, -- { 0x000000f9, 0x00000004 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 R300_cp_microcode[][2] = { -- { 0x4200e000, 0000000000 }, -- { 0x4000e000, 0000000000 }, -- { 0x000000ae, 0x00000008 }, -- { 0x000000b2, 0x00000008 }, -- { 0x67554b4a, 0000000000 }, -- { 0x4a4a4475, 0000000000 }, -- { 0x55527d83, 0000000000 }, -- { 0x4a8c8b65, 0000000000 }, -- { 0x4aef4af6, 0000000000 }, -- { 0x4ae14a4a, 0000000000 }, -- { 0xe4979797, 0000000000 }, -- { 0xdb4aebdd, 0000000000 }, -- { 0x9ccc4a4a, 0000000000 }, -- { 0xd1989898, 0000000000 }, -- { 0x4a0f9ad6, 0000000000 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000d0012, 0x00000038 }, -- { 0x0000e8b4, 0x00000004 }, -- { 0x000d0014, 0x00000038 }, -- { 0x0000e8b6, 0x00000004 }, -- { 0x000d0016, 0x00000038 }, -- { 0x0000e854, 0x00000004 }, -- { 0x000d0018, 0x00000038 }, -- { 0x0000e855, 0x00000004 }, -- { 0x000d001a, 0x00000038 }, -- { 0x0000e856, 0x00000004 }, -- { 0x000d001c, 0x00000038 }, -- { 0x0000e857, 0x00000004 }, -- { 0x000d001e, 0x00000038 }, -- { 0x0000e824, 0x00000004 }, -- { 0x000d0020, 0x00000038 }, -- { 0x0000e825, 0x00000004 }, -- { 0x000d0022, 0x00000038 }, -- { 0x0000e830, 0x00000004 }, -- { 0x000d0024, 0x00000038 }, -- { 0x0000f0c0, 0x00000004 }, -- { 0x000d0026, 0x00000038 }, -- { 0x0000f0c1, 0x00000004 }, -- { 0x000d0028, 0x00000038 }, -- { 0x0000f041, 0x00000004 }, -- { 0x000d002a, 0x00000038 }, -- { 0x0000f184, 0x00000004 }, -- { 0x000d002c, 0x00000038 }, -- { 0x0000f185, 0x00000004 }, -- { 0x000d002e, 0x00000038 }, -- { 0x0000f186, 0x00000004 }, -- { 0x000d0030, 0x00000038 }, -- { 0x0000f187, 0x00000004 }, -- { 0x000d0032, 0x00000038 }, -- { 0x0000f180, 0x00000004 }, -- { 0x000d0034, 0x00000038 }, -- { 0x0000f393, 0x00000004 }, -- { 0x000d0036, 0x00000038 }, -- { 0x0000f38a, 0x00000004 }, -- { 0x000d0038, 0x00000038 }, -- { 0x0000f38e, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000043, 0x00000018 }, -- { 0x00cce800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x0000003a, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x2000451d, 0x00000004 }, -- { 0x0000e580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x08004580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x00000047, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x00032000, 0x00000004 }, -- { 0x00022051, 0x00000028 }, -- { 0x00000051, 0x00000024 }, -- { 0x0800450f, 0x00000004 }, -- { 0x0000a04b, 0x00000008 }, -- { 0x0000e565, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000052, 0x00000008 }, -- { 0x03cca5b4, 0x00000004 }, -- { 0x05432000, 0x00000004 }, -- { 0x00022000, 0x00000004 }, -- { 0x4ccce05e, 0x00000030 }, -- { 0x08274565, 0x00000004 }, -- { 0x0000005e, 0x00000030 }, -- { 0x08004564, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000055, 0x00000008 }, -- { 0x00802061, 0x00000010 }, -- { 0x00202000, 0x00000004 }, -- { 0x001b00ff, 0x00000004 }, -- { 0x01000064, 0x00000010 }, -- { 0x001f2000, 0x00000004 }, -- { 0x001c00ff, 0x00000004 }, -- { 0000000000, 0x0000000c }, -- { 0x00000080, 0x00000030 }, -- { 0x00000055, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00012000, 0x00000004 }, -- { 0x00082000, 0x00000004 }, -- { 0x1800650e, 0x00000004 }, -- { 0x00092000, 0x00000004 }, -- { 0x000a2000, 0x00000004 }, -- { 0x000f0000, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x00000074, 0x00000018 }, -- { 0x0000e563, 0x00000004 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000069, 0x00000008 }, -- { 0x0000a069, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x0000e577, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x0000e50f, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000077, 0x00000018 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000077, 0x00000008 }, -- { 0x0014e50e, 0x00000004 }, -- { 0x0040e50f, 0x00000004 }, -- { 0x00c0007a, 0x00000008 }, -- { 0x0000e570, 0x00000004 }, -- { 0x0000e571, 0x00000004 }, -- { 0x0000e572, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x0000e568, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00000084, 0x00000018 }, -- { 0x000b0000, 0x00000004 }, -- { 0x18c0e562, 0x00000004 }, -- { 0x00000086, 0x00000008 }, -- { 0x00c00085, 0x00000008 }, -- { 0x000700e3, 0x00000004 }, -- { 0x00000092, 0x00000038 }, -- { 0x000ca094, 0x00000030 }, -- { 0x080045bb, 0x00000004 }, -- { 0x000c2095, 0x00000030 }, -- { 0x0800e5bc, 0000000000 }, -- { 0x0000e5bb, 0x00000004 }, -- { 0x0000e5bc, 0000000000 }, -- { 0x00120000, 0x0000000c }, -- { 0x00120000, 0x00000004 }, -- { 0x001b0002, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e800, 0000000000 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e82e, 0000000000 }, -- { 0x02cca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000ce1cc, 0x00000004 }, -- { 0x050de1cd, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x000000a4, 0x00000018 }, -- { 0x00c0a000, 0x00000004 }, -- { 0x000000a1, 0x00000008 }, -- { 0x000000a6, 0x00000020 }, -- { 0x4200e000, 0000000000 }, -- { 0x000000ad, 0x00000038 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00160000, 0x00000004 }, -- { 0x700ce000, 0x00000004 }, -- { 0x001400a9, 0x00000008 }, -- { 0x4000e000, 0000000000 }, -- { 0x02400000, 0x00000004 }, -- { 0x400ee000, 0x00000004 }, -- { 0x02400000, 0x00000004 }, -- { 0x4000e000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0240e51b, 0x00000004 }, -- { 0x0080e50a, 0x00000005 }, -- { 0x0080e50b, 0x00000005 }, -- { 0x00220000, 0x00000004 }, -- { 0x000700e3, 0x00000004 }, -- { 0x000000c0, 0x00000038 }, -- { 0x000c2095, 0x00000030 }, -- { 0x0880e5bd, 0x00000005 }, -- { 0x000c2094, 0x00000030 }, -- { 0x0800e5bb, 0x00000005 }, -- { 0x000c2095, 0x00000030 }, -- { 0x0880e5bc, 0x00000005 }, -- { 0x000000c3, 0x00000008 }, -- { 0x0080e5bd, 0x00000005 }, -- { 0x0000e5bb, 0x00000005 }, -- { 0x0080e5bc, 0x00000005 }, -- { 0x00210000, 0x00000004 }, -- { 0x02800000, 0x00000004 }, -- { 0x00c000c7, 0x00000018 }, -- { 0x4180e000, 0x00000040 }, -- { 0x000000c9, 0x00000024 }, -- { 0x01000000, 0x0000000c }, -- { 0x0100e51d, 0x0000000c }, -- { 0x000045bb, 0x00000004 }, -- { 0x000080c3, 0x00000008 }, -- { 0x0000f3ce, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053cf, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f3d2, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053d3, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f39d, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c0539e, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x03c00830, 0x00000004 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x200045e0, 0x00000004 }, -- { 0x0000e5e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000700e0, 0x00000004 }, -- { 0x0800e394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x0000e8c4, 0x00000004 }, -- { 0x0000e8c5, 0x00000004 }, -- { 0x0000e8c6, 0x00000004 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000e4, 0x00000008 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000eb, 0x00000008 }, -- { 0x02c02000, 0x00000004 }, -- { 0x00060000, 0x00000004 }, -- { 0x000000f3, 0x00000034 }, -- { 0x000000f0, 0x00000008 }, -- { 0x00008000, 0x00000004 }, -- { 0xc000e000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x001d0018, 0x00000004 }, -- { 0x001a0001, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0x0500a04a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 R420_cp_microcode[][2] = { -- { 0x4200e000, 0000000000 }, -- { 0x4000e000, 0000000000 }, -- { 0x00000099, 0x00000008 }, -- { 0x0000009d, 0x00000008 }, -- { 0x4a554b4a, 0000000000 }, -- { 0x4a4a4467, 0000000000 }, -- { 0x55526f75, 0000000000 }, -- { 0x4a7e7d65, 0000000000 }, -- { 0xd9d3dff6, 0000000000 }, -- { 0x4ac54a4a, 0000000000 }, -- { 0xc8828282, 0000000000 }, -- { 0xbf4acfc1, 0000000000 }, -- { 0x87b04a4a, 0000000000 }, -- { 0xb5838383, 0000000000 }, -- { 0x4a0f85ba, 0000000000 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000d0012, 0x00000038 }, -- { 0x0000e8b4, 0x00000004 }, -- { 0x000d0014, 0x00000038 }, -- { 0x0000e8b6, 0x00000004 }, -- { 0x000d0016, 0x00000038 }, -- { 0x0000e854, 0x00000004 }, -- { 0x000d0018, 0x00000038 }, -- { 0x0000e855, 0x00000004 }, -- { 0x000d001a, 0x00000038 }, -- { 0x0000e856, 0x00000004 }, -- { 0x000d001c, 0x00000038 }, -- { 0x0000e857, 0x00000004 }, -- { 0x000d001e, 0x00000038 }, -- { 0x0000e824, 0x00000004 }, -- { 0x000d0020, 0x00000038 }, -- { 0x0000e825, 0x00000004 }, -- { 0x000d0022, 0x00000038 }, -- { 0x0000e830, 0x00000004 }, -- { 0x000d0024, 0x00000038 }, -- { 0x0000f0c0, 0x00000004 }, -- { 0x000d0026, 0x00000038 }, -- { 0x0000f0c1, 0x00000004 }, -- { 0x000d0028, 0x00000038 }, -- { 0x0000f041, 0x00000004 }, -- { 0x000d002a, 0x00000038 }, -- { 0x0000f184, 0x00000004 }, -- { 0x000d002c, 0x00000038 }, -- { 0x0000f185, 0x00000004 }, -- { 0x000d002e, 0x00000038 }, -- { 0x0000f186, 0x00000004 }, -- { 0x000d0030, 0x00000038 }, -- { 0x0000f187, 0x00000004 }, -- { 0x000d0032, 0x00000038 }, -- { 0x0000f180, 0x00000004 }, -- { 0x000d0034, 0x00000038 }, -- { 0x0000f393, 0x00000004 }, -- { 0x000d0036, 0x00000038 }, -- { 0x0000f38a, 0x00000004 }, -- { 0x000d0038, 0x00000038 }, -- { 0x0000f38e, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000043, 0x00000018 }, -- { 0x00cce800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x0000003a, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x2000451d, 0x00000004 }, -- { 0x0000e580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x08004580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x00000047, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x00032000, 0x00000004 }, -- { 0x00022051, 0x00000028 }, -- { 0x00000051, 0x00000024 }, -- { 0x0800450f, 0x00000004 }, -- { 0x0000a04b, 0x00000008 }, -- { 0x0000e565, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000052, 0x00000008 }, -- { 0x03cca5b4, 0x00000004 }, -- { 0x05432000, 0x00000004 }, -- { 0x00022000, 0x00000004 }, -- { 0x4ccce05e, 0x00000030 }, -- { 0x08274565, 0x00000004 }, -- { 0x0000005e, 0x00000030 }, -- { 0x08004564, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000055, 0x00000008 }, -- { 0x00802061, 0x00000010 }, -- { 0x00202000, 0x00000004 }, -- { 0x001b00ff, 0x00000004 }, -- { 0x01000064, 0x00000010 }, -- { 0x001f2000, 0x00000004 }, -- { 0x001c00ff, 0x00000004 }, -- { 0000000000, 0x0000000c }, -- { 0x00000072, 0x00000030 }, -- { 0x00000055, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x0000e577, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x0000e50f, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000069, 0x00000018 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000069, 0x00000008 }, -- { 0x0014e50e, 0x00000004 }, -- { 0x0040e50f, 0x00000004 }, -- { 0x00c0006c, 0x00000008 }, -- { 0x0000e570, 0x00000004 }, -- { 0x0000e571, 0x00000004 }, -- { 0x0000e572, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x0000e568, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00000076, 0x00000018 }, -- { 0x000b0000, 0x00000004 }, -- { 0x18c0e562, 0x00000004 }, -- { 0x00000078, 0x00000008 }, -- { 0x00c00077, 0x00000008 }, -- { 0x000700c7, 0x00000004 }, -- { 0x00000080, 0x00000038 }, -- { 0x0000e5bb, 0x00000004 }, -- { 0x0000e5bc, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e800, 0000000000 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e82e, 0000000000 }, -- { 0x02cca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000ce1cc, 0x00000004 }, -- { 0x050de1cd, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x0000008f, 0x00000018 }, -- { 0x00c0a000, 0x00000004 }, -- { 0x0000008c, 0x00000008 }, -- { 0x00000091, 0x00000020 }, -- { 0x4200e000, 0000000000 }, -- { 0x00000098, 0x00000038 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00160000, 0x00000004 }, -- { 0x700ce000, 0x00000004 }, -- { 0x00140094, 0x00000008 }, -- { 0x4000e000, 0000000000 }, -- { 0x02400000, 0x00000004 }, -- { 0x400ee000, 0x00000004 }, -- { 0x02400000, 0x00000004 }, -- { 0x4000e000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0240e51b, 0x00000004 }, -- { 0x0080e50a, 0x00000005 }, -- { 0x0080e50b, 0x00000005 }, -- { 0x00220000, 0x00000004 }, -- { 0x000700c7, 0x00000004 }, -- { 0x000000a4, 0x00000038 }, -- { 0x0080e5bd, 0x00000005 }, -- { 0x0000e5bb, 0x00000005 }, -- { 0x0080e5bc, 0x00000005 }, -- { 0x00210000, 0x00000004 }, -- { 0x02800000, 0x00000004 }, -- { 0x00c000ab, 0x00000018 }, -- { 0x4180e000, 0x00000040 }, -- { 0x000000ad, 0x00000024 }, -- { 0x01000000, 0x0000000c }, -- { 0x0100e51d, 0x0000000c }, -- { 0x000045bb, 0x00000004 }, -- { 0x000080a7, 0x00000008 }, -- { 0x0000f3ce, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053cf, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f3d2, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053d3, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f39d, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c0539e, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x03c00830, 0x00000004 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x200045e0, 0x00000004 }, -- { 0x0000e5e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000700c4, 0x00000004 }, -- { 0x0800e394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x0000e8c4, 0x00000004 }, -- { 0x0000e8c5, 0x00000004 }, -- { 0x0000e8c6, 0x00000004 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000c8, 0x00000008 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000cf, 0x00000008 }, -- { 0x02c02000, 0x00000004 }, -- { 0x00060000, 0x00000004 }, -- { 0x000000d7, 0x00000034 }, -- { 0x000000d4, 0x00000008 }, -- { 0x00008000, 0x00000004 }, -- { 0xc000e000, 0000000000 }, -- { 0x0000e1cc, 0x00000004 }, -- { 0x0500e1cd, 0x00000004 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000000de, 0x00000034 }, -- { 0x000000da, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x0019e1cc, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x0500a000, 0x00000004 }, -- { 0x080041cd, 0x00000004 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x001d0018, 0x00000004 }, -- { 0x001a0001, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0x0500a04a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 RS600_cp_microcode[][2] = { -- { 0x4200e000, 0000000000 }, -- { 0x4000e000, 0000000000 }, -- { 0x000000a0, 0x00000008 }, -- { 0x000000a4, 0x00000008 }, -- { 0x4a554b4a, 0000000000 }, -- { 0x4a4a4467, 0000000000 }, -- { 0x55526f75, 0000000000 }, -- { 0x4a7e7d65, 0000000000 }, -- { 0x4ae74af6, 0000000000 }, -- { 0x4ad34a4a, 0000000000 }, -- { 0xd6898989, 0000000000 }, -- { 0xcd4addcf, 0000000000 }, -- { 0x8ebe4ae2, 0000000000 }, -- { 0xc38a8a8a, 0000000000 }, -- { 0x4a0f8cc8, 0000000000 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000d0012, 0x00000038 }, -- { 0x0000e8b4, 0x00000004 }, -- { 0x000d0014, 0x00000038 }, -- { 0x0000e8b6, 0x00000004 }, -- { 0x000d0016, 0x00000038 }, -- { 0x0000e854, 0x00000004 }, -- { 0x000d0018, 0x00000038 }, -- { 0x0000e855, 0x00000004 }, -- { 0x000d001a, 0x00000038 }, -- { 0x0000e856, 0x00000004 }, -- { 0x000d001c, 0x00000038 }, -- { 0x0000e857, 0x00000004 }, -- { 0x000d001e, 0x00000038 }, -- { 0x0000e824, 0x00000004 }, -- { 0x000d0020, 0x00000038 }, -- { 0x0000e825, 0x00000004 }, -- { 0x000d0022, 0x00000038 }, -- { 0x0000e830, 0x00000004 }, -- { 0x000d0024, 0x00000038 }, -- { 0x0000f0c0, 0x00000004 }, -- { 0x000d0026, 0x00000038 }, -- { 0x0000f0c1, 0x00000004 }, -- { 0x000d0028, 0x00000038 }, -- { 0x0000f041, 0x00000004 }, -- { 0x000d002a, 0x00000038 }, -- { 0x0000f184, 0x00000004 }, -- { 0x000d002c, 0x00000038 }, -- { 0x0000f185, 0x00000004 }, -- { 0x000d002e, 0x00000038 }, -- { 0x0000f186, 0x00000004 }, -- { 0x000d0030, 0x00000038 }, -- { 0x0000f187, 0x00000004 }, -- { 0x000d0032, 0x00000038 }, -- { 0x0000f180, 0x00000004 }, -- { 0x000d0034, 0x00000038 }, -- { 0x0000f393, 0x00000004 }, -- { 0x000d0036, 0x00000038 }, -- { 0x0000f38a, 0x00000004 }, -- { 0x000d0038, 0x00000038 }, -- { 0x0000f38e, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000043, 0x00000018 }, -- { 0x00cce800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x0000003a, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x2000451d, 0x00000004 }, -- { 0x0000e580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x08004580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x00000047, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x00032000, 0x00000004 }, -- { 0x00022051, 0x00000028 }, -- { 0x00000051, 0x00000024 }, -- { 0x0800450f, 0x00000004 }, -- { 0x0000a04b, 0x00000008 }, -- { 0x0000e565, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000052, 0x00000008 }, -- { 0x03cca5b4, 0x00000004 }, -- { 0x05432000, 0x00000004 }, -- { 0x00022000, 0x00000004 }, -- { 0x4ccce05e, 0x00000030 }, -- { 0x08274565, 0x00000004 }, -- { 0x0000005e, 0x00000030 }, -- { 0x08004564, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000055, 0x00000008 }, -- { 0x00802061, 0x00000010 }, -- { 0x00202000, 0x00000004 }, -- { 0x001b00ff, 0x00000004 }, -- { 0x01000064, 0x00000010 }, -- { 0x001f2000, 0x00000004 }, -- { 0x001c00ff, 0x00000004 }, -- { 0000000000, 0x0000000c }, -- { 0x00000072, 0x00000030 }, -- { 0x00000055, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x0000e577, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x0000e50f, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000069, 0x00000018 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000069, 0x00000008 }, -- { 0x0014e50e, 0x00000004 }, -- { 0x0040e50f, 0x00000004 }, -- { 0x00c0006c, 0x00000008 }, -- { 0x0000e570, 0x00000004 }, -- { 0x0000e571, 0x00000004 }, -- { 0x0000e572, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x0000e568, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00000076, 0x00000018 }, -- { 0x000b0000, 0x00000004 }, -- { 0x18c0e562, 0x00000004 }, -- { 0x00000078, 0x00000008 }, -- { 0x00c00077, 0x00000008 }, -- { 0x000700d5, 0x00000004 }, -- { 0x00000084, 0x00000038 }, -- { 0x000ca086, 0x00000030 }, -- { 0x080045bb, 0x00000004 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0800e5bc, 0000000000 }, -- { 0x0000e5bb, 0x00000004 }, -- { 0x0000e5bc, 0000000000 }, -- { 0x00120000, 0x0000000c }, -- { 0x00120000, 0x00000004 }, -- { 0x001b0002, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e800, 0000000000 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e82e, 0000000000 }, -- { 0x02cca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000ce1cc, 0x00000004 }, -- { 0x050de1cd, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x00000096, 0x00000018 }, -- { 0x00c0a000, 0x00000004 }, -- { 0x00000093, 0x00000008 }, -- { 0x00000098, 0x00000020 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000009f, 0x00000038 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00160000, 0x00000004 }, -- { 0x700ce000, 0x00000004 }, -- { 0x0014009b, 0x00000008 }, -- { 0x4000e000, 0000000000 }, -- { 0x02400000, 0x00000004 }, -- { 0x400ee000, 0x00000004 }, -- { 0x02400000, 0x00000004 }, -- { 0x4000e000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0240e51b, 0x00000004 }, -- { 0x0080e50a, 0x00000005 }, -- { 0x0080e50b, 0x00000005 }, -- { 0x00220000, 0x00000004 }, -- { 0x000700d5, 0x00000004 }, -- { 0x000000b2, 0x00000038 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0880e5bd, 0x00000005 }, -- { 0x000c2086, 0x00000030 }, -- { 0x0800e5bb, 0x00000005 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0880e5bc, 0x00000005 }, -- { 0x000000b5, 0x00000008 }, -- { 0x0080e5bd, 0x00000005 }, -- { 0x0000e5bb, 0x00000005 }, -- { 0x0080e5bc, 0x00000005 }, -- { 0x00210000, 0x00000004 }, -- { 0x02800000, 0x00000004 }, -- { 0x00c000b9, 0x00000018 }, -- { 0x4180e000, 0x00000040 }, -- { 0x000000bb, 0x00000024 }, -- { 0x01000000, 0x0000000c }, -- { 0x0100e51d, 0x0000000c }, -- { 0x000045bb, 0x00000004 }, -- { 0x000080b5, 0x00000008 }, -- { 0x0000f3ce, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053cf, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f3d2, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053d3, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f39d, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c0539e, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x03c00830, 0x00000004 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x200045e0, 0x00000004 }, -- { 0x0000e5e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000700d2, 0x00000004 }, -- { 0x0800e394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x0000e8c4, 0x00000004 }, -- { 0x0000e8c5, 0x00000004 }, -- { 0x0000e8c6, 0x00000004 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000d6, 0x00000008 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000dd, 0x00000008 }, -- { 0x00e00116, 0000000000 }, -- { 0x000700e1, 0x00000004 }, -- { 0x0800401c, 0x00000004 }, -- { 0x200050e7, 0x00000004 }, -- { 0x0000e01d, 0x00000004 }, -- { 0x000000e4, 0x00000008 }, -- { 0x02c02000, 0x00000004 }, -- { 0x00060000, 0x00000004 }, -- { 0x000000eb, 0x00000034 }, -- { 0x000000e8, 0x00000008 }, -- { 0x00008000, 0x00000004 }, -- { 0xc000e000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x001d0018, 0x00000004 }, -- { 0x001a0001, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0x0500a04a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 RS690_cp_microcode[][2] = { -- { 0x000000dd, 0x00000008 }, -- { 0x000000df, 0x00000008 }, -- { 0x000000a0, 0x00000008 }, -- { 0x000000a4, 0x00000008 }, -- { 0x4a554b4a, 0000000000 }, -- { 0x4a4a4467, 0000000000 }, -- { 0x55526f75, 0000000000 }, -- { 0x4a7e7d65, 0000000000 }, -- { 0x4ad74af6, 0000000000 }, -- { 0x4ac94a4a, 0000000000 }, -- { 0xcc898989, 0000000000 }, -- { 0xc34ad3c5, 0000000000 }, -- { 0x8e4a4a4a, 0000000000 }, -- { 0x4a8a8a8a, 0000000000 }, -- { 0x4a0f8c4a, 0000000000 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000d0012, 0x00000038 }, -- { 0x0000e8b4, 0x00000004 }, -- { 0x000d0014, 0x00000038 }, -- { 0x0000e8b6, 0x00000004 }, -- { 0x000d0016, 0x00000038 }, -- { 0x0000e854, 0x00000004 }, -- { 0x000d0018, 0x00000038 }, -- { 0x0000e855, 0x00000004 }, -- { 0x000d001a, 0x00000038 }, -- { 0x0000e856, 0x00000004 }, -- { 0x000d001c, 0x00000038 }, -- { 0x0000e857, 0x00000004 }, -- { 0x000d001e, 0x00000038 }, -- { 0x0000e824, 0x00000004 }, -- { 0x000d0020, 0x00000038 }, -- { 0x0000e825, 0x00000004 }, -- { 0x000d0022, 0x00000038 }, -- { 0x0000e830, 0x00000004 }, -- { 0x000d0024, 0x00000038 }, -- { 0x0000f0c0, 0x00000004 }, -- { 0x000d0026, 0x00000038 }, -- { 0x0000f0c1, 0x00000004 }, -- { 0x000d0028, 0x00000038 }, -- { 0x0000f041, 0x00000004 }, -- { 0x000d002a, 0x00000038 }, -- { 0x0000f184, 0x00000004 }, -- { 0x000d002c, 0x00000038 }, -- { 0x0000f185, 0x00000004 }, -- { 0x000d002e, 0x00000038 }, -- { 0x0000f186, 0x00000004 }, -- { 0x000d0030, 0x00000038 }, -- { 0x0000f187, 0x00000004 }, -- { 0x000d0032, 0x00000038 }, -- { 0x0000f180, 0x00000004 }, -- { 0x000d0034, 0x00000038 }, -- { 0x0000f393, 0x00000004 }, -- { 0x000d0036, 0x00000038 }, -- { 0x0000f38a, 0x00000004 }, -- { 0x000d0038, 0x00000038 }, -- { 0x0000f38e, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000043, 0x00000018 }, -- { 0x00cce800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x0000003a, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x2000451d, 0x00000004 }, -- { 0x0000e580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x08004580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x00000047, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x00032000, 0x00000004 }, -- { 0x00022051, 0x00000028 }, -- { 0x00000051, 0x00000024 }, -- { 0x0800450f, 0x00000004 }, -- { 0x0000a04b, 0x00000008 }, -- { 0x0000e565, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000052, 0x00000008 }, -- { 0x03cca5b4, 0x00000004 }, -- { 0x05432000, 0x00000004 }, -- { 0x00022000, 0x00000004 }, -- { 0x4ccce05e, 0x00000030 }, -- { 0x08274565, 0x00000004 }, -- { 0x0000005e, 0x00000030 }, -- { 0x08004564, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000055, 0x00000008 }, -- { 0x00802061, 0x00000010 }, -- { 0x00202000, 0x00000004 }, -- { 0x001b00ff, 0x00000004 }, -- { 0x01000064, 0x00000010 }, -- { 0x001f2000, 0x00000004 }, -- { 0x001c00ff, 0x00000004 }, -- { 0000000000, 0x0000000c }, -- { 0x00000072, 0x00000030 }, -- { 0x00000055, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x0000e577, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x0000e50f, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000069, 0x00000018 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000069, 0x00000008 }, -- { 0x0014e50e, 0x00000004 }, -- { 0x0040e50f, 0x00000004 }, -- { 0x00c0006c, 0x00000008 }, -- { 0x0000e570, 0x00000004 }, -- { 0x0000e571, 0x00000004 }, -- { 0x0000e572, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x0000e568, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00000076, 0x00000018 }, -- { 0x000b0000, 0x00000004 }, -- { 0x18c0e562, 0x00000004 }, -- { 0x00000078, 0x00000008 }, -- { 0x00c00077, 0x00000008 }, -- { 0x000700cb, 0x00000004 }, -- { 0x00000084, 0x00000038 }, -- { 0x000ca086, 0x00000030 }, -- { 0x080045bb, 0x00000004 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0800e5bc, 0000000000 }, -- { 0x0000e5bb, 0x00000004 }, -- { 0x0000e5bc, 0000000000 }, -- { 0x00120000, 0x0000000c }, -- { 0x00120000, 0x00000004 }, -- { 0x001b0002, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e800, 0000000000 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e82e, 0000000000 }, -- { 0x02cca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000ce1cc, 0x00000004 }, -- { 0x050de1cd, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x00000096, 0x00000018 }, -- { 0x00c0a000, 0x00000004 }, -- { 0x00000093, 0x00000008 }, -- { 0x00000098, 0x00000020 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000009f, 0x00000038 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00160000, 0x00000004 }, -- { 0x700ce000, 0x00000004 }, -- { 0x0014009b, 0x00000008 }, -- { 0x4000e000, 0000000000 }, -- { 0x02400000, 0x00000004 }, -- { 0x400ee000, 0x00000004 }, -- { 0x02400000, 0x00000004 }, -- { 0x4000e000, 0000000000 }, -- { 0x00100000, 0x0000002c }, -- { 0x00004000, 0000000000 }, -- { 0x080045c8, 0x00000004 }, -- { 0x00240005, 0x00000004 }, -- { 0x08004d0b, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0240e51b, 0x00000004 }, -- { 0x0080e50a, 0x00000005 }, -- { 0x0080e50b, 0x00000005 }, -- { 0x00220000, 0x00000004 }, -- { 0x000700cb, 0x00000004 }, -- { 0x000000b7, 0x00000038 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0880e5bd, 0x00000005 }, -- { 0x000c2086, 0x00000030 }, -- { 0x0800e5bb, 0x00000005 }, -- { 0x000c2087, 0x00000030 }, -- { 0x0880e5bc, 0x00000005 }, -- { 0x000000ba, 0x00000008 }, -- { 0x0080e5bd, 0x00000005 }, -- { 0x0000e5bb, 0x00000005 }, -- { 0x0080e5bc, 0x00000005 }, -- { 0x00210000, 0x00000004 }, -- { 0x02800000, 0x00000004 }, -- { 0x00c000be, 0x00000018 }, -- { 0x4180e000, 0x00000040 }, -- { 0x000000c0, 0x00000024 }, -- { 0x01000000, 0x0000000c }, -- { 0x0100e51d, 0x0000000c }, -- { 0x000045bb, 0x00000004 }, -- { 0x000080ba, 0x00000008 }, -- { 0x03c00830, 0x00000004 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x200045e0, 0x00000004 }, -- { 0x0000e5e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000700c8, 0x00000004 }, -- { 0x0800e394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x0000e8c4, 0x00000004 }, -- { 0x0000e8c5, 0x00000004 }, -- { 0x0000e8c6, 0x00000004 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000cc, 0x00000008 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000d3, 0x00000008 }, -- { 0x02c02000, 0x00000004 }, -- { 0x00060000, 0x00000004 }, -- { 0x000000db, 0x00000034 }, -- { 0x000000d8, 0x00000008 }, -- { 0x00008000, 0x00000004 }, -- { 0xc000e000, 0000000000 }, -- { 0x000000e1, 0x00000030 }, -- { 0x4200e000, 0000000000 }, -- { 0x000000e1, 0x00000030 }, -- { 0x4000e000, 0000000000 }, -- { 0x0025001b, 0x00000004 }, -- { 0x00230000, 0x00000004 }, -- { 0x00250005, 0x00000004 }, -- { 0x000000e6, 0x00000034 }, -- { 0000000000, 0x0000000c }, -- { 0x00244000, 0x00000004 }, -- { 0x080045c8, 0x00000004 }, -- { 0x00240005, 0x00000004 }, -- { 0x08004d0b, 0x0000000c }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x001d0018, 0x00000004 }, -- { 0x001a0001, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0x0500a04a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- --static const u32 R520_cp_microcode[][2] = { -- { 0x4200e000, 0000000000 }, -- { 0x4000e000, 0000000000 }, -- { 0x00000099, 0x00000008 }, -- { 0x0000009d, 0x00000008 }, -- { 0x4a554b4a, 0000000000 }, -- { 0x4a4a4467, 0000000000 }, -- { 0x55526f75, 0000000000 }, -- { 0x4a7e7d65, 0000000000 }, -- { 0xe0dae6f6, 0000000000 }, -- { 0x4ac54a4a, 0000000000 }, -- { 0xc8828282, 0000000000 }, -- { 0xbf4acfc1, 0000000000 }, -- { 0x87b04ad5, 0000000000 }, -- { 0xb5838383, 0000000000 }, -- { 0x4a0f85ba, 0000000000 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000d0012, 0x00000038 }, -- { 0x0000e8b4, 0x00000004 }, -- { 0x000d0014, 0x00000038 }, -- { 0x0000e8b6, 0x00000004 }, -- { 0x000d0016, 0x00000038 }, -- { 0x0000e854, 0x00000004 }, -- { 0x000d0018, 0x00000038 }, -- { 0x0000e855, 0x00000004 }, -- { 0x000d001a, 0x00000038 }, -- { 0x0000e856, 0x00000004 }, -- { 0x000d001c, 0x00000038 }, -- { 0x0000e857, 0x00000004 }, -- { 0x000d001e, 0x00000038 }, -- { 0x0000e824, 0x00000004 }, -- { 0x000d0020, 0x00000038 }, -- { 0x0000e825, 0x00000004 }, -- { 0x000d0022, 0x00000038 }, -- { 0x0000e830, 0x00000004 }, -- { 0x000d0024, 0x00000038 }, -- { 0x0000f0c0, 0x00000004 }, -- { 0x000d0026, 0x00000038 }, -- { 0x0000f0c1, 0x00000004 }, -- { 0x000d0028, 0x00000038 }, -- { 0x0000e000, 0x00000004 }, -- { 0x000d002a, 0x00000038 }, -- { 0x0000e000, 0x00000004 }, -- { 0x000d002c, 0x00000038 }, -- { 0x0000e000, 0x00000004 }, -- { 0x000d002e, 0x00000038 }, -- { 0x0000e000, 0x00000004 }, -- { 0x000d0030, 0x00000038 }, -- { 0x0000e000, 0x00000004 }, -- { 0x000d0032, 0x00000038 }, -- { 0x0000f180, 0x00000004 }, -- { 0x000d0034, 0x00000038 }, -- { 0x0000f393, 0x00000004 }, -- { 0x000d0036, 0x00000038 }, -- { 0x0000f38a, 0x00000004 }, -- { 0x000d0038, 0x00000038 }, -- { 0x0000f38e, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000043, 0x00000018 }, -- { 0x00cce800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x08004800, 0x00000004 }, -- { 0x0000003a, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x2000451d, 0x00000004 }, -- { 0x0000e580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x08004580, 0x00000004 }, -- { 0x000ce581, 0x00000004 }, -- { 0x00000047, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x00032000, 0x00000004 }, -- { 0x00022051, 0x00000028 }, -- { 0x00000051, 0x00000024 }, -- { 0x0800450f, 0x00000004 }, -- { 0x0000a04b, 0x00000008 }, -- { 0x0000e565, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000052, 0x00000008 }, -- { 0x03cca5b4, 0x00000004 }, -- { 0x05432000, 0x00000004 }, -- { 0x00022000, 0x00000004 }, -- { 0x4ccce05e, 0x00000030 }, -- { 0x08274565, 0x00000004 }, -- { 0x0000005e, 0x00000030 }, -- { 0x08004564, 0x00000004 }, -- { 0x0000e566, 0x00000004 }, -- { 0x00000055, 0x00000008 }, -- { 0x00802061, 0x00000010 }, -- { 0x00202000, 0x00000004 }, -- { 0x001b00ff, 0x00000004 }, -- { 0x01000064, 0x00000010 }, -- { 0x001f2000, 0x00000004 }, -- { 0x001c00ff, 0x00000004 }, -- { 0000000000, 0x0000000c }, -- { 0x00000072, 0x00000030 }, -- { 0x00000055, 0x00000008 }, -- { 0x0000e576, 0x00000004 }, -- { 0x0000e577, 0x00000004 }, -- { 0x0000e50e, 0x00000004 }, -- { 0x0000e50f, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00000069, 0x00000018 }, -- { 0x00c0e5f9, 0x000000c2 }, -- { 0x00000069, 0x00000008 }, -- { 0x0014e50e, 0x00000004 }, -- { 0x0040e50f, 0x00000004 }, -- { 0x00c0006c, 0x00000008 }, -- { 0x0000e570, 0x00000004 }, -- { 0x0000e571, 0x00000004 }, -- { 0x0000e572, 0x0000000c }, -- { 0x0000a000, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x0000e568, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00000076, 0x00000018 }, -- { 0x000b0000, 0x00000004 }, -- { 0x18c0e562, 0x00000004 }, -- { 0x00000078, 0x00000008 }, -- { 0x00c00077, 0x00000008 }, -- { 0x000700c7, 0x00000004 }, -- { 0x00000080, 0x00000038 }, -- { 0x0000e5bb, 0x00000004 }, -- { 0x0000e5bc, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e800, 0000000000 }, -- { 0x0000e821, 0x00000004 }, -- { 0x0000e82e, 0000000000 }, -- { 0x02cca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000ce1cc, 0x00000004 }, -- { 0x050de1cd, 0x00000004 }, -- { 0x00400000, 0x00000004 }, -- { 0x0000008f, 0x00000018 }, -- { 0x00c0a000, 0x00000004 }, -- { 0x0000008c, 0x00000008 }, -- { 0x00000091, 0x00000020 }, -- { 0x4200e000, 0000000000 }, -- { 0x00000098, 0x00000038 }, -- { 0x000ca000, 0x00000004 }, -- { 0x00140000, 0x00000004 }, -- { 0x000c2000, 0x00000004 }, -- { 0x00160000, 0x00000004 }, -- { 0x700ce000, 0x00000004 }, -- { 0x00140094, 0x00000008 }, -- { 0x4000e000, 0000000000 }, -- { 0x02400000, 0x00000004 }, -- { 0x400ee000, 0x00000004 }, -- { 0x02400000, 0x00000004 }, -- { 0x4000e000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x0240e51b, 0x00000004 }, -- { 0x0080e50a, 0x00000005 }, -- { 0x0080e50b, 0x00000005 }, -- { 0x00220000, 0x00000004 }, -- { 0x000700c7, 0x00000004 }, -- { 0x000000a4, 0x00000038 }, -- { 0x0080e5bd, 0x00000005 }, -- { 0x0000e5bb, 0x00000005 }, -- { 0x0080e5bc, 0x00000005 }, -- { 0x00210000, 0x00000004 }, -- { 0x02800000, 0x00000004 }, -- { 0x00c000ab, 0x00000018 }, -- { 0x4180e000, 0x00000040 }, -- { 0x000000ad, 0x00000024 }, -- { 0x01000000, 0x0000000c }, -- { 0x0100e51d, 0x0000000c }, -- { 0x000045bb, 0x00000004 }, -- { 0x000080a7, 0x00000008 }, -- { 0x0000f3ce, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053cf, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f3d2, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c053d3, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x0000f39d, 0x00000004 }, -- { 0x0140a000, 0x00000004 }, -- { 0x00cc2000, 0x00000004 }, -- { 0x08c0539e, 0x00000040 }, -- { 0x00008000, 0000000000 }, -- { 0x03c00830, 0x00000004 }, -- { 0x4200e000, 0000000000 }, -- { 0x0000a000, 0x00000004 }, -- { 0x200045e0, 0x00000004 }, -- { 0x0000e5e1, 0000000000 }, -- { 0x00000001, 0000000000 }, -- { 0x000700c4, 0x00000004 }, -- { 0x0800e394, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x0000e8c4, 0x00000004 }, -- { 0x0000e8c5, 0x00000004 }, -- { 0x0000e8c6, 0x00000004 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000c8, 0x00000008 }, -- { 0x0000e928, 0x00000004 }, -- { 0x0000e929, 0x00000004 }, -- { 0x0000e92a, 0x00000004 }, -- { 0x000000cf, 0x00000008 }, -- { 0xdeadbeef, 0000000000 }, -- { 0x00000116, 0000000000 }, -- { 0x000700d3, 0x00000004 }, -- { 0x080050e7, 0x00000004 }, -- { 0x000700d4, 0x00000004 }, -- { 0x0800401c, 0x00000004 }, -- { 0x0000e01d, 0000000000 }, -- { 0x02c02000, 0x00000004 }, -- { 0x00060000, 0x00000004 }, -- { 0x000000de, 0x00000034 }, -- { 0x000000db, 0x00000008 }, -- { 0x00008000, 0x00000004 }, -- { 0xc000e000, 0000000000 }, -- { 0x0000e1cc, 0x00000004 }, -- { 0x0500e1cd, 0x00000004 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000000e5, 0x00000034 }, -- { 0x000000e1, 0x00000008 }, -- { 0x0000a000, 0000000000 }, -- { 0x0019e1cc, 0x00000004 }, -- { 0x001b0001, 0x00000004 }, -- { 0x0500a000, 0x00000004 }, -- { 0x080041cd, 0x00000004 }, -- { 0x000ca000, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0x000c2000, 0x00000004 }, -- { 0x001d0018, 0x00000004 }, -- { 0x001a0001, 0x00000004 }, -- { 0x000000fb, 0x00000034 }, -- { 0x0000004a, 0x00000008 }, -- { 0x0500a04a, 0x00000008 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, -- { 0000000000, 0000000000 }, --}; -- -- --#endif -diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h -index 3b09a1f..523d6cb 100644 ---- a/drivers/gpu/drm/radeon/radeon_mode.h -+++ b/drivers/gpu/drm/radeon/radeon_mode.h -@@ -188,6 +188,21 @@ struct radeon_native_mode { - uint32_t flags; - }; - -+#define MAX_H_CODE_TIMING_LEN 32 -+#define MAX_V_CODE_TIMING_LEN 32 -+ -+/* need to store these as reading -+ back code tables is excessive */ -+struct radeon_tv_regs { -+ uint32_t tv_uv_adr; -+ uint32_t timing_cntl; -+ uint32_t hrestart; -+ uint32_t vrestart; -+ uint32_t frestart; -+ uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN]; -+ uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; -+}; -+ - struct radeon_crtc { - struct drm_crtc base; - int crtc_id; -@@ -195,8 +210,6 @@ struct radeon_crtc { - bool enabled; - bool can_tile; - uint32_t crtc_offset; -- struct radeon_framebuffer *fbdev_fb; -- struct drm_mode_set mode_set; - struct drm_gem_object *cursor_bo; - uint64_t cursor_addr; - int cursor_width; -@@ -204,7 +217,6 @@ struct radeon_crtc { - uint32_t legacy_display_base_addr; - uint32_t legacy_cursor_offset; - enum radeon_rmx_type rmx_type; -- uint32_t devices; - fixed20_12 vsc; - fixed20_12 hsc; - struct radeon_native_mode native_mode; -@@ -236,7 +248,13 @@ struct radeon_encoder_tv_dac { - uint32_t ntsc_tvdac_adj; - uint32_t pal_tvdac_adj; - -+ int h_pos; -+ int v_pos; -+ int h_size; -+ int supported_tv_stds; -+ bool tv_on; - enum radeon_tv_std tv_std; -+ struct radeon_tv_regs tv; - }; - - struct radeon_encoder_int_tmds { -@@ -255,10 +273,15 @@ struct radeon_encoder_atom_dig { - struct radeon_native_mode native_mode; - }; - -+struct radeon_encoder_atom_dac { -+ enum radeon_tv_std tv_std; -+}; -+ - struct radeon_encoder { - struct drm_encoder base; - uint32_t encoder_id; - uint32_t devices; -+ uint32_t active_device; - uint32_t flags; - uint32_t pixel_clock; - enum radeon_rmx_type rmx_type; -@@ -276,7 +299,10 @@ struct radeon_connector { - uint32_t connector_id; - uint32_t devices; - struct radeon_i2c_chan *ddc_bus; -- int use_digital; -+ bool use_digital; -+ /* we need to mind the EDID between detect -+ and get modes due to analog/digital/tvencoder */ -+ struct edid *edid; - void *con_priv; - }; - -@@ -310,6 +336,7 @@ struct drm_encoder *radeon_encoder_legacy_tmds_int_add(struct drm_device *dev, i - struct drm_encoder *radeon_encoder_legacy_tmds_ext_add(struct drm_device *dev, int bios_index); - extern void atombios_external_tmds_setup(struct drm_encoder *encoder, int action); - extern int atombios_get_encoder_mode(struct drm_encoder *encoder); -+extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); - - extern void radeon_crtc_load_lut(struct drm_crtc *crtc); - extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, -@@ -396,6 +423,19 @@ extern int radeon_static_clocks_init(struct drm_device *dev); - bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); --void atom_rv515_force_tv_scaler(struct radeon_device *rdev); -- -+void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *radeon_crtc); -+ -+/* legacy tv */ -+void radeon_legacy_tv_adjust_crtc_reg(struct drm_encoder *encoder, -+ uint32_t *h_total_disp, uint32_t *h_sync_strt_wid, -+ uint32_t *v_total_disp, uint32_t *v_sync_strt_wid); -+void radeon_legacy_tv_adjust_pll1(struct drm_encoder *encoder, -+ uint32_t *htotal_cntl, uint32_t *ppll_ref_div, -+ uint32_t *ppll_div_3, uint32_t *pixclks_cntl); -+void radeon_legacy_tv_adjust_pll2(struct drm_encoder *encoder, -+ uint32_t *htotal2_cntl, uint32_t *p2pll_ref_div, -+ uint32_t *p2pll_div_0, uint32_t *pixclks_cntl); -+void radeon_legacy_tv_mode_set(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode); - #endif -diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h -index 473e477..10e8af6 100644 ---- a/drivers/gpu/drm/radeon/radeon_object.h -+++ b/drivers/gpu/drm/radeon/radeon_object.h -@@ -37,6 +37,7 @@ - * TTM. - */ - struct radeon_mman { -+ struct ttm_bo_global_ref bo_global_ref; - struct ttm_global_reference mem_global_ref; - bool mem_global_referenced; - struct ttm_bo_device bdev; -diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h -index 4df43f6..21da871 100644 ---- a/drivers/gpu/drm/radeon/radeon_reg.h -+++ b/drivers/gpu/drm/radeon/radeon_reg.h -@@ -1945,6 +1945,11 @@ - # define RADEON_TXFORMAT_DXT1 (12 << 0) - # define RADEON_TXFORMAT_DXT23 (14 << 0) - # define RADEON_TXFORMAT_DXT45 (15 << 0) -+# define RADEON_TXFORMAT_SHADOW16 (16 << 0) -+# define RADEON_TXFORMAT_SHADOW32 (17 << 0) -+# define RADEON_TXFORMAT_DUDV88 (18 << 0) -+# define RADEON_TXFORMAT_LDUDV655 (19 << 0) -+# define RADEON_TXFORMAT_LDUDUV8888 (20 << 0) - # define RADEON_TXFORMAT_FORMAT_MASK (31 << 0) - # define RADEON_TXFORMAT_FORMAT_SHIFT 0 - # define RADEON_TXFORMAT_APPLE_YUV_MODE (1 << 5) -@@ -2203,7 +2208,7 @@ - # define RADEON_ROP_ENABLE (1 << 6) - # define RADEON_STENCIL_ENABLE (1 << 7) - # define RADEON_Z_ENABLE (1 << 8) --# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) -+# define RADEON_DEPTHXY_OFFSET_ENABLE (1 << 9) - # define RADEON_RB3D_COLOR_FORMAT_SHIFT 10 - - # define RADEON_COLOR_FORMAT_ARGB1555 3 -@@ -2773,7 +2778,12 @@ - # define R200_TXFORMAT_DXT1 (12 << 0) - # define R200_TXFORMAT_DXT23 (14 << 0) - # define R200_TXFORMAT_DXT45 (15 << 0) -+# define R200_TXFORMAT_DVDU88 (18 << 0) -+# define R200_TXFORMAT_LDVDU655 (19 << 0) -+# define R200_TXFORMAT_LDVDU8888 (20 << 0) -+# define R200_TXFORMAT_GR1616 (21 << 0) - # define R200_TXFORMAT_ABGR8888 (22 << 0) -+# define R200_TXFORMAT_BGR111110 (23 << 0) - # define R200_TXFORMAT_FORMAT_MASK (31 << 0) - # define R200_TXFORMAT_FORMAT_SHIFT 0 - # define R200_TXFORMAT_ALPHA_IN_MAP (1 << 6) -@@ -2818,6 +2828,13 @@ - #define R200_PP_TXPITCH_4 0x2c90 /* NPOT only */ - #define R200_PP_TXPITCH_5 0x2cb0 /* NPOT only */ - -+#define R200_PP_CUBIC_FACES_0 0x2c18 -+#define R200_PP_CUBIC_FACES_1 0x2c38 -+#define R200_PP_CUBIC_FACES_2 0x2c58 -+#define R200_PP_CUBIC_FACES_3 0x2c78 -+#define R200_PP_CUBIC_FACES_4 0x2c98 -+#define R200_PP_CUBIC_FACES_5 0x2cb8 -+ - #define R200_PP_TXOFFSET_0 0x2d00 - # define R200_TXO_ENDIAN_NO_SWAP (0 << 0) - # define R200_TXO_ENDIAN_BYTE_SWAP (1 << 0) -@@ -2829,11 +2846,44 @@ - # define R200_TXO_MICRO_TILE (1 << 3) - # define R200_TXO_OFFSET_MASK 0xffffffe0 - # define R200_TXO_OFFSET_SHIFT 5 -+#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04 -+#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08 -+#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c -+#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10 -+#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14 -+ - #define R200_PP_TXOFFSET_1 0x2d18 -+#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c -+#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20 -+#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24 -+#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28 -+#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c -+ - #define R200_PP_TXOFFSET_2 0x2d30 -+#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34 -+#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38 -+#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c -+#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40 -+#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44 -+ - #define R200_PP_TXOFFSET_3 0x2d48 -+#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c -+#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50 -+#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54 -+#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58 -+#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c - #define R200_PP_TXOFFSET_4 0x2d60 -+#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64 -+#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68 -+#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c -+#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70 -+#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74 - #define R200_PP_TXOFFSET_5 0x2d78 -+#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c -+#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80 -+#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84 -+#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88 -+#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c - - #define R200_PP_TFACTOR_0 0x2ee0 - #define R200_PP_TFACTOR_1 0x2ee4 -@@ -3175,6 +3225,11 @@ - # define R200_FORCE_INORDER_PROC (1<<31) - #define R200_PP_CNTL_X 0x2cc4 - #define R200_PP_TXMULTI_CTL_0 0x2c1c -+#define R200_PP_TXMULTI_CTL_1 0x2c3c -+#define R200_PP_TXMULTI_CTL_2 0x2c5c -+#define R200_PP_TXMULTI_CTL_3 0x2c7c -+#define R200_PP_TXMULTI_CTL_4 0x2c9c -+#define R200_PP_TXMULTI_CTL_5 0x2cbc - #define R200_SE_VTX_STATE_CNTL 0x2180 - # define R200_UPDATE_USER_COLOR_0_ENA_MASK (1<<16) - -@@ -3200,6 +3255,24 @@ - #define RADEON_CP_RB_WPTR 0x0714 - #define RADEON_CP_RB_RPTR_WR 0x071c - -+#define RADEON_SCRATCH_UMSK 0x0770 -+#define RADEON_SCRATCH_ADDR 0x0774 -+ -+#define R600_CP_RB_BASE 0xc100 -+#define R600_CP_RB_CNTL 0xc104 -+# define R600_RB_BUFSZ(x) ((x) << 0) -+# define R600_RB_BLKSZ(x) ((x) << 8) -+# define R600_RB_NO_UPDATE (1 << 27) -+# define R600_RB_RPTR_WR_ENA (1 << 31) -+#define R600_CP_RB_RPTR_WR 0xc108 -+#define R600_CP_RB_RPTR_ADDR 0xc10c -+#define R600_CP_RB_RPTR_ADDR_HI 0xc110 -+#define R600_CP_RB_WPTR 0xc114 -+#define R600_CP_RB_WPTR_ADDR 0xc118 -+#define R600_CP_RB_WPTR_ADDR_HI 0xc11c -+#define R600_CP_RB_RPTR 0x8700 -+#define R600_CP_RB_WPTR_DELAY 0x8704 -+ - #define RADEON_CP_IB_BASE 0x0738 - #define RADEON_CP_IB_BUFSZ 0x073c - -@@ -3407,7 +3480,9 @@ - # define RADEON_RGB_CONVERT_BY_PASS (1 << 10) - # define RADEON_UVRAM_READ_MARGIN_SHIFT 16 - # define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT 20 --# define RADEON_TVOUT_SCALE_EN (1 << 26) -+# define RADEON_RGB_ATTEN_SEL(x) ((x) << 24) -+# define RADEON_TVOUT_SCALE_EN (1 << 26) -+# define RADEON_RGB_ATTEN_VAL(x) ((x) << 28) - #define RADEON_TV_SYNC_CNTL 0x0808 - # define RADEON_SYNC_OE (1 << 0) - # define RADEON_SYNC_OUT (1 << 1) -diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c -index 60d1593..aa9837a 100644 ---- a/drivers/gpu/drm/radeon/radeon_ring.c -+++ b/drivers/gpu/drm/radeon/radeon_ring.c -@@ -110,7 +110,6 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) - return; - } - list_del(&tmp->list); -- INIT_LIST_HEAD(&tmp->list); - if (tmp->fence) { - radeon_fence_unref(&tmp->fence); - } -@@ -119,19 +118,11 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) - mutex_unlock(&rdev->ib_pool.mutex); - } - --static void radeon_ib_align(struct radeon_device *rdev, struct radeon_ib *ib) --{ -- while ((ib->length_dw & rdev->cp.align_mask)) { -- ib->ptr[ib->length_dw++] = PACKET2(0); -- } --} -- - int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) - { - int r = 0; - - mutex_lock(&rdev->ib_pool.mutex); -- radeon_ib_align(rdev, ib); - if (!ib->length_dw || !rdev->cp.ready) { - /* TODO: Nothings in the ib we should report. */ - mutex_unlock(&rdev->ib_pool.mutex); -@@ -145,9 +136,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) - mutex_unlock(&rdev->ib_pool.mutex); - return r; - } -- radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); -- radeon_ring_write(rdev, ib->gpu_addr); -- radeon_ring_write(rdev, ib->length_dw); -+ radeon_ring_ib_execute(rdev, ib); - radeon_fence_emit(rdev, ib->fence); - radeon_ring_unlock_commit(rdev); - list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); -@@ -215,69 +204,16 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) - mutex_unlock(&rdev->ib_pool.mutex); - } - --int radeon_ib_test(struct radeon_device *rdev) --{ -- struct radeon_ib *ib; -- uint32_t scratch; -- uint32_t tmp = 0; -- unsigned i; -- int r; -- -- r = radeon_scratch_get(rdev, &scratch); -- if (r) { -- DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); -- return r; -- } -- WREG32(scratch, 0xCAFEDEAD); -- r = radeon_ib_get(rdev, &ib); -- if (r) { -- return r; -- } -- ib->ptr[0] = PACKET0(scratch, 0); -- ib->ptr[1] = 0xDEADBEEF; -- ib->ptr[2] = PACKET2(0); -- ib->ptr[3] = PACKET2(0); -- ib->ptr[4] = PACKET2(0); -- ib->ptr[5] = PACKET2(0); -- ib->ptr[6] = PACKET2(0); -- ib->ptr[7] = PACKET2(0); -- ib->length_dw = 8; -- r = radeon_ib_schedule(rdev, ib); -- if (r) { -- radeon_scratch_free(rdev, scratch); -- radeon_ib_free(rdev, &ib); -- return r; -- } -- r = radeon_fence_wait(ib->fence, false); -- if (r) { -- return r; -- } -- for (i = 0; i < rdev->usec_timeout; i++) { -- tmp = RREG32(scratch); -- if (tmp == 0xDEADBEEF) { -- break; -- } -- DRM_UDELAY(1); -- } -- if (i < rdev->usec_timeout) { -- DRM_INFO("ib test succeeded in %u usecs\n", i); -- } else { -- DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n", -- scratch, tmp); -- r = -EINVAL; -- } -- radeon_scratch_free(rdev, scratch); -- radeon_ib_free(rdev, &ib); -- return r; --} -- - - /* - * Ring. - */ - void radeon_ring_free_size(struct radeon_device *rdev) - { -- rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); -+ if (rdev->family >= CHIP_R600) -+ rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); -+ else -+ rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); - /* This works because ring_size is a power of 2 */ - rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); - rdev->cp.ring_free_dw -= rdev->cp.wptr; -@@ -320,11 +256,10 @@ void radeon_ring_unlock_commit(struct radeon_device *rdev) - count_dw_pad = (rdev->cp.align_mask + 1) - - (rdev->cp.wptr & rdev->cp.align_mask); - for (i = 0; i < count_dw_pad; i++) { -- radeon_ring_write(rdev, PACKET2(0)); -+ radeon_ring_write(rdev, 2 << 30); - } - DRM_MEMORYBARRIER(); -- WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); -- (void)RREG32(RADEON_CP_RB_WPTR); -+ radeon_cp_commit(rdev); - mutex_unlock(&rdev->cp.mutex); - } - -@@ -334,46 +269,6 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev) - mutex_unlock(&rdev->cp.mutex); - } - --int radeon_ring_test(struct radeon_device *rdev) --{ -- uint32_t scratch; -- uint32_t tmp = 0; -- unsigned i; -- int r; -- -- r = radeon_scratch_get(rdev, &scratch); -- if (r) { -- DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); -- return r; -- } -- WREG32(scratch, 0xCAFEDEAD); -- r = radeon_ring_lock(rdev, 2); -- if (r) { -- DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); -- radeon_scratch_free(rdev, scratch); -- return r; -- } -- radeon_ring_write(rdev, PACKET0(scratch, 0)); -- radeon_ring_write(rdev, 0xDEADBEEF); -- radeon_ring_unlock_commit(rdev); -- for (i = 0; i < rdev->usec_timeout; i++) { -- tmp = RREG32(scratch); -- if (tmp == 0xDEADBEEF) { -- break; -- } -- DRM_UDELAY(1); -- } -- if (i < rdev->usec_timeout) { -- DRM_INFO("ring test succeeded in %d usecs\n", i); -- } else { -- DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", -- scratch, tmp); -- r = -EINVAL; -- } -- radeon_scratch_free(rdev, scratch); -- return r; --} -- - int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) - { - int r; -diff --git a/drivers/gpu/drm/radeon/radeon_share.h b/drivers/gpu/drm/radeon/radeon_share.h -index 63a7735..5f9e358 100644 ---- a/drivers/gpu/drm/radeon/radeon_share.h -+++ b/drivers/gpu/drm/radeon/radeon_share.h -@@ -28,12 +28,89 @@ - #ifndef __RADEON_SHARE_H__ - #define __RADEON_SHARE_H__ - -+/* Common */ -+struct radeon_device; -+struct radeon_cs_parser; -+int radeon_clocks_init(struct radeon_device *rdev); -+void radeon_clocks_fini(struct radeon_device *rdev); -+void radeon_scratch_init(struct radeon_device *rdev); -+void radeon_surface_init(struct radeon_device *rdev); -+int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); -+ -+ -+/* R100, RV100, RS100, RV200, RS200, R200, RV250, RS300, RV280 */ - void r100_vram_init_sizes(struct radeon_device *rdev); - -+ -+/* R300, R350, RV350, RV380 */ -+struct r300_asic { -+ const unsigned *reg_safe_bm; -+ unsigned reg_safe_bm_size; -+}; -+ -+ -+/* RS690, RS740 */ - void rs690_line_buffer_adjust(struct radeon_device *rdev, - struct drm_display_mode *mode1, - struct drm_display_mode *mode2); - -+ -+/* RV515 */ - void rv515_bandwidth_avivo_update(struct radeon_device *rdev); - -+ -+/* R600, RV610, RV630, RV620, RV635, RV670, RS780, RS880 */ -+bool r600_card_posted(struct radeon_device *rdev); -+void r600_cp_stop(struct radeon_device *rdev); -+void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); -+int r600_cp_resume(struct radeon_device *rdev); -+int r600_count_pipe_bits(uint32_t val); -+int r600_gart_clear_page(struct radeon_device *rdev, int i); -+int r600_mc_wait_for_idle(struct radeon_device *rdev); -+void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); -+int r600_ib_test(struct radeon_device *rdev); -+int r600_ring_test(struct radeon_device *rdev); -+int r600_wb_init(struct radeon_device *rdev); -+void r600_wb_fini(struct radeon_device *rdev); -+void r600_scratch_init(struct radeon_device *rdev); -+int r600_blit_init(struct radeon_device *rdev); -+void r600_blit_fini(struct radeon_device *rdev); -+int r600_cp_init_microcode(struct radeon_device *rdev); -+struct r600_asic { -+ unsigned max_pipes; -+ unsigned max_tile_pipes; -+ unsigned max_simds; -+ unsigned max_backends; -+ unsigned max_gprs; -+ unsigned max_threads; -+ unsigned max_stack_entries; -+ unsigned max_hw_contexts; -+ unsigned max_gs_threads; -+ unsigned sx_max_export_size; -+ unsigned sx_max_export_pos_size; -+ unsigned sx_max_export_smx_size; -+ unsigned sq_num_cf_insts; -+}; -+ -+/* RV770, RV7300, RV710 */ -+struct rv770_asic { -+ unsigned max_pipes; -+ unsigned max_tile_pipes; -+ unsigned max_simds; -+ unsigned max_backends; -+ unsigned max_gprs; -+ unsigned max_threads; -+ unsigned max_stack_entries; -+ unsigned max_hw_contexts; -+ unsigned max_gs_threads; -+ unsigned sx_max_export_size; -+ unsigned sx_max_export_pos_size; -+ unsigned sx_max_export_smx_size; -+ unsigned sq_num_cf_insts; -+ unsigned sx_num_of_sets; -+ unsigned sc_prim_fifo_size; -+ unsigned sc_hiz_tile_fifo_size; -+ unsigned sc_earlyz_tile_fifo_fize; -+}; -+ - #endif -diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c -index 2882f40..aad0c6f 100644 ---- a/drivers/gpu/drm/radeon/radeon_state.c -+++ b/drivers/gpu/drm/radeon/radeon_state.c -@@ -1546,7 +1546,7 @@ static void radeon_cp_dispatch_vertex(struct drm_device * dev, - } while (i < nbox); - } - --static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) -+void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *master, struct drm_buf *buf) - { - drm_radeon_private_t *dev_priv = dev->dev_private; - struct drm_radeon_master_private *master_priv = master->driver_priv; -@@ -2213,7 +2213,10 @@ static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *f - if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS) - sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; - -- radeon_cp_dispatch_swap(dev, file_priv->master); -+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) -+ r600_cp_dispatch_swap(dev, file_priv); -+ else -+ radeon_cp_dispatch_swap(dev, file_priv->master); - sarea_priv->ctx_owner = 0; - - COMMIT_RING(); -@@ -2412,7 +2415,10 @@ static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file - RING_SPACE_TEST_WITH_RETURN(dev_priv); - VB_AGE_TEST_WITH_RETURN(dev_priv); - -- ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); -+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) -+ ret = r600_cp_dispatch_texture(dev, file_priv, tex, &image); -+ else -+ ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image); - - return ret; - } -@@ -2495,8 +2501,9 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - } - -- if (indirect->discard) -+ if (indirect->discard) { - radeon_cp_discard_buffer(dev, file_priv->master, buf); -+ } - - COMMIT_RING(); - return 0; -@@ -3227,7 +3234,8 @@ struct drm_ioctl_desc radeon_ioctls[] = { - DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), - DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), -- DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH) -+ DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), -+ DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) - }; - - int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); -diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c -index 15c3531..acd889c 100644 ---- a/drivers/gpu/drm/radeon/radeon_ttm.c -+++ b/drivers/gpu/drm/radeon/radeon_ttm.c -@@ -35,11 +35,14 @@ - #include - #include - #include -+#include - #include "radeon_reg.h" - #include "radeon.h" - - #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) - -+static int radeon_ttm_debugfs_init(struct radeon_device *rdev); -+ - static struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) - { - struct radeon_mman *mman; -@@ -77,9 +80,25 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) - global_ref->release = &radeon_ttm_mem_global_release; - r = ttm_global_item_ref(global_ref); - if (r != 0) { -- DRM_ERROR("Failed referencing a global TTM memory object.\n"); -+ DRM_ERROR("Failed setting up TTM memory accounting " -+ "subsystem.\n"); -+ return r; -+ } -+ -+ rdev->mman.bo_global_ref.mem_glob = -+ rdev->mman.mem_global_ref.object; -+ global_ref = &rdev->mman.bo_global_ref.ref; -+ global_ref->global_type = TTM_GLOBAL_TTM_BO; -+ global_ref->size = sizeof(struct ttm_bo_global); -+ global_ref->init = &ttm_bo_global_init; -+ global_ref->release = &ttm_bo_global_release; -+ r = ttm_global_item_ref(global_ref); -+ if (r != 0) { -+ DRM_ERROR("Failed setting up TTM BO subsystem.\n"); -+ ttm_global_item_unref(&rdev->mman.mem_global_ref); - return r; - } -+ - rdev->mman.mem_global_referenced = true; - return 0; - } -@@ -87,6 +106,7 @@ static int radeon_ttm_global_init(struct radeon_device *rdev) - static void radeon_ttm_global_fini(struct radeon_device *rdev) - { - if (rdev->mman.mem_global_referenced) { -+ ttm_global_item_unref(&rdev->mman.bo_global_ref.ref); - ttm_global_item_unref(&rdev->mman.mem_global_ref); - rdev->mman.mem_global_referenced = false; - } -@@ -286,9 +306,11 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, - r = ttm_bo_move_ttm(bo, true, no_wait, new_mem); - out_cleanup: - if (tmp_mem.mm_node) { -- spin_lock(&rdev->mman.bdev.lru_lock); -+ struct ttm_bo_global *glob = rdev->mman.bdev.glob; -+ -+ spin_lock(&glob->lru_lock); - drm_mm_put_block(tmp_mem.mm_node); -- spin_unlock(&rdev->mman.bdev.lru_lock); -+ spin_unlock(&glob->lru_lock); - return r; - } - return r; -@@ -323,9 +345,11 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, - } - out_cleanup: - if (tmp_mem.mm_node) { -- spin_lock(&rdev->mman.bdev.lru_lock); -+ struct ttm_bo_global *glob = rdev->mman.bdev.glob; -+ -+ spin_lock(&glob->lru_lock); - drm_mm_put_block(tmp_mem.mm_node); -- spin_unlock(&rdev->mman.bdev.lru_lock); -+ spin_unlock(&glob->lru_lock); - return r; - } - return r; -@@ -352,9 +376,8 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, - radeon_move_null(bo, new_mem); - return 0; - } -- if (!rdev->cp.ready) { -+ if (!rdev->cp.ready || rdev->asic->copy == NULL) { - /* use memcpy */ -- DRM_ERROR("CP is not ready use memcpy.\n"); - goto memcpy; - } - -@@ -446,7 +469,7 @@ int radeon_ttm_init(struct radeon_device *rdev) - } - /* No others user of address space so set it to 0 */ - r = ttm_bo_device_init(&rdev->mman.bdev, -- rdev->mman.mem_global_ref.object, -+ rdev->mman.bo_global_ref.ref.object, - &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, - rdev->need_dma32); - if (r) { -@@ -471,7 +494,7 @@ int radeon_ttm_init(struct radeon_device *rdev) - return r; - } - DRM_INFO("radeon: %uM of VRAM memory ready\n", -- rdev->mc.real_vram_size / (1024 * 1024)); -+ (unsigned)rdev->mc.real_vram_size / (1024 * 1024)); - r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT, 0, - ((rdev->mc.gtt_size) >> PAGE_SHIFT)); - if (r) { -@@ -479,10 +502,16 @@ int radeon_ttm_init(struct radeon_device *rdev) - return r; - } - DRM_INFO("radeon: %uM of GTT memory ready.\n", -- rdev->mc.gtt_size / (1024 * 1024)); -+ (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); - if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { - rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; - } -+ -+ r = radeon_ttm_debugfs_init(rdev); -+ if (r) { -+ DRM_ERROR("Failed to init debugfs\n"); -+ return r; -+ } - return 0; - } - -@@ -657,3 +686,50 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev) - gtt->bound = false; - return >t->backend; - } -+ -+#define RADEON_DEBUGFS_MEM_TYPES 2 -+ -+static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES]; -+static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32]; -+ -+#if defined(CONFIG_DEBUG_FS) -+static int radeon_mm_dump_table(struct seq_file *m, void *data) -+{ -+ struct drm_info_node *node = (struct drm_info_node *)m->private; -+ struct drm_mm *mm = (struct drm_mm *)node->info_ent->data; -+ struct drm_device *dev = node->minor->dev; -+ struct radeon_device *rdev = dev->dev_private; -+ int ret; -+ struct ttm_bo_global *glob = rdev->mman.bdev.glob; -+ -+ spin_lock(&glob->lru_lock); -+ ret = drm_mm_dump_table(m, mm); -+ spin_unlock(&glob->lru_lock); -+ return ret; -+} -+#endif -+ -+static int radeon_ttm_debugfs_init(struct radeon_device *rdev) -+{ -+ unsigned i; -+ -+#if defined(CONFIG_DEBUG_FS) -+ for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { -+ if (i == 0) -+ sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); -+ else -+ sprintf(radeon_mem_types_names[i], "radeon_gtt_mm"); -+ radeon_mem_types_list[i].name = radeon_mem_types_names[i]; -+ radeon_mem_types_list[i].show = &radeon_mm_dump_table; -+ radeon_mem_types_list[i].driver_features = 0; -+ if (i == 0) -+ radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_VRAM].manager; -+ else -+ radeon_mem_types_list[i].data = &rdev->mman.bdev.man[TTM_PL_TT].manager; -+ -+ } -+ return radeon_debugfs_add_files(rdev, radeon_mem_types_list, RADEON_DEBUGFS_MEM_TYPES); -+ -+#endif -+ return 0; -+} -diff --git a/drivers/gpu/drm/radeon/reg_srcs/r100 b/drivers/gpu/drm/radeon/reg_srcs/r100 -new file mode 100644 -index 0000000..f7ee062 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/r100 -@@ -0,0 +1,105 @@ -+r100 0x3294 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -+0x1810 FOG_3D_TABLE_START -+0x1814 FOG_3D_TABLE_END -+0x1a14 FOG_TABLE_INDEX -+0x1a18 FOG_TABLE_DATA -+0x1c14 PP_MISC -+0x1c18 PP_FOG_COLOR -+0x1c1c RE_SOLID_COLOR -+0x1c20 RB3D_BLENDCNTL -+0x1c4c SE_CNTL -+0x1c50 SE_COORD_FMT -+0x1c60 PP_TXCBLEND_0 -+0x1c64 PP_TXABLEND_0 -+0x1c68 PP_TFACTOR_0 -+0x1c78 PP_TXCBLEND_1 -+0x1c7c PP_TXABLEND_1 -+0x1c80 PP_TFACTOR_1 -+0x1c90 PP_TXCBLEND_2 -+0x1c94 PP_TXABLEND_2 -+0x1c98 PP_TFACTOR_2 -+0x1cc8 RE_STIPPLE_ADDR -+0x1ccc RE_STIPPLE_DATA -+0x1cd0 RE_LINE_PATTERN -+0x1cd4 RE_LINE_STATE -+0x1d40 PP_BORDER_COLOR0 -+0x1d44 PP_BORDER_COLOR1 -+0x1d48 PP_BORDER_COLOR2 -+0x1d7c RB3D_STENCILREFMASK -+0x1d80 RB3D_ROPCNTL -+0x1d84 RB3D_PLANEMASK -+0x1d98 VAP_VPORT_XSCALE -+0x1d9C VAP_VPORT_XOFFSET -+0x1da0 VAP_VPORT_YSCALE -+0x1da4 VAP_VPORT_YOFFSET -+0x1da8 VAP_VPORT_ZSCALE -+0x1dac VAP_VPORT_ZOFFSET -+0x1db0 SE_ZBIAS_FACTOR -+0x1db4 SE_ZBIAS_CONSTANT -+0x1db8 SE_LINE_WIDTH -+0x2140 SE_CNTL_STATUS -+0x2200 SE_TCL_VECTOR_INDX_REG -+0x2204 SE_TCL_VECTOR_DATA_REG -+0x2208 SE_TCL_SCALAR_INDX_REG -+0x220c SE_TCL_SCALAR_DATA_REG -+0x2210 SE_TCL_MATERIAL_EMISSIVE_RED -+0x2214 SE_TCL_MATERIAL_EMISSIVE_GREEN -+0x2218 SE_TCL_MATERIAL_EMISSIVE_BLUE -+0x221c SE_TCL_MATERIAL_EMISSIVE_ALPHA -+0x2220 SE_TCL_MATERIAL_AMBIENT_RED -+0x2224 SE_TCL_MATERIAL_AMBIENT_GREEN -+0x2228 SE_TCL_MATERIAL_AMBIENT_BLUE -+0x222c SE_TCL_MATERIAL_AMBIENT_ALPHA -+0x2230 SE_TCL_MATERIAL_DIFFUSE_RED -+0x2234 SE_TCL_MATERIAL_DIFFUSE_GREEN -+0x2238 SE_TCL_MATERIAL_DIFFUSE_BLUE -+0x223c SE_TCL_MATERIAL_DIFFUSE_ALPHA -+0x2240 SE_TCL_MATERIAL_SPECULAR_RED -+0x2244 SE_TCL_MATERIAL_SPECULAR_GREEN -+0x2248 SE_TCL_MATERIAL_SPECULAR_BLUE -+0x224c SE_TCL_MATERIAL_SPECULAR_ALPHA -+0x2250 SE_TCL_SHININESS -+0x2254 SE_TCL_OUTPUT_VTX_FMT -+0x2258 SE_TCL_OUTPUT_VTX_SEL -+0x225c SE_TCL_MATRIX_SELECT_0 -+0x2260 SE_TCL_MATRIX_SELECT_1 -+0x2264 SE_TCL_UCP_VERT_BLEND_CNTL -+0x2268 SE_TCL_TEXTURE_PROC_CTL -+0x226c SE_TCL_LIGHT_MODEL_CTL -+0x2270 SE_TCL_PER_LIGHT_CTL_0 -+0x2274 SE_TCL_PER_LIGHT_CTL_1 -+0x2278 SE_TCL_PER_LIGHT_CTL_2 -+0x227c SE_TCL_PER_LIGHT_CTL_3 -+0x2284 SE_TCL_STATE_FLUSH -+0x26c0 RE_TOP_LEFT -+0x26c4 RE_MISC -+0x3290 RB3D_ZPASS_DATA -diff --git a/drivers/gpu/drm/radeon/reg_srcs/r200 b/drivers/gpu/drm/radeon/reg_srcs/r200 -new file mode 100644 -index 0000000..6021c88 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/r200 -@@ -0,0 +1,184 @@ -+r200 0x3294 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -+0x1c14 PP_MISC -+0x1c18 PP_FOG_COLOR -+0x1c1c RE_SOLID_COLOR -+0x1c20 RB3D_BLENDCNTL -+0x1c4c SE_CNTL -+0x1c50 RE_CNTL -+0x1cc8 RE_STIPPLE_ADDR -+0x1ccc RE_STIPPLE_DATA -+0x1cd0 RE_LINE_PATTERN -+0x1cd4 RE_LINE_STATE -+0x1cd8 RE_SCISSOR_TL_0 -+0x1cdc RE_SCISSOR_BR_0 -+0x1ce0 RE_SCISSOR_TL_1 -+0x1ce4 RE_SCISSOR_BR_1 -+0x1ce8 RE_SCISSOR_TL_2 -+0x1cec RE_SCISSOR_BR_2 -+0x1d60 RB3D_DEPTHXY_OFFSET -+0x1d7c RB3D_STENCILREFMASK -+0x1d80 RB3D_ROPCNTL -+0x1d84 RB3D_PLANEMASK -+0x1d98 VAP_VPORT_XSCALE -+0x1d9c VAP_VPORT_XOFFSET -+0x1da0 VAP_VPORT_YSCALE -+0x1da4 VAP_VPORT_YOFFSET -+0x1da8 VAP_VPORT_ZSCALE -+0x1dac VAP_VPORT_ZOFFSET -+0x1db0 SE_ZBIAS_FACTOR -+0x1db4 SE_ZBIAS_CONSTANT -+0x1db8 SE_LINE_WIDTH -+0x2080 SE_VAP_CNTL -+0x2090 SE_TCL_OUTPUT_VTX_FMT_0 -+0x2094 SE_TCL_OUTPUT_VTX_FMT_1 -+0x20b0 SE_VTE_CNTL -+0x2140 SE_CNTL_STATUS -+0x2180 SE_VTX_STATE_CNTL -+0x2200 SE_TCL_VECTOR_INDX_REG -+0x2204 SE_TCL_VECTOR_DATA_REG -+0x2208 SE_TCL_SCALAR_INDX_REG -+0x220c SE_TCL_SCALAR_DATA_REG -+0x2230 SE_TCL_MATRIX_SEL_0 -+0x2234 SE_TCL_MATRIX_SEL_1 -+0x2238 SE_TCL_MATRIX_SEL_2 -+0x223c SE_TCL_MATRIX_SEL_3 -+0x2240 SE_TCL_MATRIX_SEL_4 -+0x2250 SE_TCL_OUTPUT_VTX_COMP_SEL -+0x2254 SE_TCL_INPUT_VTX_VECTOR_ADDR_0 -+0x2258 SE_TCL_INPUT_VTX_VECTOR_ADDR_1 -+0x225c SE_TCL_INPUT_VTX_VECTOR_ADDR_2 -+0x2260 SE_TCL_INPUT_VTX_VECTOR_ADDR_3 -+0x2268 SE_TCL_LIGHT_MODEL_CTL_0 -+0x226c SE_TCL_LIGHT_MODEL_CTL_1 -+0x2270 SE_TCL_PER_LIGHT_CTL_0 -+0x2274 SE_TCL_PER_LIGHT_CTL_1 -+0x2278 SE_TCL_PER_LIGHT_CTL_2 -+0x227c SE_TCL_PER_LIGHT_CTL_3 -+0x2284 VAP_PVS_STATE_FLUSH_REG -+0x22a8 SE_TCL_TEX_PROC_CTL_2 -+0x22ac SE_TCL_TEX_PROC_CTL_3 -+0x22b0 SE_TCL_TEX_PROC_CTL_0 -+0x22b4 SE_TCL_TEX_PROC_CTL_1 -+0x22b8 SE_TCL_TEX_CYL_WRAP_CTL -+0x22c0 SE_TCL_UCP_VERT_BLEND_CNTL -+0x22c4 SE_TCL_POINT_SPRITE_CNTL -+0x2648 RE_POINTSIZE -+0x26c0 RE_TOP_LEFT -+0x26c4 RE_MISC -+0x26f0 RE_AUX_SCISSOR_CNTL -+0x2c14 PP_BORDER_COLOR_0 -+0x2c34 PP_BORDER_COLOR_1 -+0x2c54 PP_BORDER_COLOR_2 -+0x2c74 PP_BORDER_COLOR_3 -+0x2c94 PP_BORDER_COLOR_4 -+0x2cb4 PP_BORDER_COLOR_5 -+0x2cc4 PP_CNTL_X -+0x2cf8 PP_TRI_PERF -+0x2cfc PP_PERF_CNTL -+0x2d9c PP_TAM_DEBUG3 -+0x2ee0 PP_TFACTOR_0 -+0x2ee4 PP_TFACTOR_1 -+0x2ee8 PP_TFACTOR_2 -+0x2eec PP_TFACTOR_3 -+0x2ef0 PP_TFACTOR_4 -+0x2ef4 PP_TFACTOR_5 -+0x2ef8 PP_TFACTOR_6 -+0x2efc PP_TFACTOR_7 -+0x2f00 PP_TXCBLEND_0 -+0x2f04 PP_TXCBLEND2_0 -+0x2f08 PP_TXABLEND_0 -+0x2f0c PP_TXABLEND2_0 -+0x2f10 PP_TXCBLEND_1 -+0x2f14 PP_TXCBLEND2_1 -+0x2f18 PP_TXABLEND_1 -+0x2f1c PP_TXABLEND2_1 -+0x2f20 PP_TXCBLEND_2 -+0x2f24 PP_TXCBLEND2_2 -+0x2f28 PP_TXABLEND_2 -+0x2f2c PP_TXABLEND2_2 -+0x2f30 PP_TXCBLEND_3 -+0x2f34 PP_TXCBLEND2_3 -+0x2f38 PP_TXABLEND_3 -+0x2f3c PP_TXABLEND2_3 -+0x2f40 PP_TXCBLEND_4 -+0x2f44 PP_TXCBLEND2_4 -+0x2f48 PP_TXABLEND_4 -+0x2f4c PP_TXABLEND2_4 -+0x2f50 PP_TXCBLEND_5 -+0x2f54 PP_TXCBLEND2_5 -+0x2f58 PP_TXABLEND_5 -+0x2f5c PP_TXABLEND2_5 -+0x2f60 PP_TXCBLEND_6 -+0x2f64 PP_TXCBLEND2_6 -+0x2f68 PP_TXABLEND_6 -+0x2f6c PP_TXABLEND2_6 -+0x2f70 PP_TXCBLEND_7 -+0x2f74 PP_TXCBLEND2_7 -+0x2f78 PP_TXABLEND_7 -+0x2f7c PP_TXABLEND2_7 -+0x2f80 PP_TXCBLEND_8 -+0x2f84 PP_TXCBLEND2_8 -+0x2f88 PP_TXABLEND_8 -+0x2f8c PP_TXABLEND2_8 -+0x2f90 PP_TXCBLEND_9 -+0x2f94 PP_TXCBLEND2_9 -+0x2f98 PP_TXABLEND_9 -+0x2f9c PP_TXABLEND2_9 -+0x2fa0 PP_TXCBLEND_10 -+0x2fa4 PP_TXCBLEND2_10 -+0x2fa8 PP_TXABLEND_10 -+0x2fac PP_TXABLEND2_10 -+0x2fb0 PP_TXCBLEND_11 -+0x2fb4 PP_TXCBLEND2_11 -+0x2fb8 PP_TXABLEND_11 -+0x2fbc PP_TXABLEND2_11 -+0x2fc0 PP_TXCBLEND_12 -+0x2fc4 PP_TXCBLEND2_12 -+0x2fc8 PP_TXABLEND_12 -+0x2fcc PP_TXABLEND2_12 -+0x2fd0 PP_TXCBLEND_13 -+0x2fd4 PP_TXCBLEND2_13 -+0x2fd8 PP_TXABLEND_13 -+0x2fdc PP_TXABLEND2_13 -+0x2fe0 PP_TXCBLEND_14 -+0x2fe4 PP_TXCBLEND2_14 -+0x2fe8 PP_TXABLEND_14 -+0x2fec PP_TXABLEND2_14 -+0x2ff0 PP_TXCBLEND_15 -+0x2ff4 PP_TXCBLEND2_15 -+0x2ff8 PP_TXABLEND_15 -+0x2ffc PP_TXABLEND2_15 -+0x3218 RB3D_BLENCOLOR -+0x321c RB3D_ABLENDCNTL -+0x3220 RB3D_CBLENDCNTL -+0x3290 RB3D_ZPASS_DATA -+ -diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 -new file mode 100644 -index 0000000..19c4663 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/r300 -@@ -0,0 +1,729 @@ -+r300 0x4f60 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -+0x1D98 VAP_VPORT_XSCALE -+0x1D9C VAP_VPORT_XOFFSET -+0x1DA0 VAP_VPORT_YSCALE -+0x1DA4 VAP_VPORT_YOFFSET -+0x1DA8 VAP_VPORT_ZSCALE -+0x1DAC VAP_VPORT_ZOFFSET -+0x2080 VAP_CNTL -+0x2090 VAP_OUT_VTX_FMT_0 -+0x2094 VAP_OUT_VTX_FMT_1 -+0x20B0 VAP_VTE_CNTL -+0x2138 VAP_VF_MIN_VTX_INDX -+0x2140 VAP_CNTL_STATUS -+0x2150 VAP_PROG_STREAM_CNTL_0 -+0x2154 VAP_PROG_STREAM_CNTL_1 -+0x2158 VAP_PROG_STREAM_CNTL_2 -+0x215C VAP_PROG_STREAM_CNTL_3 -+0x2160 VAP_PROG_STREAM_CNTL_4 -+0x2164 VAP_PROG_STREAM_CNTL_5 -+0x2168 VAP_PROG_STREAM_CNTL_6 -+0x216C VAP_PROG_STREAM_CNTL_7 -+0x2180 VAP_VTX_STATE_CNTL -+0x2184 VAP_VSM_VTX_ASSM -+0x2188 VAP_VTX_STATE_IND_REG_0 -+0x218C VAP_VTX_STATE_IND_REG_1 -+0x2190 VAP_VTX_STATE_IND_REG_2 -+0x2194 VAP_VTX_STATE_IND_REG_3 -+0x2198 VAP_VTX_STATE_IND_REG_4 -+0x219C VAP_VTX_STATE_IND_REG_5 -+0x21A0 VAP_VTX_STATE_IND_REG_6 -+0x21A4 VAP_VTX_STATE_IND_REG_7 -+0x21A8 VAP_VTX_STATE_IND_REG_8 -+0x21AC VAP_VTX_STATE_IND_REG_9 -+0x21B0 VAP_VTX_STATE_IND_REG_10 -+0x21B4 VAP_VTX_STATE_IND_REG_11 -+0x21B8 VAP_VTX_STATE_IND_REG_12 -+0x21BC VAP_VTX_STATE_IND_REG_13 -+0x21C0 VAP_VTX_STATE_IND_REG_14 -+0x21C4 VAP_VTX_STATE_IND_REG_15 -+0x21DC VAP_PSC_SGN_NORM_CNTL -+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -+0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -+0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -+0x2200 VAP_PVS_VECTOR_INDX_REG -+0x2204 VAP_PVS_VECTOR_DATA_REG -+0x2208 VAP_PVS_VECTOR_DATA_REG_128 -+0x221C VAP_CLIP_CNTL -+0x2220 VAP_GB_VERT_CLIP_ADJ -+0x2224 VAP_GB_VERT_DISC_ADJ -+0x2228 VAP_GB_HORZ_CLIP_ADJ -+0x222C VAP_GB_HORZ_DISC_ADJ -+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -+0x2284 VAP_PVS_STATE_FLUSH_REG -+0x2288 VAP_PVS_VTX_TIMEOUT_REG -+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -+0x22D0 VAP_PVS_CODE_CNTL_0 -+0x22D4 VAP_PVS_CONST_CNTL -+0x22D8 VAP_PVS_CODE_CNTL_1 -+0x22DC VAP_PVS_FLOW_CNTL_OPC -+0x342C RB2D_DSTCACHE_CTLSTAT -+0x4000 GB_VAP_RASTER_VTX_FMT_0 -+0x4004 GB_VAP_RASTER_VTX_FMT_1 -+0x4008 GB_ENABLE -+0x401C GB_SELECT -+0x4020 GB_AA_CONFIG -+0x4024 GB_FIFO_SIZE -+0x4100 TX_INVALTAGS -+0x4200 GA_POINT_S0 -+0x4204 GA_POINT_T0 -+0x4208 GA_POINT_S1 -+0x420C GA_POINT_T1 -+0x4214 GA_TRIANGLE_STIPPLE -+0x421C GA_POINT_SIZE -+0x4230 GA_POINT_MINMAX -+0x4234 GA_LINE_CNTL -+0x4238 GA_LINE_STIPPLE_CONFIG -+0x4260 GA_LINE_STIPPLE_VALUE -+0x4264 GA_LINE_S0 -+0x4268 GA_LINE_S1 -+0x4278 GA_COLOR_CONTROL -+0x427C GA_SOLID_RG -+0x4280 GA_SOLID_BA -+0x4288 GA_POLY_MODE -+0x428C GA_ROUND_MODE -+0x4290 GA_OFFSET -+0x4294 GA_FOG_SCALE -+0x4298 GA_FOG_OFFSET -+0x42A0 SU_TEX_WRAP -+0x42A4 SU_POLY_OFFSET_FRONT_SCALE -+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -+0x42AC SU_POLY_OFFSET_BACK_SCALE -+0x42B0 SU_POLY_OFFSET_BACK_OFFSET -+0x42B4 SU_POLY_OFFSET_ENABLE -+0x42B8 SU_CULL_MODE -+0x42C0 SU_DEPTH_SCALE -+0x42C4 SU_DEPTH_OFFSET -+0x42C8 SU_REG_DEST -+0x4300 RS_COUNT -+0x4304 RS_INST_COUNT -+0x4310 RS_IP_0 -+0x4314 RS_IP_1 -+0x4318 RS_IP_2 -+0x431C RS_IP_3 -+0x4320 RS_IP_4 -+0x4324 RS_IP_5 -+0x4328 RS_IP_6 -+0x432C RS_IP_7 -+0x4330 RS_INST_0 -+0x4334 RS_INST_1 -+0x4338 RS_INST_2 -+0x433C RS_INST_3 -+0x4340 RS_INST_4 -+0x4344 RS_INST_5 -+0x4348 RS_INST_6 -+0x434C RS_INST_7 -+0x4350 RS_INST_8 -+0x4354 RS_INST_9 -+0x4358 RS_INST_10 -+0x435C RS_INST_11 -+0x4360 RS_INST_12 -+0x4364 RS_INST_13 -+0x4368 RS_INST_14 -+0x436C RS_INST_15 -+0x43A4 SC_HYPERZ_EN -+0x43A8 SC_EDGERULE -+0x43B0 SC_CLIP_0_A -+0x43B4 SC_CLIP_0_B -+0x43B8 SC_CLIP_1_A -+0x43BC SC_CLIP_1_B -+0x43C0 SC_CLIP_2_A -+0x43C4 SC_CLIP_2_B -+0x43C8 SC_CLIP_3_A -+0x43CC SC_CLIP_3_B -+0x43D0 SC_CLIP_RULE -+0x43E0 SC_SCISSOR0 -+0x43E8 SC_SCREENDOOR -+0x4440 TX_FILTER1_0 -+0x4444 TX_FILTER1_1 -+0x4448 TX_FILTER1_2 -+0x444C TX_FILTER1_3 -+0x4450 TX_FILTER1_4 -+0x4454 TX_FILTER1_5 -+0x4458 TX_FILTER1_6 -+0x445C TX_FILTER1_7 -+0x4460 TX_FILTER1_8 -+0x4464 TX_FILTER1_9 -+0x4468 TX_FILTER1_10 -+0x446C TX_FILTER1_11 -+0x4470 TX_FILTER1_12 -+0x4474 TX_FILTER1_13 -+0x4478 TX_FILTER1_14 -+0x447C TX_FILTER1_15 -+0x4580 TX_CHROMA_KEY_0 -+0x4584 TX_CHROMA_KEY_1 -+0x4588 TX_CHROMA_KEY_2 -+0x458C TX_CHROMA_KEY_3 -+0x4590 TX_CHROMA_KEY_4 -+0x4594 TX_CHROMA_KEY_5 -+0x4598 TX_CHROMA_KEY_6 -+0x459C TX_CHROMA_KEY_7 -+0x45A0 TX_CHROMA_KEY_8 -+0x45A4 TX_CHROMA_KEY_9 -+0x45A8 TX_CHROMA_KEY_10 -+0x45AC TX_CHROMA_KEY_11 -+0x45B0 TX_CHROMA_KEY_12 -+0x45B4 TX_CHROMA_KEY_13 -+0x45B8 TX_CHROMA_KEY_14 -+0x45BC TX_CHROMA_KEY_15 -+0x45C0 TX_BORDER_COLOR_0 -+0x45C4 TX_BORDER_COLOR_1 -+0x45C8 TX_BORDER_COLOR_2 -+0x45CC TX_BORDER_COLOR_3 -+0x45D0 TX_BORDER_COLOR_4 -+0x45D4 TX_BORDER_COLOR_5 -+0x45D8 TX_BORDER_COLOR_6 -+0x45DC TX_BORDER_COLOR_7 -+0x45E0 TX_BORDER_COLOR_8 -+0x45E4 TX_BORDER_COLOR_9 -+0x45E8 TX_BORDER_COLOR_10 -+0x45EC TX_BORDER_COLOR_11 -+0x45F0 TX_BORDER_COLOR_12 -+0x45F4 TX_BORDER_COLOR_13 -+0x45F8 TX_BORDER_COLOR_14 -+0x45FC TX_BORDER_COLOR_15 -+0x4600 US_CONFIG -+0x4604 US_PIXSIZE -+0x4608 US_CODE_OFFSET -+0x460C US_RESET -+0x4610 US_CODE_ADDR_0 -+0x4614 US_CODE_ADDR_1 -+0x4618 US_CODE_ADDR_2 -+0x461C US_CODE_ADDR_3 -+0x4620 US_TEX_INST_0 -+0x4624 US_TEX_INST_1 -+0x4628 US_TEX_INST_2 -+0x462C US_TEX_INST_3 -+0x4630 US_TEX_INST_4 -+0x4634 US_TEX_INST_5 -+0x4638 US_TEX_INST_6 -+0x463C US_TEX_INST_7 -+0x4640 US_TEX_INST_8 -+0x4644 US_TEX_INST_9 -+0x4648 US_TEX_INST_10 -+0x464C US_TEX_INST_11 -+0x4650 US_TEX_INST_12 -+0x4654 US_TEX_INST_13 -+0x4658 US_TEX_INST_14 -+0x465C US_TEX_INST_15 -+0x4660 US_TEX_INST_16 -+0x4664 US_TEX_INST_17 -+0x4668 US_TEX_INST_18 -+0x466C US_TEX_INST_19 -+0x4670 US_TEX_INST_20 -+0x4674 US_TEX_INST_21 -+0x4678 US_TEX_INST_22 -+0x467C US_TEX_INST_23 -+0x4680 US_TEX_INST_24 -+0x4684 US_TEX_INST_25 -+0x4688 US_TEX_INST_26 -+0x468C US_TEX_INST_27 -+0x4690 US_TEX_INST_28 -+0x4694 US_TEX_INST_29 -+0x4698 US_TEX_INST_30 -+0x469C US_TEX_INST_31 -+0x46A4 US_OUT_FMT_0 -+0x46A8 US_OUT_FMT_1 -+0x46AC US_OUT_FMT_2 -+0x46B0 US_OUT_FMT_3 -+0x46B4 US_W_FMT -+0x46C0 US_ALU_RGB_ADDR_0 -+0x46C4 US_ALU_RGB_ADDR_1 -+0x46C8 US_ALU_RGB_ADDR_2 -+0x46CC US_ALU_RGB_ADDR_3 -+0x46D0 US_ALU_RGB_ADDR_4 -+0x46D4 US_ALU_RGB_ADDR_5 -+0x46D8 US_ALU_RGB_ADDR_6 -+0x46DC US_ALU_RGB_ADDR_7 -+0x46E0 US_ALU_RGB_ADDR_8 -+0x46E4 US_ALU_RGB_ADDR_9 -+0x46E8 US_ALU_RGB_ADDR_10 -+0x46EC US_ALU_RGB_ADDR_11 -+0x46F0 US_ALU_RGB_ADDR_12 -+0x46F4 US_ALU_RGB_ADDR_13 -+0x46F8 US_ALU_RGB_ADDR_14 -+0x46FC US_ALU_RGB_ADDR_15 -+0x4700 US_ALU_RGB_ADDR_16 -+0x4704 US_ALU_RGB_ADDR_17 -+0x4708 US_ALU_RGB_ADDR_18 -+0x470C US_ALU_RGB_ADDR_19 -+0x4710 US_ALU_RGB_ADDR_20 -+0x4714 US_ALU_RGB_ADDR_21 -+0x4718 US_ALU_RGB_ADDR_22 -+0x471C US_ALU_RGB_ADDR_23 -+0x4720 US_ALU_RGB_ADDR_24 -+0x4724 US_ALU_RGB_ADDR_25 -+0x4728 US_ALU_RGB_ADDR_26 -+0x472C US_ALU_RGB_ADDR_27 -+0x4730 US_ALU_RGB_ADDR_28 -+0x4734 US_ALU_RGB_ADDR_29 -+0x4738 US_ALU_RGB_ADDR_30 -+0x473C US_ALU_RGB_ADDR_31 -+0x4740 US_ALU_RGB_ADDR_32 -+0x4744 US_ALU_RGB_ADDR_33 -+0x4748 US_ALU_RGB_ADDR_34 -+0x474C US_ALU_RGB_ADDR_35 -+0x4750 US_ALU_RGB_ADDR_36 -+0x4754 US_ALU_RGB_ADDR_37 -+0x4758 US_ALU_RGB_ADDR_38 -+0x475C US_ALU_RGB_ADDR_39 -+0x4760 US_ALU_RGB_ADDR_40 -+0x4764 US_ALU_RGB_ADDR_41 -+0x4768 US_ALU_RGB_ADDR_42 -+0x476C US_ALU_RGB_ADDR_43 -+0x4770 US_ALU_RGB_ADDR_44 -+0x4774 US_ALU_RGB_ADDR_45 -+0x4778 US_ALU_RGB_ADDR_46 -+0x477C US_ALU_RGB_ADDR_47 -+0x4780 US_ALU_RGB_ADDR_48 -+0x4784 US_ALU_RGB_ADDR_49 -+0x4788 US_ALU_RGB_ADDR_50 -+0x478C US_ALU_RGB_ADDR_51 -+0x4790 US_ALU_RGB_ADDR_52 -+0x4794 US_ALU_RGB_ADDR_53 -+0x4798 US_ALU_RGB_ADDR_54 -+0x479C US_ALU_RGB_ADDR_55 -+0x47A0 US_ALU_RGB_ADDR_56 -+0x47A4 US_ALU_RGB_ADDR_57 -+0x47A8 US_ALU_RGB_ADDR_58 -+0x47AC US_ALU_RGB_ADDR_59 -+0x47B0 US_ALU_RGB_ADDR_60 -+0x47B4 US_ALU_RGB_ADDR_61 -+0x47B8 US_ALU_RGB_ADDR_62 -+0x47BC US_ALU_RGB_ADDR_63 -+0x47C0 US_ALU_ALPHA_ADDR_0 -+0x47C4 US_ALU_ALPHA_ADDR_1 -+0x47C8 US_ALU_ALPHA_ADDR_2 -+0x47CC US_ALU_ALPHA_ADDR_3 -+0x47D0 US_ALU_ALPHA_ADDR_4 -+0x47D4 US_ALU_ALPHA_ADDR_5 -+0x47D8 US_ALU_ALPHA_ADDR_6 -+0x47DC US_ALU_ALPHA_ADDR_7 -+0x47E0 US_ALU_ALPHA_ADDR_8 -+0x47E4 US_ALU_ALPHA_ADDR_9 -+0x47E8 US_ALU_ALPHA_ADDR_10 -+0x47EC US_ALU_ALPHA_ADDR_11 -+0x47F0 US_ALU_ALPHA_ADDR_12 -+0x47F4 US_ALU_ALPHA_ADDR_13 -+0x47F8 US_ALU_ALPHA_ADDR_14 -+0x47FC US_ALU_ALPHA_ADDR_15 -+0x4800 US_ALU_ALPHA_ADDR_16 -+0x4804 US_ALU_ALPHA_ADDR_17 -+0x4808 US_ALU_ALPHA_ADDR_18 -+0x480C US_ALU_ALPHA_ADDR_19 -+0x4810 US_ALU_ALPHA_ADDR_20 -+0x4814 US_ALU_ALPHA_ADDR_21 -+0x4818 US_ALU_ALPHA_ADDR_22 -+0x481C US_ALU_ALPHA_ADDR_23 -+0x4820 US_ALU_ALPHA_ADDR_24 -+0x4824 US_ALU_ALPHA_ADDR_25 -+0x4828 US_ALU_ALPHA_ADDR_26 -+0x482C US_ALU_ALPHA_ADDR_27 -+0x4830 US_ALU_ALPHA_ADDR_28 -+0x4834 US_ALU_ALPHA_ADDR_29 -+0x4838 US_ALU_ALPHA_ADDR_30 -+0x483C US_ALU_ALPHA_ADDR_31 -+0x4840 US_ALU_ALPHA_ADDR_32 -+0x4844 US_ALU_ALPHA_ADDR_33 -+0x4848 US_ALU_ALPHA_ADDR_34 -+0x484C US_ALU_ALPHA_ADDR_35 -+0x4850 US_ALU_ALPHA_ADDR_36 -+0x4854 US_ALU_ALPHA_ADDR_37 -+0x4858 US_ALU_ALPHA_ADDR_38 -+0x485C US_ALU_ALPHA_ADDR_39 -+0x4860 US_ALU_ALPHA_ADDR_40 -+0x4864 US_ALU_ALPHA_ADDR_41 -+0x4868 US_ALU_ALPHA_ADDR_42 -+0x486C US_ALU_ALPHA_ADDR_43 -+0x4870 US_ALU_ALPHA_ADDR_44 -+0x4874 US_ALU_ALPHA_ADDR_45 -+0x4878 US_ALU_ALPHA_ADDR_46 -+0x487C US_ALU_ALPHA_ADDR_47 -+0x4880 US_ALU_ALPHA_ADDR_48 -+0x4884 US_ALU_ALPHA_ADDR_49 -+0x4888 US_ALU_ALPHA_ADDR_50 -+0x488C US_ALU_ALPHA_ADDR_51 -+0x4890 US_ALU_ALPHA_ADDR_52 -+0x4894 US_ALU_ALPHA_ADDR_53 -+0x4898 US_ALU_ALPHA_ADDR_54 -+0x489C US_ALU_ALPHA_ADDR_55 -+0x48A0 US_ALU_ALPHA_ADDR_56 -+0x48A4 US_ALU_ALPHA_ADDR_57 -+0x48A8 US_ALU_ALPHA_ADDR_58 -+0x48AC US_ALU_ALPHA_ADDR_59 -+0x48B0 US_ALU_ALPHA_ADDR_60 -+0x48B4 US_ALU_ALPHA_ADDR_61 -+0x48B8 US_ALU_ALPHA_ADDR_62 -+0x48BC US_ALU_ALPHA_ADDR_63 -+0x48C0 US_ALU_RGB_INST_0 -+0x48C4 US_ALU_RGB_INST_1 -+0x48C8 US_ALU_RGB_INST_2 -+0x48CC US_ALU_RGB_INST_3 -+0x48D0 US_ALU_RGB_INST_4 -+0x48D4 US_ALU_RGB_INST_5 -+0x48D8 US_ALU_RGB_INST_6 -+0x48DC US_ALU_RGB_INST_7 -+0x48E0 US_ALU_RGB_INST_8 -+0x48E4 US_ALU_RGB_INST_9 -+0x48E8 US_ALU_RGB_INST_10 -+0x48EC US_ALU_RGB_INST_11 -+0x48F0 US_ALU_RGB_INST_12 -+0x48F4 US_ALU_RGB_INST_13 -+0x48F8 US_ALU_RGB_INST_14 -+0x48FC US_ALU_RGB_INST_15 -+0x4900 US_ALU_RGB_INST_16 -+0x4904 US_ALU_RGB_INST_17 -+0x4908 US_ALU_RGB_INST_18 -+0x490C US_ALU_RGB_INST_19 -+0x4910 US_ALU_RGB_INST_20 -+0x4914 US_ALU_RGB_INST_21 -+0x4918 US_ALU_RGB_INST_22 -+0x491C US_ALU_RGB_INST_23 -+0x4920 US_ALU_RGB_INST_24 -+0x4924 US_ALU_RGB_INST_25 -+0x4928 US_ALU_RGB_INST_26 -+0x492C US_ALU_RGB_INST_27 -+0x4930 US_ALU_RGB_INST_28 -+0x4934 US_ALU_RGB_INST_29 -+0x4938 US_ALU_RGB_INST_30 -+0x493C US_ALU_RGB_INST_31 -+0x4940 US_ALU_RGB_INST_32 -+0x4944 US_ALU_RGB_INST_33 -+0x4948 US_ALU_RGB_INST_34 -+0x494C US_ALU_RGB_INST_35 -+0x4950 US_ALU_RGB_INST_36 -+0x4954 US_ALU_RGB_INST_37 -+0x4958 US_ALU_RGB_INST_38 -+0x495C US_ALU_RGB_INST_39 -+0x4960 US_ALU_RGB_INST_40 -+0x4964 US_ALU_RGB_INST_41 -+0x4968 US_ALU_RGB_INST_42 -+0x496C US_ALU_RGB_INST_43 -+0x4970 US_ALU_RGB_INST_44 -+0x4974 US_ALU_RGB_INST_45 -+0x4978 US_ALU_RGB_INST_46 -+0x497C US_ALU_RGB_INST_47 -+0x4980 US_ALU_RGB_INST_48 -+0x4984 US_ALU_RGB_INST_49 -+0x4988 US_ALU_RGB_INST_50 -+0x498C US_ALU_RGB_INST_51 -+0x4990 US_ALU_RGB_INST_52 -+0x4994 US_ALU_RGB_INST_53 -+0x4998 US_ALU_RGB_INST_54 -+0x499C US_ALU_RGB_INST_55 -+0x49A0 US_ALU_RGB_INST_56 -+0x49A4 US_ALU_RGB_INST_57 -+0x49A8 US_ALU_RGB_INST_58 -+0x49AC US_ALU_RGB_INST_59 -+0x49B0 US_ALU_RGB_INST_60 -+0x49B4 US_ALU_RGB_INST_61 -+0x49B8 US_ALU_RGB_INST_62 -+0x49BC US_ALU_RGB_INST_63 -+0x49C0 US_ALU_ALPHA_INST_0 -+0x49C4 US_ALU_ALPHA_INST_1 -+0x49C8 US_ALU_ALPHA_INST_2 -+0x49CC US_ALU_ALPHA_INST_3 -+0x49D0 US_ALU_ALPHA_INST_4 -+0x49D4 US_ALU_ALPHA_INST_5 -+0x49D8 US_ALU_ALPHA_INST_6 -+0x49DC US_ALU_ALPHA_INST_7 -+0x49E0 US_ALU_ALPHA_INST_8 -+0x49E4 US_ALU_ALPHA_INST_9 -+0x49E8 US_ALU_ALPHA_INST_10 -+0x49EC US_ALU_ALPHA_INST_11 -+0x49F0 US_ALU_ALPHA_INST_12 -+0x49F4 US_ALU_ALPHA_INST_13 -+0x49F8 US_ALU_ALPHA_INST_14 -+0x49FC US_ALU_ALPHA_INST_15 -+0x4A00 US_ALU_ALPHA_INST_16 -+0x4A04 US_ALU_ALPHA_INST_17 -+0x4A08 US_ALU_ALPHA_INST_18 -+0x4A0C US_ALU_ALPHA_INST_19 -+0x4A10 US_ALU_ALPHA_INST_20 -+0x4A14 US_ALU_ALPHA_INST_21 -+0x4A18 US_ALU_ALPHA_INST_22 -+0x4A1C US_ALU_ALPHA_INST_23 -+0x4A20 US_ALU_ALPHA_INST_24 -+0x4A24 US_ALU_ALPHA_INST_25 -+0x4A28 US_ALU_ALPHA_INST_26 -+0x4A2C US_ALU_ALPHA_INST_27 -+0x4A30 US_ALU_ALPHA_INST_28 -+0x4A34 US_ALU_ALPHA_INST_29 -+0x4A38 US_ALU_ALPHA_INST_30 -+0x4A3C US_ALU_ALPHA_INST_31 -+0x4A40 US_ALU_ALPHA_INST_32 -+0x4A44 US_ALU_ALPHA_INST_33 -+0x4A48 US_ALU_ALPHA_INST_34 -+0x4A4C US_ALU_ALPHA_INST_35 -+0x4A50 US_ALU_ALPHA_INST_36 -+0x4A54 US_ALU_ALPHA_INST_37 -+0x4A58 US_ALU_ALPHA_INST_38 -+0x4A5C US_ALU_ALPHA_INST_39 -+0x4A60 US_ALU_ALPHA_INST_40 -+0x4A64 US_ALU_ALPHA_INST_41 -+0x4A68 US_ALU_ALPHA_INST_42 -+0x4A6C US_ALU_ALPHA_INST_43 -+0x4A70 US_ALU_ALPHA_INST_44 -+0x4A74 US_ALU_ALPHA_INST_45 -+0x4A78 US_ALU_ALPHA_INST_46 -+0x4A7C US_ALU_ALPHA_INST_47 -+0x4A80 US_ALU_ALPHA_INST_48 -+0x4A84 US_ALU_ALPHA_INST_49 -+0x4A88 US_ALU_ALPHA_INST_50 -+0x4A8C US_ALU_ALPHA_INST_51 -+0x4A90 US_ALU_ALPHA_INST_52 -+0x4A94 US_ALU_ALPHA_INST_53 -+0x4A98 US_ALU_ALPHA_INST_54 -+0x4A9C US_ALU_ALPHA_INST_55 -+0x4AA0 US_ALU_ALPHA_INST_56 -+0x4AA4 US_ALU_ALPHA_INST_57 -+0x4AA8 US_ALU_ALPHA_INST_58 -+0x4AAC US_ALU_ALPHA_INST_59 -+0x4AB0 US_ALU_ALPHA_INST_60 -+0x4AB4 US_ALU_ALPHA_INST_61 -+0x4AB8 US_ALU_ALPHA_INST_62 -+0x4ABC US_ALU_ALPHA_INST_63 -+0x4BC0 FG_FOG_BLEND -+0x4BC4 FG_FOG_FACTOR -+0x4BC8 FG_FOG_COLOR_R -+0x4BCC FG_FOG_COLOR_G -+0x4BD0 FG_FOG_COLOR_B -+0x4BD4 FG_ALPHA_FUNC -+0x4BD8 FG_DEPTH_SRC -+0x4C00 US_ALU_CONST_R_0 -+0x4C04 US_ALU_CONST_G_0 -+0x4C08 US_ALU_CONST_B_0 -+0x4C0C US_ALU_CONST_A_0 -+0x4C10 US_ALU_CONST_R_1 -+0x4C14 US_ALU_CONST_G_1 -+0x4C18 US_ALU_CONST_B_1 -+0x4C1C US_ALU_CONST_A_1 -+0x4C20 US_ALU_CONST_R_2 -+0x4C24 US_ALU_CONST_G_2 -+0x4C28 US_ALU_CONST_B_2 -+0x4C2C US_ALU_CONST_A_2 -+0x4C30 US_ALU_CONST_R_3 -+0x4C34 US_ALU_CONST_G_3 -+0x4C38 US_ALU_CONST_B_3 -+0x4C3C US_ALU_CONST_A_3 -+0x4C40 US_ALU_CONST_R_4 -+0x4C44 US_ALU_CONST_G_4 -+0x4C48 US_ALU_CONST_B_4 -+0x4C4C US_ALU_CONST_A_4 -+0x4C50 US_ALU_CONST_R_5 -+0x4C54 US_ALU_CONST_G_5 -+0x4C58 US_ALU_CONST_B_5 -+0x4C5C US_ALU_CONST_A_5 -+0x4C60 US_ALU_CONST_R_6 -+0x4C64 US_ALU_CONST_G_6 -+0x4C68 US_ALU_CONST_B_6 -+0x4C6C US_ALU_CONST_A_6 -+0x4C70 US_ALU_CONST_R_7 -+0x4C74 US_ALU_CONST_G_7 -+0x4C78 US_ALU_CONST_B_7 -+0x4C7C US_ALU_CONST_A_7 -+0x4C80 US_ALU_CONST_R_8 -+0x4C84 US_ALU_CONST_G_8 -+0x4C88 US_ALU_CONST_B_8 -+0x4C8C US_ALU_CONST_A_8 -+0x4C90 US_ALU_CONST_R_9 -+0x4C94 US_ALU_CONST_G_9 -+0x4C98 US_ALU_CONST_B_9 -+0x4C9C US_ALU_CONST_A_9 -+0x4CA0 US_ALU_CONST_R_10 -+0x4CA4 US_ALU_CONST_G_10 -+0x4CA8 US_ALU_CONST_B_10 -+0x4CAC US_ALU_CONST_A_10 -+0x4CB0 US_ALU_CONST_R_11 -+0x4CB4 US_ALU_CONST_G_11 -+0x4CB8 US_ALU_CONST_B_11 -+0x4CBC US_ALU_CONST_A_11 -+0x4CC0 US_ALU_CONST_R_12 -+0x4CC4 US_ALU_CONST_G_12 -+0x4CC8 US_ALU_CONST_B_12 -+0x4CCC US_ALU_CONST_A_12 -+0x4CD0 US_ALU_CONST_R_13 -+0x4CD4 US_ALU_CONST_G_13 -+0x4CD8 US_ALU_CONST_B_13 -+0x4CDC US_ALU_CONST_A_13 -+0x4CE0 US_ALU_CONST_R_14 -+0x4CE4 US_ALU_CONST_G_14 -+0x4CE8 US_ALU_CONST_B_14 -+0x4CEC US_ALU_CONST_A_14 -+0x4CF0 US_ALU_CONST_R_15 -+0x4CF4 US_ALU_CONST_G_15 -+0x4CF8 US_ALU_CONST_B_15 -+0x4CFC US_ALU_CONST_A_15 -+0x4D00 US_ALU_CONST_R_16 -+0x4D04 US_ALU_CONST_G_16 -+0x4D08 US_ALU_CONST_B_16 -+0x4D0C US_ALU_CONST_A_16 -+0x4D10 US_ALU_CONST_R_17 -+0x4D14 US_ALU_CONST_G_17 -+0x4D18 US_ALU_CONST_B_17 -+0x4D1C US_ALU_CONST_A_17 -+0x4D20 US_ALU_CONST_R_18 -+0x4D24 US_ALU_CONST_G_18 -+0x4D28 US_ALU_CONST_B_18 -+0x4D2C US_ALU_CONST_A_18 -+0x4D30 US_ALU_CONST_R_19 -+0x4D34 US_ALU_CONST_G_19 -+0x4D38 US_ALU_CONST_B_19 -+0x4D3C US_ALU_CONST_A_19 -+0x4D40 US_ALU_CONST_R_20 -+0x4D44 US_ALU_CONST_G_20 -+0x4D48 US_ALU_CONST_B_20 -+0x4D4C US_ALU_CONST_A_20 -+0x4D50 US_ALU_CONST_R_21 -+0x4D54 US_ALU_CONST_G_21 -+0x4D58 US_ALU_CONST_B_21 -+0x4D5C US_ALU_CONST_A_21 -+0x4D60 US_ALU_CONST_R_22 -+0x4D64 US_ALU_CONST_G_22 -+0x4D68 US_ALU_CONST_B_22 -+0x4D6C US_ALU_CONST_A_22 -+0x4D70 US_ALU_CONST_R_23 -+0x4D74 US_ALU_CONST_G_23 -+0x4D78 US_ALU_CONST_B_23 -+0x4D7C US_ALU_CONST_A_23 -+0x4D80 US_ALU_CONST_R_24 -+0x4D84 US_ALU_CONST_G_24 -+0x4D88 US_ALU_CONST_B_24 -+0x4D8C US_ALU_CONST_A_24 -+0x4D90 US_ALU_CONST_R_25 -+0x4D94 US_ALU_CONST_G_25 -+0x4D98 US_ALU_CONST_B_25 -+0x4D9C US_ALU_CONST_A_25 -+0x4DA0 US_ALU_CONST_R_26 -+0x4DA4 US_ALU_CONST_G_26 -+0x4DA8 US_ALU_CONST_B_26 -+0x4DAC US_ALU_CONST_A_26 -+0x4DB0 US_ALU_CONST_R_27 -+0x4DB4 US_ALU_CONST_G_27 -+0x4DB8 US_ALU_CONST_B_27 -+0x4DBC US_ALU_CONST_A_27 -+0x4DC0 US_ALU_CONST_R_28 -+0x4DC4 US_ALU_CONST_G_28 -+0x4DC8 US_ALU_CONST_B_28 -+0x4DCC US_ALU_CONST_A_28 -+0x4DD0 US_ALU_CONST_R_29 -+0x4DD4 US_ALU_CONST_G_29 -+0x4DD8 US_ALU_CONST_B_29 -+0x4DDC US_ALU_CONST_A_29 -+0x4DE0 US_ALU_CONST_R_30 -+0x4DE4 US_ALU_CONST_G_30 -+0x4DE8 US_ALU_CONST_B_30 -+0x4DEC US_ALU_CONST_A_30 -+0x4DF0 US_ALU_CONST_R_31 -+0x4DF4 US_ALU_CONST_G_31 -+0x4DF8 US_ALU_CONST_B_31 -+0x4DFC US_ALU_CONST_A_31 -+0x4E04 RB3D_BLENDCNTL_R3 -+0x4E08 RB3D_ABLENDCNTL_R3 -+0x4E0C RB3D_COLOR_CHANNEL_MASK -+0x4E10 RB3D_CONSTANT_COLOR -+0x4E14 RB3D_COLOR_CLEAR_VALUE -+0x4E18 RB3D_ROPCNTL_R3 -+0x4E1C RB3D_CLRCMP_FLIPE_R3 -+0x4E20 RB3D_CLRCMP_CLR_R3 -+0x4E24 RB3D_CLRCMP_MSK_R3 -+0x4E48 RB3D_DEBUG_CTL -+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -+0x4E50 RB3D_DITHER_CTL -+0x4E54 RB3D_CMASK_OFFSET0 -+0x4E58 RB3D_CMASK_OFFSET1 -+0x4E5C RB3D_CMASK_OFFSET2 -+0x4E60 RB3D_CMASK_OFFSET3 -+0x4E64 RB3D_CMASK_PITCH0 -+0x4E68 RB3D_CMASK_PITCH1 -+0x4E6C RB3D_CMASK_PITCH2 -+0x4E70 RB3D_CMASK_PITCH3 -+0x4E74 RB3D_CMASK_WRINDEX -+0x4E78 RB3D_CMASK_DWORD -+0x4E7C RB3D_CMASK_RDINDEX -+0x4E80 RB3D_AARESOLVE_OFFSET -+0x4E84 RB3D_AARESOLVE_PITCH -+0x4E88 RB3D_AARESOLVE_CTL -+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -+0x4F04 ZB_ZSTENCILCNTL -+0x4F08 ZB_STENCILREFMASK -+0x4F14 ZB_ZTOP -+0x4F18 ZB_ZCACHE_CTLSTAT -+0x4F1C ZB_BW_CNTL -+0x4F28 ZB_DEPTHCLEARVALUE -+0x4F30 ZB_ZMASK_OFFSET -+0x4F34 ZB_ZMASK_PITCH -+0x4F38 ZB_ZMASK_WRINDEX -+0x4F3C ZB_ZMASK_DWORD -+0x4F40 ZB_ZMASK_RDINDEX -+0x4F44 ZB_HIZ_OFFSET -+0x4F48 ZB_HIZ_WRINDEX -+0x4F4C ZB_HIZ_DWORD -+0x4F50 ZB_HIZ_RDINDEX -+0x4F54 ZB_HIZ_PITCH -+0x4F58 ZB_ZPASS_DATA -diff --git a/drivers/gpu/drm/radeon/reg_srcs/rn50 b/drivers/gpu/drm/radeon/reg_srcs/rn50 -new file mode 100644 -index 0000000..2687b63 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/rn50 -@@ -0,0 +1,30 @@ -+rn50 0x3294 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 -new file mode 100644 -index 0000000..8e3c0b8 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 -@@ -0,0 +1,729 @@ -+rs600 0x6d40 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -+0x1D98 VAP_VPORT_XSCALE -+0x1D9C VAP_VPORT_XOFFSET -+0x1DA0 VAP_VPORT_YSCALE -+0x1DA4 VAP_VPORT_YOFFSET -+0x1DA8 VAP_VPORT_ZSCALE -+0x1DAC VAP_VPORT_ZOFFSET -+0x2080 VAP_CNTL -+0x2090 VAP_OUT_VTX_FMT_0 -+0x2094 VAP_OUT_VTX_FMT_1 -+0x20B0 VAP_VTE_CNTL -+0x2138 VAP_VF_MIN_VTX_INDX -+0x2140 VAP_CNTL_STATUS -+0x2150 VAP_PROG_STREAM_CNTL_0 -+0x2154 VAP_PROG_STREAM_CNTL_1 -+0x2158 VAP_PROG_STREAM_CNTL_2 -+0x215C VAP_PROG_STREAM_CNTL_3 -+0x2160 VAP_PROG_STREAM_CNTL_4 -+0x2164 VAP_PROG_STREAM_CNTL_5 -+0x2168 VAP_PROG_STREAM_CNTL_6 -+0x216C VAP_PROG_STREAM_CNTL_7 -+0x2180 VAP_VTX_STATE_CNTL -+0x2184 VAP_VSM_VTX_ASSM -+0x2188 VAP_VTX_STATE_IND_REG_0 -+0x218C VAP_VTX_STATE_IND_REG_1 -+0x2190 VAP_VTX_STATE_IND_REG_2 -+0x2194 VAP_VTX_STATE_IND_REG_3 -+0x2198 VAP_VTX_STATE_IND_REG_4 -+0x219C VAP_VTX_STATE_IND_REG_5 -+0x21A0 VAP_VTX_STATE_IND_REG_6 -+0x21A4 VAP_VTX_STATE_IND_REG_7 -+0x21A8 VAP_VTX_STATE_IND_REG_8 -+0x21AC VAP_VTX_STATE_IND_REG_9 -+0x21B0 VAP_VTX_STATE_IND_REG_10 -+0x21B4 VAP_VTX_STATE_IND_REG_11 -+0x21B8 VAP_VTX_STATE_IND_REG_12 -+0x21BC VAP_VTX_STATE_IND_REG_13 -+0x21C0 VAP_VTX_STATE_IND_REG_14 -+0x21C4 VAP_VTX_STATE_IND_REG_15 -+0x21DC VAP_PSC_SGN_NORM_CNTL -+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -+0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -+0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -+0x2200 VAP_PVS_VECTOR_INDX_REG -+0x2204 VAP_PVS_VECTOR_DATA_REG -+0x2208 VAP_PVS_VECTOR_DATA_REG_128 -+0x221C VAP_CLIP_CNTL -+0x2220 VAP_GB_VERT_CLIP_ADJ -+0x2224 VAP_GB_VERT_DISC_ADJ -+0x2228 VAP_GB_HORZ_CLIP_ADJ -+0x222C VAP_GB_HORZ_DISC_ADJ -+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -+0x2284 VAP_PVS_STATE_FLUSH_REG -+0x2288 VAP_PVS_VTX_TIMEOUT_REG -+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -+0x22D0 VAP_PVS_CODE_CNTL_0 -+0x22D4 VAP_PVS_CONST_CNTL -+0x22D8 VAP_PVS_CODE_CNTL_1 -+0x22DC VAP_PVS_FLOW_CNTL_OPC -+0x342C RB2D_DSTCACHE_CTLSTAT -+0x4000 GB_VAP_RASTER_VTX_FMT_0 -+0x4004 GB_VAP_RASTER_VTX_FMT_1 -+0x4008 GB_ENABLE -+0x401C GB_SELECT -+0x4020 GB_AA_CONFIG -+0x4024 GB_FIFO_SIZE -+0x4100 TX_INVALTAGS -+0x4200 GA_POINT_S0 -+0x4204 GA_POINT_T0 -+0x4208 GA_POINT_S1 -+0x420C GA_POINT_T1 -+0x4214 GA_TRIANGLE_STIPPLE -+0x421C GA_POINT_SIZE -+0x4230 GA_POINT_MINMAX -+0x4234 GA_LINE_CNTL -+0x4238 GA_LINE_STIPPLE_CONFIG -+0x4260 GA_LINE_STIPPLE_VALUE -+0x4264 GA_LINE_S0 -+0x4268 GA_LINE_S1 -+0x4278 GA_COLOR_CONTROL -+0x427C GA_SOLID_RG -+0x4280 GA_SOLID_BA -+0x4288 GA_POLY_MODE -+0x428C GA_ROUND_MODE -+0x4290 GA_OFFSET -+0x4294 GA_FOG_SCALE -+0x4298 GA_FOG_OFFSET -+0x42A0 SU_TEX_WRAP -+0x42A4 SU_POLY_OFFSET_FRONT_SCALE -+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -+0x42AC SU_POLY_OFFSET_BACK_SCALE -+0x42B0 SU_POLY_OFFSET_BACK_OFFSET -+0x42B4 SU_POLY_OFFSET_ENABLE -+0x42B8 SU_CULL_MODE -+0x42C0 SU_DEPTH_SCALE -+0x42C4 SU_DEPTH_OFFSET -+0x42C8 SU_REG_DEST -+0x4300 RS_COUNT -+0x4304 RS_INST_COUNT -+0x4310 RS_IP_0 -+0x4314 RS_IP_1 -+0x4318 RS_IP_2 -+0x431C RS_IP_3 -+0x4320 RS_IP_4 -+0x4324 RS_IP_5 -+0x4328 RS_IP_6 -+0x432C RS_IP_7 -+0x4330 RS_INST_0 -+0x4334 RS_INST_1 -+0x4338 RS_INST_2 -+0x433C RS_INST_3 -+0x4340 RS_INST_4 -+0x4344 RS_INST_5 -+0x4348 RS_INST_6 -+0x434C RS_INST_7 -+0x4350 RS_INST_8 -+0x4354 RS_INST_9 -+0x4358 RS_INST_10 -+0x435C RS_INST_11 -+0x4360 RS_INST_12 -+0x4364 RS_INST_13 -+0x4368 RS_INST_14 -+0x436C RS_INST_15 -+0x43A4 SC_HYPERZ_EN -+0x43A8 SC_EDGERULE -+0x43B0 SC_CLIP_0_A -+0x43B4 SC_CLIP_0_B -+0x43B8 SC_CLIP_1_A -+0x43BC SC_CLIP_1_B -+0x43C0 SC_CLIP_2_A -+0x43C4 SC_CLIP_2_B -+0x43C8 SC_CLIP_3_A -+0x43CC SC_CLIP_3_B -+0x43D0 SC_CLIP_RULE -+0x43E0 SC_SCISSOR0 -+0x43E8 SC_SCREENDOOR -+0x4440 TX_FILTER1_0 -+0x4444 TX_FILTER1_1 -+0x4448 TX_FILTER1_2 -+0x444C TX_FILTER1_3 -+0x4450 TX_FILTER1_4 -+0x4454 TX_FILTER1_5 -+0x4458 TX_FILTER1_6 -+0x445C TX_FILTER1_7 -+0x4460 TX_FILTER1_8 -+0x4464 TX_FILTER1_9 -+0x4468 TX_FILTER1_10 -+0x446C TX_FILTER1_11 -+0x4470 TX_FILTER1_12 -+0x4474 TX_FILTER1_13 -+0x4478 TX_FILTER1_14 -+0x447C TX_FILTER1_15 -+0x4580 TX_CHROMA_KEY_0 -+0x4584 TX_CHROMA_KEY_1 -+0x4588 TX_CHROMA_KEY_2 -+0x458C TX_CHROMA_KEY_3 -+0x4590 TX_CHROMA_KEY_4 -+0x4594 TX_CHROMA_KEY_5 -+0x4598 TX_CHROMA_KEY_6 -+0x459C TX_CHROMA_KEY_7 -+0x45A0 TX_CHROMA_KEY_8 -+0x45A4 TX_CHROMA_KEY_9 -+0x45A8 TX_CHROMA_KEY_10 -+0x45AC TX_CHROMA_KEY_11 -+0x45B0 TX_CHROMA_KEY_12 -+0x45B4 TX_CHROMA_KEY_13 -+0x45B8 TX_CHROMA_KEY_14 -+0x45BC TX_CHROMA_KEY_15 -+0x45C0 TX_BORDER_COLOR_0 -+0x45C4 TX_BORDER_COLOR_1 -+0x45C8 TX_BORDER_COLOR_2 -+0x45CC TX_BORDER_COLOR_3 -+0x45D0 TX_BORDER_COLOR_4 -+0x45D4 TX_BORDER_COLOR_5 -+0x45D8 TX_BORDER_COLOR_6 -+0x45DC TX_BORDER_COLOR_7 -+0x45E0 TX_BORDER_COLOR_8 -+0x45E4 TX_BORDER_COLOR_9 -+0x45E8 TX_BORDER_COLOR_10 -+0x45EC TX_BORDER_COLOR_11 -+0x45F0 TX_BORDER_COLOR_12 -+0x45F4 TX_BORDER_COLOR_13 -+0x45F8 TX_BORDER_COLOR_14 -+0x45FC TX_BORDER_COLOR_15 -+0x4600 US_CONFIG -+0x4604 US_PIXSIZE -+0x4608 US_CODE_OFFSET -+0x460C US_RESET -+0x4610 US_CODE_ADDR_0 -+0x4614 US_CODE_ADDR_1 -+0x4618 US_CODE_ADDR_2 -+0x461C US_CODE_ADDR_3 -+0x4620 US_TEX_INST_0 -+0x4624 US_TEX_INST_1 -+0x4628 US_TEX_INST_2 -+0x462C US_TEX_INST_3 -+0x4630 US_TEX_INST_4 -+0x4634 US_TEX_INST_5 -+0x4638 US_TEX_INST_6 -+0x463C US_TEX_INST_7 -+0x4640 US_TEX_INST_8 -+0x4644 US_TEX_INST_9 -+0x4648 US_TEX_INST_10 -+0x464C US_TEX_INST_11 -+0x4650 US_TEX_INST_12 -+0x4654 US_TEX_INST_13 -+0x4658 US_TEX_INST_14 -+0x465C US_TEX_INST_15 -+0x4660 US_TEX_INST_16 -+0x4664 US_TEX_INST_17 -+0x4668 US_TEX_INST_18 -+0x466C US_TEX_INST_19 -+0x4670 US_TEX_INST_20 -+0x4674 US_TEX_INST_21 -+0x4678 US_TEX_INST_22 -+0x467C US_TEX_INST_23 -+0x4680 US_TEX_INST_24 -+0x4684 US_TEX_INST_25 -+0x4688 US_TEX_INST_26 -+0x468C US_TEX_INST_27 -+0x4690 US_TEX_INST_28 -+0x4694 US_TEX_INST_29 -+0x4698 US_TEX_INST_30 -+0x469C US_TEX_INST_31 -+0x46A4 US_OUT_FMT_0 -+0x46A8 US_OUT_FMT_1 -+0x46AC US_OUT_FMT_2 -+0x46B0 US_OUT_FMT_3 -+0x46B4 US_W_FMT -+0x46C0 US_ALU_RGB_ADDR_0 -+0x46C4 US_ALU_RGB_ADDR_1 -+0x46C8 US_ALU_RGB_ADDR_2 -+0x46CC US_ALU_RGB_ADDR_3 -+0x46D0 US_ALU_RGB_ADDR_4 -+0x46D4 US_ALU_RGB_ADDR_5 -+0x46D8 US_ALU_RGB_ADDR_6 -+0x46DC US_ALU_RGB_ADDR_7 -+0x46E0 US_ALU_RGB_ADDR_8 -+0x46E4 US_ALU_RGB_ADDR_9 -+0x46E8 US_ALU_RGB_ADDR_10 -+0x46EC US_ALU_RGB_ADDR_11 -+0x46F0 US_ALU_RGB_ADDR_12 -+0x46F4 US_ALU_RGB_ADDR_13 -+0x46F8 US_ALU_RGB_ADDR_14 -+0x46FC US_ALU_RGB_ADDR_15 -+0x4700 US_ALU_RGB_ADDR_16 -+0x4704 US_ALU_RGB_ADDR_17 -+0x4708 US_ALU_RGB_ADDR_18 -+0x470C US_ALU_RGB_ADDR_19 -+0x4710 US_ALU_RGB_ADDR_20 -+0x4714 US_ALU_RGB_ADDR_21 -+0x4718 US_ALU_RGB_ADDR_22 -+0x471C US_ALU_RGB_ADDR_23 -+0x4720 US_ALU_RGB_ADDR_24 -+0x4724 US_ALU_RGB_ADDR_25 -+0x4728 US_ALU_RGB_ADDR_26 -+0x472C US_ALU_RGB_ADDR_27 -+0x4730 US_ALU_RGB_ADDR_28 -+0x4734 US_ALU_RGB_ADDR_29 -+0x4738 US_ALU_RGB_ADDR_30 -+0x473C US_ALU_RGB_ADDR_31 -+0x4740 US_ALU_RGB_ADDR_32 -+0x4744 US_ALU_RGB_ADDR_33 -+0x4748 US_ALU_RGB_ADDR_34 -+0x474C US_ALU_RGB_ADDR_35 -+0x4750 US_ALU_RGB_ADDR_36 -+0x4754 US_ALU_RGB_ADDR_37 -+0x4758 US_ALU_RGB_ADDR_38 -+0x475C US_ALU_RGB_ADDR_39 -+0x4760 US_ALU_RGB_ADDR_40 -+0x4764 US_ALU_RGB_ADDR_41 -+0x4768 US_ALU_RGB_ADDR_42 -+0x476C US_ALU_RGB_ADDR_43 -+0x4770 US_ALU_RGB_ADDR_44 -+0x4774 US_ALU_RGB_ADDR_45 -+0x4778 US_ALU_RGB_ADDR_46 -+0x477C US_ALU_RGB_ADDR_47 -+0x4780 US_ALU_RGB_ADDR_48 -+0x4784 US_ALU_RGB_ADDR_49 -+0x4788 US_ALU_RGB_ADDR_50 -+0x478C US_ALU_RGB_ADDR_51 -+0x4790 US_ALU_RGB_ADDR_52 -+0x4794 US_ALU_RGB_ADDR_53 -+0x4798 US_ALU_RGB_ADDR_54 -+0x479C US_ALU_RGB_ADDR_55 -+0x47A0 US_ALU_RGB_ADDR_56 -+0x47A4 US_ALU_RGB_ADDR_57 -+0x47A8 US_ALU_RGB_ADDR_58 -+0x47AC US_ALU_RGB_ADDR_59 -+0x47B0 US_ALU_RGB_ADDR_60 -+0x47B4 US_ALU_RGB_ADDR_61 -+0x47B8 US_ALU_RGB_ADDR_62 -+0x47BC US_ALU_RGB_ADDR_63 -+0x47C0 US_ALU_ALPHA_ADDR_0 -+0x47C4 US_ALU_ALPHA_ADDR_1 -+0x47C8 US_ALU_ALPHA_ADDR_2 -+0x47CC US_ALU_ALPHA_ADDR_3 -+0x47D0 US_ALU_ALPHA_ADDR_4 -+0x47D4 US_ALU_ALPHA_ADDR_5 -+0x47D8 US_ALU_ALPHA_ADDR_6 -+0x47DC US_ALU_ALPHA_ADDR_7 -+0x47E0 US_ALU_ALPHA_ADDR_8 -+0x47E4 US_ALU_ALPHA_ADDR_9 -+0x47E8 US_ALU_ALPHA_ADDR_10 -+0x47EC US_ALU_ALPHA_ADDR_11 -+0x47F0 US_ALU_ALPHA_ADDR_12 -+0x47F4 US_ALU_ALPHA_ADDR_13 -+0x47F8 US_ALU_ALPHA_ADDR_14 -+0x47FC US_ALU_ALPHA_ADDR_15 -+0x4800 US_ALU_ALPHA_ADDR_16 -+0x4804 US_ALU_ALPHA_ADDR_17 -+0x4808 US_ALU_ALPHA_ADDR_18 -+0x480C US_ALU_ALPHA_ADDR_19 -+0x4810 US_ALU_ALPHA_ADDR_20 -+0x4814 US_ALU_ALPHA_ADDR_21 -+0x4818 US_ALU_ALPHA_ADDR_22 -+0x481C US_ALU_ALPHA_ADDR_23 -+0x4820 US_ALU_ALPHA_ADDR_24 -+0x4824 US_ALU_ALPHA_ADDR_25 -+0x4828 US_ALU_ALPHA_ADDR_26 -+0x482C US_ALU_ALPHA_ADDR_27 -+0x4830 US_ALU_ALPHA_ADDR_28 -+0x4834 US_ALU_ALPHA_ADDR_29 -+0x4838 US_ALU_ALPHA_ADDR_30 -+0x483C US_ALU_ALPHA_ADDR_31 -+0x4840 US_ALU_ALPHA_ADDR_32 -+0x4844 US_ALU_ALPHA_ADDR_33 -+0x4848 US_ALU_ALPHA_ADDR_34 -+0x484C US_ALU_ALPHA_ADDR_35 -+0x4850 US_ALU_ALPHA_ADDR_36 -+0x4854 US_ALU_ALPHA_ADDR_37 -+0x4858 US_ALU_ALPHA_ADDR_38 -+0x485C US_ALU_ALPHA_ADDR_39 -+0x4860 US_ALU_ALPHA_ADDR_40 -+0x4864 US_ALU_ALPHA_ADDR_41 -+0x4868 US_ALU_ALPHA_ADDR_42 -+0x486C US_ALU_ALPHA_ADDR_43 -+0x4870 US_ALU_ALPHA_ADDR_44 -+0x4874 US_ALU_ALPHA_ADDR_45 -+0x4878 US_ALU_ALPHA_ADDR_46 -+0x487C US_ALU_ALPHA_ADDR_47 -+0x4880 US_ALU_ALPHA_ADDR_48 -+0x4884 US_ALU_ALPHA_ADDR_49 -+0x4888 US_ALU_ALPHA_ADDR_50 -+0x488C US_ALU_ALPHA_ADDR_51 -+0x4890 US_ALU_ALPHA_ADDR_52 -+0x4894 US_ALU_ALPHA_ADDR_53 -+0x4898 US_ALU_ALPHA_ADDR_54 -+0x489C US_ALU_ALPHA_ADDR_55 -+0x48A0 US_ALU_ALPHA_ADDR_56 -+0x48A4 US_ALU_ALPHA_ADDR_57 -+0x48A8 US_ALU_ALPHA_ADDR_58 -+0x48AC US_ALU_ALPHA_ADDR_59 -+0x48B0 US_ALU_ALPHA_ADDR_60 -+0x48B4 US_ALU_ALPHA_ADDR_61 -+0x48B8 US_ALU_ALPHA_ADDR_62 -+0x48BC US_ALU_ALPHA_ADDR_63 -+0x48C0 US_ALU_RGB_INST_0 -+0x48C4 US_ALU_RGB_INST_1 -+0x48C8 US_ALU_RGB_INST_2 -+0x48CC US_ALU_RGB_INST_3 -+0x48D0 US_ALU_RGB_INST_4 -+0x48D4 US_ALU_RGB_INST_5 -+0x48D8 US_ALU_RGB_INST_6 -+0x48DC US_ALU_RGB_INST_7 -+0x48E0 US_ALU_RGB_INST_8 -+0x48E4 US_ALU_RGB_INST_9 -+0x48E8 US_ALU_RGB_INST_10 -+0x48EC US_ALU_RGB_INST_11 -+0x48F0 US_ALU_RGB_INST_12 -+0x48F4 US_ALU_RGB_INST_13 -+0x48F8 US_ALU_RGB_INST_14 -+0x48FC US_ALU_RGB_INST_15 -+0x4900 US_ALU_RGB_INST_16 -+0x4904 US_ALU_RGB_INST_17 -+0x4908 US_ALU_RGB_INST_18 -+0x490C US_ALU_RGB_INST_19 -+0x4910 US_ALU_RGB_INST_20 -+0x4914 US_ALU_RGB_INST_21 -+0x4918 US_ALU_RGB_INST_22 -+0x491C US_ALU_RGB_INST_23 -+0x4920 US_ALU_RGB_INST_24 -+0x4924 US_ALU_RGB_INST_25 -+0x4928 US_ALU_RGB_INST_26 -+0x492C US_ALU_RGB_INST_27 -+0x4930 US_ALU_RGB_INST_28 -+0x4934 US_ALU_RGB_INST_29 -+0x4938 US_ALU_RGB_INST_30 -+0x493C US_ALU_RGB_INST_31 -+0x4940 US_ALU_RGB_INST_32 -+0x4944 US_ALU_RGB_INST_33 -+0x4948 US_ALU_RGB_INST_34 -+0x494C US_ALU_RGB_INST_35 -+0x4950 US_ALU_RGB_INST_36 -+0x4954 US_ALU_RGB_INST_37 -+0x4958 US_ALU_RGB_INST_38 -+0x495C US_ALU_RGB_INST_39 -+0x4960 US_ALU_RGB_INST_40 -+0x4964 US_ALU_RGB_INST_41 -+0x4968 US_ALU_RGB_INST_42 -+0x496C US_ALU_RGB_INST_43 -+0x4970 US_ALU_RGB_INST_44 -+0x4974 US_ALU_RGB_INST_45 -+0x4978 US_ALU_RGB_INST_46 -+0x497C US_ALU_RGB_INST_47 -+0x4980 US_ALU_RGB_INST_48 -+0x4984 US_ALU_RGB_INST_49 -+0x4988 US_ALU_RGB_INST_50 -+0x498C US_ALU_RGB_INST_51 -+0x4990 US_ALU_RGB_INST_52 -+0x4994 US_ALU_RGB_INST_53 -+0x4998 US_ALU_RGB_INST_54 -+0x499C US_ALU_RGB_INST_55 -+0x49A0 US_ALU_RGB_INST_56 -+0x49A4 US_ALU_RGB_INST_57 -+0x49A8 US_ALU_RGB_INST_58 -+0x49AC US_ALU_RGB_INST_59 -+0x49B0 US_ALU_RGB_INST_60 -+0x49B4 US_ALU_RGB_INST_61 -+0x49B8 US_ALU_RGB_INST_62 -+0x49BC US_ALU_RGB_INST_63 -+0x49C0 US_ALU_ALPHA_INST_0 -+0x49C4 US_ALU_ALPHA_INST_1 -+0x49C8 US_ALU_ALPHA_INST_2 -+0x49CC US_ALU_ALPHA_INST_3 -+0x49D0 US_ALU_ALPHA_INST_4 -+0x49D4 US_ALU_ALPHA_INST_5 -+0x49D8 US_ALU_ALPHA_INST_6 -+0x49DC US_ALU_ALPHA_INST_7 -+0x49E0 US_ALU_ALPHA_INST_8 -+0x49E4 US_ALU_ALPHA_INST_9 -+0x49E8 US_ALU_ALPHA_INST_10 -+0x49EC US_ALU_ALPHA_INST_11 -+0x49F0 US_ALU_ALPHA_INST_12 -+0x49F4 US_ALU_ALPHA_INST_13 -+0x49F8 US_ALU_ALPHA_INST_14 -+0x49FC US_ALU_ALPHA_INST_15 -+0x4A00 US_ALU_ALPHA_INST_16 -+0x4A04 US_ALU_ALPHA_INST_17 -+0x4A08 US_ALU_ALPHA_INST_18 -+0x4A0C US_ALU_ALPHA_INST_19 -+0x4A10 US_ALU_ALPHA_INST_20 -+0x4A14 US_ALU_ALPHA_INST_21 -+0x4A18 US_ALU_ALPHA_INST_22 -+0x4A1C US_ALU_ALPHA_INST_23 -+0x4A20 US_ALU_ALPHA_INST_24 -+0x4A24 US_ALU_ALPHA_INST_25 -+0x4A28 US_ALU_ALPHA_INST_26 -+0x4A2C US_ALU_ALPHA_INST_27 -+0x4A30 US_ALU_ALPHA_INST_28 -+0x4A34 US_ALU_ALPHA_INST_29 -+0x4A38 US_ALU_ALPHA_INST_30 -+0x4A3C US_ALU_ALPHA_INST_31 -+0x4A40 US_ALU_ALPHA_INST_32 -+0x4A44 US_ALU_ALPHA_INST_33 -+0x4A48 US_ALU_ALPHA_INST_34 -+0x4A4C US_ALU_ALPHA_INST_35 -+0x4A50 US_ALU_ALPHA_INST_36 -+0x4A54 US_ALU_ALPHA_INST_37 -+0x4A58 US_ALU_ALPHA_INST_38 -+0x4A5C US_ALU_ALPHA_INST_39 -+0x4A60 US_ALU_ALPHA_INST_40 -+0x4A64 US_ALU_ALPHA_INST_41 -+0x4A68 US_ALU_ALPHA_INST_42 -+0x4A6C US_ALU_ALPHA_INST_43 -+0x4A70 US_ALU_ALPHA_INST_44 -+0x4A74 US_ALU_ALPHA_INST_45 -+0x4A78 US_ALU_ALPHA_INST_46 -+0x4A7C US_ALU_ALPHA_INST_47 -+0x4A80 US_ALU_ALPHA_INST_48 -+0x4A84 US_ALU_ALPHA_INST_49 -+0x4A88 US_ALU_ALPHA_INST_50 -+0x4A8C US_ALU_ALPHA_INST_51 -+0x4A90 US_ALU_ALPHA_INST_52 -+0x4A94 US_ALU_ALPHA_INST_53 -+0x4A98 US_ALU_ALPHA_INST_54 -+0x4A9C US_ALU_ALPHA_INST_55 -+0x4AA0 US_ALU_ALPHA_INST_56 -+0x4AA4 US_ALU_ALPHA_INST_57 -+0x4AA8 US_ALU_ALPHA_INST_58 -+0x4AAC US_ALU_ALPHA_INST_59 -+0x4AB0 US_ALU_ALPHA_INST_60 -+0x4AB4 US_ALU_ALPHA_INST_61 -+0x4AB8 US_ALU_ALPHA_INST_62 -+0x4ABC US_ALU_ALPHA_INST_63 -+0x4BC0 FG_FOG_BLEND -+0x4BC4 FG_FOG_FACTOR -+0x4BC8 FG_FOG_COLOR_R -+0x4BCC FG_FOG_COLOR_G -+0x4BD0 FG_FOG_COLOR_B -+0x4BD4 FG_ALPHA_FUNC -+0x4BD8 FG_DEPTH_SRC -+0x4C00 US_ALU_CONST_R_0 -+0x4C04 US_ALU_CONST_G_0 -+0x4C08 US_ALU_CONST_B_0 -+0x4C0C US_ALU_CONST_A_0 -+0x4C10 US_ALU_CONST_R_1 -+0x4C14 US_ALU_CONST_G_1 -+0x4C18 US_ALU_CONST_B_1 -+0x4C1C US_ALU_CONST_A_1 -+0x4C20 US_ALU_CONST_R_2 -+0x4C24 US_ALU_CONST_G_2 -+0x4C28 US_ALU_CONST_B_2 -+0x4C2C US_ALU_CONST_A_2 -+0x4C30 US_ALU_CONST_R_3 -+0x4C34 US_ALU_CONST_G_3 -+0x4C38 US_ALU_CONST_B_3 -+0x4C3C US_ALU_CONST_A_3 -+0x4C40 US_ALU_CONST_R_4 -+0x4C44 US_ALU_CONST_G_4 -+0x4C48 US_ALU_CONST_B_4 -+0x4C4C US_ALU_CONST_A_4 -+0x4C50 US_ALU_CONST_R_5 -+0x4C54 US_ALU_CONST_G_5 -+0x4C58 US_ALU_CONST_B_5 -+0x4C5C US_ALU_CONST_A_5 -+0x4C60 US_ALU_CONST_R_6 -+0x4C64 US_ALU_CONST_G_6 -+0x4C68 US_ALU_CONST_B_6 -+0x4C6C US_ALU_CONST_A_6 -+0x4C70 US_ALU_CONST_R_7 -+0x4C74 US_ALU_CONST_G_7 -+0x4C78 US_ALU_CONST_B_7 -+0x4C7C US_ALU_CONST_A_7 -+0x4C80 US_ALU_CONST_R_8 -+0x4C84 US_ALU_CONST_G_8 -+0x4C88 US_ALU_CONST_B_8 -+0x4C8C US_ALU_CONST_A_8 -+0x4C90 US_ALU_CONST_R_9 -+0x4C94 US_ALU_CONST_G_9 -+0x4C98 US_ALU_CONST_B_9 -+0x4C9C US_ALU_CONST_A_9 -+0x4CA0 US_ALU_CONST_R_10 -+0x4CA4 US_ALU_CONST_G_10 -+0x4CA8 US_ALU_CONST_B_10 -+0x4CAC US_ALU_CONST_A_10 -+0x4CB0 US_ALU_CONST_R_11 -+0x4CB4 US_ALU_CONST_G_11 -+0x4CB8 US_ALU_CONST_B_11 -+0x4CBC US_ALU_CONST_A_11 -+0x4CC0 US_ALU_CONST_R_12 -+0x4CC4 US_ALU_CONST_G_12 -+0x4CC8 US_ALU_CONST_B_12 -+0x4CCC US_ALU_CONST_A_12 -+0x4CD0 US_ALU_CONST_R_13 -+0x4CD4 US_ALU_CONST_G_13 -+0x4CD8 US_ALU_CONST_B_13 -+0x4CDC US_ALU_CONST_A_13 -+0x4CE0 US_ALU_CONST_R_14 -+0x4CE4 US_ALU_CONST_G_14 -+0x4CE8 US_ALU_CONST_B_14 -+0x4CEC US_ALU_CONST_A_14 -+0x4CF0 US_ALU_CONST_R_15 -+0x4CF4 US_ALU_CONST_G_15 -+0x4CF8 US_ALU_CONST_B_15 -+0x4CFC US_ALU_CONST_A_15 -+0x4D00 US_ALU_CONST_R_16 -+0x4D04 US_ALU_CONST_G_16 -+0x4D08 US_ALU_CONST_B_16 -+0x4D0C US_ALU_CONST_A_16 -+0x4D10 US_ALU_CONST_R_17 -+0x4D14 US_ALU_CONST_G_17 -+0x4D18 US_ALU_CONST_B_17 -+0x4D1C US_ALU_CONST_A_17 -+0x4D20 US_ALU_CONST_R_18 -+0x4D24 US_ALU_CONST_G_18 -+0x4D28 US_ALU_CONST_B_18 -+0x4D2C US_ALU_CONST_A_18 -+0x4D30 US_ALU_CONST_R_19 -+0x4D34 US_ALU_CONST_G_19 -+0x4D38 US_ALU_CONST_B_19 -+0x4D3C US_ALU_CONST_A_19 -+0x4D40 US_ALU_CONST_R_20 -+0x4D44 US_ALU_CONST_G_20 -+0x4D48 US_ALU_CONST_B_20 -+0x4D4C US_ALU_CONST_A_20 -+0x4D50 US_ALU_CONST_R_21 -+0x4D54 US_ALU_CONST_G_21 -+0x4D58 US_ALU_CONST_B_21 -+0x4D5C US_ALU_CONST_A_21 -+0x4D60 US_ALU_CONST_R_22 -+0x4D64 US_ALU_CONST_G_22 -+0x4D68 US_ALU_CONST_B_22 -+0x4D6C US_ALU_CONST_A_22 -+0x4D70 US_ALU_CONST_R_23 -+0x4D74 US_ALU_CONST_G_23 -+0x4D78 US_ALU_CONST_B_23 -+0x4D7C US_ALU_CONST_A_23 -+0x4D80 US_ALU_CONST_R_24 -+0x4D84 US_ALU_CONST_G_24 -+0x4D88 US_ALU_CONST_B_24 -+0x4D8C US_ALU_CONST_A_24 -+0x4D90 US_ALU_CONST_R_25 -+0x4D94 US_ALU_CONST_G_25 -+0x4D98 US_ALU_CONST_B_25 -+0x4D9C US_ALU_CONST_A_25 -+0x4DA0 US_ALU_CONST_R_26 -+0x4DA4 US_ALU_CONST_G_26 -+0x4DA8 US_ALU_CONST_B_26 -+0x4DAC US_ALU_CONST_A_26 -+0x4DB0 US_ALU_CONST_R_27 -+0x4DB4 US_ALU_CONST_G_27 -+0x4DB8 US_ALU_CONST_B_27 -+0x4DBC US_ALU_CONST_A_27 -+0x4DC0 US_ALU_CONST_R_28 -+0x4DC4 US_ALU_CONST_G_28 -+0x4DC8 US_ALU_CONST_B_28 -+0x4DCC US_ALU_CONST_A_28 -+0x4DD0 US_ALU_CONST_R_29 -+0x4DD4 US_ALU_CONST_G_29 -+0x4DD8 US_ALU_CONST_B_29 -+0x4DDC US_ALU_CONST_A_29 -+0x4DE0 US_ALU_CONST_R_30 -+0x4DE4 US_ALU_CONST_G_30 -+0x4DE8 US_ALU_CONST_B_30 -+0x4DEC US_ALU_CONST_A_30 -+0x4DF0 US_ALU_CONST_R_31 -+0x4DF4 US_ALU_CONST_G_31 -+0x4DF8 US_ALU_CONST_B_31 -+0x4DFC US_ALU_CONST_A_31 -+0x4E04 RB3D_BLENDCNTL_R3 -+0x4E08 RB3D_ABLENDCNTL_R3 -+0x4E0C RB3D_COLOR_CHANNEL_MASK -+0x4E10 RB3D_CONSTANT_COLOR -+0x4E14 RB3D_COLOR_CLEAR_VALUE -+0x4E18 RB3D_ROPCNTL_R3 -+0x4E1C RB3D_CLRCMP_FLIPE_R3 -+0x4E20 RB3D_CLRCMP_CLR_R3 -+0x4E24 RB3D_CLRCMP_MSK_R3 -+0x4E48 RB3D_DEBUG_CTL -+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -+0x4E50 RB3D_DITHER_CTL -+0x4E54 RB3D_CMASK_OFFSET0 -+0x4E58 RB3D_CMASK_OFFSET1 -+0x4E5C RB3D_CMASK_OFFSET2 -+0x4E60 RB3D_CMASK_OFFSET3 -+0x4E64 RB3D_CMASK_PITCH0 -+0x4E68 RB3D_CMASK_PITCH1 -+0x4E6C RB3D_CMASK_PITCH2 -+0x4E70 RB3D_CMASK_PITCH3 -+0x4E74 RB3D_CMASK_WRINDEX -+0x4E78 RB3D_CMASK_DWORD -+0x4E7C RB3D_CMASK_RDINDEX -+0x4E80 RB3D_AARESOLVE_OFFSET -+0x4E84 RB3D_AARESOLVE_PITCH -+0x4E88 RB3D_AARESOLVE_CTL -+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -+0x4F04 ZB_ZSTENCILCNTL -+0x4F08 ZB_STENCILREFMASK -+0x4F14 ZB_ZTOP -+0x4F18 ZB_ZCACHE_CTLSTAT -+0x4F1C ZB_BW_CNTL -+0x4F28 ZB_DEPTHCLEARVALUE -+0x4F30 ZB_ZMASK_OFFSET -+0x4F34 ZB_ZMASK_PITCH -+0x4F38 ZB_ZMASK_WRINDEX -+0x4F3C ZB_ZMASK_DWORD -+0x4F40 ZB_ZMASK_RDINDEX -+0x4F44 ZB_HIZ_OFFSET -+0x4F48 ZB_HIZ_WRINDEX -+0x4F4C ZB_HIZ_DWORD -+0x4F50 ZB_HIZ_RDINDEX -+0x4F54 ZB_HIZ_PITCH -+0x4F58 ZB_ZPASS_DATA -diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 -new file mode 100644 -index 0000000..0102a0d ---- /dev/null -+++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 -@@ -0,0 +1,486 @@ -+rv515 0x6d40 -+0x1434 SRC_Y_X -+0x1438 DST_Y_X -+0x143C DST_HEIGHT_WIDTH -+0x146C DP_GUI_MASTER_CNTL -+0x1474 BRUSH_Y_X -+0x1478 DP_BRUSH_BKGD_CLR -+0x147C DP_BRUSH_FRGD_CLR -+0x1480 BRUSH_DATA0 -+0x1484 BRUSH_DATA1 -+0x1598 DST_WIDTH_HEIGHT -+0x15C0 CLR_CMP_CNTL -+0x15C4 CLR_CMP_CLR_SRC -+0x15C8 CLR_CMP_CLR_DST -+0x15CC CLR_CMP_MSK -+0x15D8 DP_SRC_FRGD_CLR -+0x15DC DP_SRC_BKGD_CLR -+0x1600 DST_LINE_START -+0x1604 DST_LINE_END -+0x1608 DST_LINE_PATCOUNT -+0x16C0 DP_CNTL -+0x16CC DP_WRITE_MSK -+0x16D0 DP_CNTL_XDIR_YDIR_YMAJOR -+0x16E8 DEFAULT_SC_BOTTOM_RIGHT -+0x16EC SC_TOP_LEFT -+0x16F0 SC_BOTTOM_RIGHT -+0x16F4 SRC_SC_BOTTOM_RIGHT -+0x1714 DSTCACHE_CTLSTAT -+0x1720 WAIT_UNTIL -+0x172C RBBM_GUICNTL -+0x1D98 VAP_VPORT_XSCALE -+0x1D9C VAP_VPORT_XOFFSET -+0x1DA0 VAP_VPORT_YSCALE -+0x1DA4 VAP_VPORT_YOFFSET -+0x1DA8 VAP_VPORT_ZSCALE -+0x1DAC VAP_VPORT_ZOFFSET -+0x2080 VAP_CNTL -+0x2090 VAP_OUT_VTX_FMT_0 -+0x2094 VAP_OUT_VTX_FMT_1 -+0x20B0 VAP_VTE_CNTL -+0x2138 VAP_VF_MIN_VTX_INDX -+0x2140 VAP_CNTL_STATUS -+0x2150 VAP_PROG_STREAM_CNTL_0 -+0x2154 VAP_PROG_STREAM_CNTL_1 -+0x2158 VAP_PROG_STREAM_CNTL_2 -+0x215C VAP_PROG_STREAM_CNTL_3 -+0x2160 VAP_PROG_STREAM_CNTL_4 -+0x2164 VAP_PROG_STREAM_CNTL_5 -+0x2168 VAP_PROG_STREAM_CNTL_6 -+0x216C VAP_PROG_STREAM_CNTL_7 -+0x2180 VAP_VTX_STATE_CNTL -+0x2184 VAP_VSM_VTX_ASSM -+0x2188 VAP_VTX_STATE_IND_REG_0 -+0x218C VAP_VTX_STATE_IND_REG_1 -+0x2190 VAP_VTX_STATE_IND_REG_2 -+0x2194 VAP_VTX_STATE_IND_REG_3 -+0x2198 VAP_VTX_STATE_IND_REG_4 -+0x219C VAP_VTX_STATE_IND_REG_5 -+0x21A0 VAP_VTX_STATE_IND_REG_6 -+0x21A4 VAP_VTX_STATE_IND_REG_7 -+0x21A8 VAP_VTX_STATE_IND_REG_8 -+0x21AC VAP_VTX_STATE_IND_REG_9 -+0x21B0 VAP_VTX_STATE_IND_REG_10 -+0x21B4 VAP_VTX_STATE_IND_REG_11 -+0x21B8 VAP_VTX_STATE_IND_REG_12 -+0x21BC VAP_VTX_STATE_IND_REG_13 -+0x21C0 VAP_VTX_STATE_IND_REG_14 -+0x21C4 VAP_VTX_STATE_IND_REG_15 -+0x21DC VAP_PSC_SGN_NORM_CNTL -+0x21E0 VAP_PROG_STREAM_CNTL_EXT_0 -+0x21E4 VAP_PROG_STREAM_CNTL_EXT_1 -+0x21E8 VAP_PROG_STREAM_CNTL_EXT_2 -+0x21EC VAP_PROG_STREAM_CNTL_EXT_3 -+0x21F0 VAP_PROG_STREAM_CNTL_EXT_4 -+0x21F4 VAP_PROG_STREAM_CNTL_EXT_5 -+0x21F8 VAP_PROG_STREAM_CNTL_EXT_6 -+0x21FC VAP_PROG_STREAM_CNTL_EXT_7 -+0x2200 VAP_PVS_VECTOR_INDX_REG -+0x2204 VAP_PVS_VECTOR_DATA_REG -+0x2208 VAP_PVS_VECTOR_DATA_REG_128 -+0x2218 VAP_TEX_TO_COLOR_CNTL -+0x221C VAP_CLIP_CNTL -+0x2220 VAP_GB_VERT_CLIP_ADJ -+0x2224 VAP_GB_VERT_DISC_ADJ -+0x2228 VAP_GB_HORZ_CLIP_ADJ -+0x222C VAP_GB_HORZ_DISC_ADJ -+0x2230 VAP_PVS_FLOW_CNTL_ADDRS_0 -+0x2234 VAP_PVS_FLOW_CNTL_ADDRS_1 -+0x2238 VAP_PVS_FLOW_CNTL_ADDRS_2 -+0x223C VAP_PVS_FLOW_CNTL_ADDRS_3 -+0x2240 VAP_PVS_FLOW_CNTL_ADDRS_4 -+0x2244 VAP_PVS_FLOW_CNTL_ADDRS_5 -+0x2248 VAP_PVS_FLOW_CNTL_ADDRS_6 -+0x224C VAP_PVS_FLOW_CNTL_ADDRS_7 -+0x2250 VAP_PVS_FLOW_CNTL_ADDRS_8 -+0x2254 VAP_PVS_FLOW_CNTL_ADDRS_9 -+0x2258 VAP_PVS_FLOW_CNTL_ADDRS_10 -+0x225C VAP_PVS_FLOW_CNTL_ADDRS_11 -+0x2260 VAP_PVS_FLOW_CNTL_ADDRS_12 -+0x2264 VAP_PVS_FLOW_CNTL_ADDRS_13 -+0x2268 VAP_PVS_FLOW_CNTL_ADDRS_14 -+0x226C VAP_PVS_FLOW_CNTL_ADDRS_15 -+0x2284 VAP_PVS_STATE_FLUSH_REG -+0x2288 VAP_PVS_VTX_TIMEOUT_REG -+0x2290 VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 -+0x2294 VAP_PVS_FLOW_CNTL_LOOP_INDEX_1 -+0x2298 VAP_PVS_FLOW_CNTL_LOOP_INDEX_2 -+0x229C VAP_PVS_FLOW_CNTL_LOOP_INDEX_3 -+0x22A0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_4 -+0x22A4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_5 -+0x22A8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_6 -+0x22AC VAP_PVS_FLOW_CNTL_LOOP_INDEX_7 -+0x22B0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_8 -+0x22B4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_9 -+0x22B8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_10 -+0x22BC VAP_PVS_FLOW_CNTL_LOOP_INDEX_11 -+0x22C0 VAP_PVS_FLOW_CNTL_LOOP_INDEX_12 -+0x22C4 VAP_PVS_FLOW_CNTL_LOOP_INDEX_13 -+0x22C8 VAP_PVS_FLOW_CNTL_LOOP_INDEX_14 -+0x22CC VAP_PVS_FLOW_CNTL_LOOP_INDEX_15 -+0x22D0 VAP_PVS_CODE_CNTL_0 -+0x22D4 VAP_PVS_CONST_CNTL -+0x22D8 VAP_PVS_CODE_CNTL_1 -+0x22DC VAP_PVS_FLOW_CNTL_OPC -+0x2500 VAP_PVS_FLOW_CNTL_ADDRS_LW_0 -+0x2504 VAP_PVS_FLOW_CNTL_ADDRS_UW_0 -+0x2508 VAP_PVS_FLOW_CNTL_ADDRS_LW_1 -+0x250C VAP_PVS_FLOW_CNTL_ADDRS_UW_1 -+0x2510 VAP_PVS_FLOW_CNTL_ADDRS_LW_2 -+0x2514 VAP_PVS_FLOW_CNTL_ADDRS_UW_2 -+0x2518 VAP_PVS_FLOW_CNTL_ADDRS_LW_3 -+0x251C VAP_PVS_FLOW_CNTL_ADDRS_UW_3 -+0x2520 VAP_PVS_FLOW_CNTL_ADDRS_LW_4 -+0x2524 VAP_PVS_FLOW_CNTL_ADDRS_UW_4 -+0x2528 VAP_PVS_FLOW_CNTL_ADDRS_LW_5 -+0x252C VAP_PVS_FLOW_CNTL_ADDRS_UW_5 -+0x2530 VAP_PVS_FLOW_CNTL_ADDRS_LW_6 -+0x2534 VAP_PVS_FLOW_CNTL_ADDRS_UW_6 -+0x2538 VAP_PVS_FLOW_CNTL_ADDRS_LW_7 -+0x253C VAP_PVS_FLOW_CNTL_ADDRS_UW_7 -+0x2540 VAP_PVS_FLOW_CNTL_ADDRS_LW_8 -+0x2544 VAP_PVS_FLOW_CNTL_ADDRS_UW_8 -+0x2548 VAP_PVS_FLOW_CNTL_ADDRS_LW_9 -+0x254C VAP_PVS_FLOW_CNTL_ADDRS_UW_9 -+0x2550 VAP_PVS_FLOW_CNTL_ADDRS_LW_10 -+0x2554 VAP_PVS_FLOW_CNTL_ADDRS_UW_10 -+0x2558 VAP_PVS_FLOW_CNTL_ADDRS_LW_11 -+0x255C VAP_PVS_FLOW_CNTL_ADDRS_UW_11 -+0x2560 VAP_PVS_FLOW_CNTL_ADDRS_LW_12 -+0x2564 VAP_PVS_FLOW_CNTL_ADDRS_UW_12 -+0x2568 VAP_PVS_FLOW_CNTL_ADDRS_LW_13 -+0x256C VAP_PVS_FLOW_CNTL_ADDRS_UW_13 -+0x2570 VAP_PVS_FLOW_CNTL_ADDRS_LW_14 -+0x2574 VAP_PVS_FLOW_CNTL_ADDRS_UW_14 -+0x2578 VAP_PVS_FLOW_CNTL_ADDRS_LW_15 -+0x257C VAP_PVS_FLOW_CNTL_ADDRS_UW_15 -+0x342C RB2D_DSTCACHE_CTLSTAT -+0x4000 GB_VAP_RASTER_VTX_FMT_0 -+0x4004 GB_VAP_RASTER_VTX_FMT_1 -+0x4008 GB_ENABLE -+0x401C GB_SELECT -+0x4020 GB_AA_CONFIG -+0x4024 GB_FIFO_SIZE -+0x4100 TX_INVALTAGS -+0x4200 GA_POINT_S0 -+0x4204 GA_POINT_T0 -+0x4208 GA_POINT_S1 -+0x420C GA_POINT_T1 -+0x4214 GA_TRIANGLE_STIPPLE -+0x421C GA_POINT_SIZE -+0x4230 GA_POINT_MINMAX -+0x4234 GA_LINE_CNTL -+0x4238 GA_LINE_STIPPLE_CONFIG -+0x4260 GA_LINE_STIPPLE_VALUE -+0x4264 GA_LINE_S0 -+0x4268 GA_LINE_S1 -+0x4278 GA_COLOR_CONTROL -+0x427C GA_SOLID_RG -+0x4280 GA_SOLID_BA -+0x4288 GA_POLY_MODE -+0x428C GA_ROUND_MODE -+0x4290 GA_OFFSET -+0x4294 GA_FOG_SCALE -+0x4298 GA_FOG_OFFSET -+0x42A0 SU_TEX_WRAP -+0x42A4 SU_POLY_OFFSET_FRONT_SCALE -+0x42A8 SU_POLY_OFFSET_FRONT_OFFSET -+0x42AC SU_POLY_OFFSET_BACK_SCALE -+0x42B0 SU_POLY_OFFSET_BACK_OFFSET -+0x42B4 SU_POLY_OFFSET_ENABLE -+0x42B8 SU_CULL_MODE -+0x42C0 SU_DEPTH_SCALE -+0x42C4 SU_DEPTH_OFFSET -+0x42C8 SU_REG_DEST -+0x4300 RS_COUNT -+0x4304 RS_INST_COUNT -+0x4074 RS_IP_0 -+0x4078 RS_IP_1 -+0x407C RS_IP_2 -+0x4080 RS_IP_3 -+0x4084 RS_IP_4 -+0x4088 RS_IP_5 -+0x408C RS_IP_6 -+0x4090 RS_IP_7 -+0x4094 RS_IP_8 -+0x4098 RS_IP_9 -+0x409C RS_IP_10 -+0x40A0 RS_IP_11 -+0x40A4 RS_IP_12 -+0x40A8 RS_IP_13 -+0x40AC RS_IP_14 -+0x40B0 RS_IP_15 -+0x4320 RS_INST_0 -+0x4324 RS_INST_1 -+0x4328 RS_INST_2 -+0x432C RS_INST_3 -+0x4330 RS_INST_4 -+0x4334 RS_INST_5 -+0x4338 RS_INST_6 -+0x433C RS_INST_7 -+0x4340 RS_INST_8 -+0x4344 RS_INST_9 -+0x4348 RS_INST_10 -+0x434C RS_INST_11 -+0x4350 RS_INST_12 -+0x4354 RS_INST_13 -+0x4358 RS_INST_14 -+0x435C RS_INST_15 -+0x43A4 SC_HYPERZ_EN -+0x43A8 SC_EDGERULE -+0x43B0 SC_CLIP_0_A -+0x43B4 SC_CLIP_0_B -+0x43B8 SC_CLIP_1_A -+0x43BC SC_CLIP_1_B -+0x43C0 SC_CLIP_2_A -+0x43C4 SC_CLIP_2_B -+0x43C8 SC_CLIP_3_A -+0x43CC SC_CLIP_3_B -+0x43D0 SC_CLIP_RULE -+0x43E0 SC_SCISSOR0 -+0x43E8 SC_SCREENDOOR -+0x4440 TX_FILTER1_0 -+0x4444 TX_FILTER1_1 -+0x4448 TX_FILTER1_2 -+0x444C TX_FILTER1_3 -+0x4450 TX_FILTER1_4 -+0x4454 TX_FILTER1_5 -+0x4458 TX_FILTER1_6 -+0x445C TX_FILTER1_7 -+0x4460 TX_FILTER1_8 -+0x4464 TX_FILTER1_9 -+0x4468 TX_FILTER1_10 -+0x446C TX_FILTER1_11 -+0x4470 TX_FILTER1_12 -+0x4474 TX_FILTER1_13 -+0x4478 TX_FILTER1_14 -+0x447C TX_FILTER1_15 -+0x4580 TX_CHROMA_KEY_0 -+0x4584 TX_CHROMA_KEY_1 -+0x4588 TX_CHROMA_KEY_2 -+0x458C TX_CHROMA_KEY_3 -+0x4590 TX_CHROMA_KEY_4 -+0x4594 TX_CHROMA_KEY_5 -+0x4598 TX_CHROMA_KEY_6 -+0x459C TX_CHROMA_KEY_7 -+0x45A0 TX_CHROMA_KEY_8 -+0x45A4 TX_CHROMA_KEY_9 -+0x45A8 TX_CHROMA_KEY_10 -+0x45AC TX_CHROMA_KEY_11 -+0x45B0 TX_CHROMA_KEY_12 -+0x45B4 TX_CHROMA_KEY_13 -+0x45B8 TX_CHROMA_KEY_14 -+0x45BC TX_CHROMA_KEY_15 -+0x45C0 TX_BORDER_COLOR_0 -+0x45C4 TX_BORDER_COLOR_1 -+0x45C8 TX_BORDER_COLOR_2 -+0x45CC TX_BORDER_COLOR_3 -+0x45D0 TX_BORDER_COLOR_4 -+0x45D4 TX_BORDER_COLOR_5 -+0x45D8 TX_BORDER_COLOR_6 -+0x45DC TX_BORDER_COLOR_7 -+0x45E0 TX_BORDER_COLOR_8 -+0x45E4 TX_BORDER_COLOR_9 -+0x45E8 TX_BORDER_COLOR_10 -+0x45EC TX_BORDER_COLOR_11 -+0x45F0 TX_BORDER_COLOR_12 -+0x45F4 TX_BORDER_COLOR_13 -+0x45F8 TX_BORDER_COLOR_14 -+0x45FC TX_BORDER_COLOR_15 -+0x4250 GA_US_VECTOR_INDEX -+0x4254 GA_US_VECTOR_DATA -+0x4600 US_CONFIG -+0x4604 US_PIXSIZE -+0x4620 US_FC_BOOL_CONST -+0x4624 US_FC_CTRL -+0x4630 US_CODE_ADDR -+0x4634 US_CODE_RANGE -+0x4638 US_CODE_OFFSET -+0x46A4 US_OUT_FMT_0 -+0x46A8 US_OUT_FMT_1 -+0x46AC US_OUT_FMT_2 -+0x46B0 US_OUT_FMT_3 -+0x46B4 US_W_FMT -+0x4BC0 FG_FOG_BLEND -+0x4BC4 FG_FOG_FACTOR -+0x4BC8 FG_FOG_COLOR_R -+0x4BCC FG_FOG_COLOR_G -+0x4BD0 FG_FOG_COLOR_B -+0x4BD4 FG_ALPHA_FUNC -+0x4BD8 FG_DEPTH_SRC -+0x4C00 US_ALU_CONST_R_0 -+0x4C04 US_ALU_CONST_G_0 -+0x4C08 US_ALU_CONST_B_0 -+0x4C0C US_ALU_CONST_A_0 -+0x4C10 US_ALU_CONST_R_1 -+0x4C14 US_ALU_CONST_G_1 -+0x4C18 US_ALU_CONST_B_1 -+0x4C1C US_ALU_CONST_A_1 -+0x4C20 US_ALU_CONST_R_2 -+0x4C24 US_ALU_CONST_G_2 -+0x4C28 US_ALU_CONST_B_2 -+0x4C2C US_ALU_CONST_A_2 -+0x4C30 US_ALU_CONST_R_3 -+0x4C34 US_ALU_CONST_G_3 -+0x4C38 US_ALU_CONST_B_3 -+0x4C3C US_ALU_CONST_A_3 -+0x4C40 US_ALU_CONST_R_4 -+0x4C44 US_ALU_CONST_G_4 -+0x4C48 US_ALU_CONST_B_4 -+0x4C4C US_ALU_CONST_A_4 -+0x4C50 US_ALU_CONST_R_5 -+0x4C54 US_ALU_CONST_G_5 -+0x4C58 US_ALU_CONST_B_5 -+0x4C5C US_ALU_CONST_A_5 -+0x4C60 US_ALU_CONST_R_6 -+0x4C64 US_ALU_CONST_G_6 -+0x4C68 US_ALU_CONST_B_6 -+0x4C6C US_ALU_CONST_A_6 -+0x4C70 US_ALU_CONST_R_7 -+0x4C74 US_ALU_CONST_G_7 -+0x4C78 US_ALU_CONST_B_7 -+0x4C7C US_ALU_CONST_A_7 -+0x4C80 US_ALU_CONST_R_8 -+0x4C84 US_ALU_CONST_G_8 -+0x4C88 US_ALU_CONST_B_8 -+0x4C8C US_ALU_CONST_A_8 -+0x4C90 US_ALU_CONST_R_9 -+0x4C94 US_ALU_CONST_G_9 -+0x4C98 US_ALU_CONST_B_9 -+0x4C9C US_ALU_CONST_A_9 -+0x4CA0 US_ALU_CONST_R_10 -+0x4CA4 US_ALU_CONST_G_10 -+0x4CA8 US_ALU_CONST_B_10 -+0x4CAC US_ALU_CONST_A_10 -+0x4CB0 US_ALU_CONST_R_11 -+0x4CB4 US_ALU_CONST_G_11 -+0x4CB8 US_ALU_CONST_B_11 -+0x4CBC US_ALU_CONST_A_11 -+0x4CC0 US_ALU_CONST_R_12 -+0x4CC4 US_ALU_CONST_G_12 -+0x4CC8 US_ALU_CONST_B_12 -+0x4CCC US_ALU_CONST_A_12 -+0x4CD0 US_ALU_CONST_R_13 -+0x4CD4 US_ALU_CONST_G_13 -+0x4CD8 US_ALU_CONST_B_13 -+0x4CDC US_ALU_CONST_A_13 -+0x4CE0 US_ALU_CONST_R_14 -+0x4CE4 US_ALU_CONST_G_14 -+0x4CE8 US_ALU_CONST_B_14 -+0x4CEC US_ALU_CONST_A_14 -+0x4CF0 US_ALU_CONST_R_15 -+0x4CF4 US_ALU_CONST_G_15 -+0x4CF8 US_ALU_CONST_B_15 -+0x4CFC US_ALU_CONST_A_15 -+0x4D00 US_ALU_CONST_R_16 -+0x4D04 US_ALU_CONST_G_16 -+0x4D08 US_ALU_CONST_B_16 -+0x4D0C US_ALU_CONST_A_16 -+0x4D10 US_ALU_CONST_R_17 -+0x4D14 US_ALU_CONST_G_17 -+0x4D18 US_ALU_CONST_B_17 -+0x4D1C US_ALU_CONST_A_17 -+0x4D20 US_ALU_CONST_R_18 -+0x4D24 US_ALU_CONST_G_18 -+0x4D28 US_ALU_CONST_B_18 -+0x4D2C US_ALU_CONST_A_18 -+0x4D30 US_ALU_CONST_R_19 -+0x4D34 US_ALU_CONST_G_19 -+0x4D38 US_ALU_CONST_B_19 -+0x4D3C US_ALU_CONST_A_19 -+0x4D40 US_ALU_CONST_R_20 -+0x4D44 US_ALU_CONST_G_20 -+0x4D48 US_ALU_CONST_B_20 -+0x4D4C US_ALU_CONST_A_20 -+0x4D50 US_ALU_CONST_R_21 -+0x4D54 US_ALU_CONST_G_21 -+0x4D58 US_ALU_CONST_B_21 -+0x4D5C US_ALU_CONST_A_21 -+0x4D60 US_ALU_CONST_R_22 -+0x4D64 US_ALU_CONST_G_22 -+0x4D68 US_ALU_CONST_B_22 -+0x4D6C US_ALU_CONST_A_22 -+0x4D70 US_ALU_CONST_R_23 -+0x4D74 US_ALU_CONST_G_23 -+0x4D78 US_ALU_CONST_B_23 -+0x4D7C US_ALU_CONST_A_23 -+0x4D80 US_ALU_CONST_R_24 -+0x4D84 US_ALU_CONST_G_24 -+0x4D88 US_ALU_CONST_B_24 -+0x4D8C US_ALU_CONST_A_24 -+0x4D90 US_ALU_CONST_R_25 -+0x4D94 US_ALU_CONST_G_25 -+0x4D98 US_ALU_CONST_B_25 -+0x4D9C US_ALU_CONST_A_25 -+0x4DA0 US_ALU_CONST_R_26 -+0x4DA4 US_ALU_CONST_G_26 -+0x4DA8 US_ALU_CONST_B_26 -+0x4DAC US_ALU_CONST_A_26 -+0x4DB0 US_ALU_CONST_R_27 -+0x4DB4 US_ALU_CONST_G_27 -+0x4DB8 US_ALU_CONST_B_27 -+0x4DBC US_ALU_CONST_A_27 -+0x4DC0 US_ALU_CONST_R_28 -+0x4DC4 US_ALU_CONST_G_28 -+0x4DC8 US_ALU_CONST_B_28 -+0x4DCC US_ALU_CONST_A_28 -+0x4DD0 US_ALU_CONST_R_29 -+0x4DD4 US_ALU_CONST_G_29 -+0x4DD8 US_ALU_CONST_B_29 -+0x4DDC US_ALU_CONST_A_29 -+0x4DE0 US_ALU_CONST_R_30 -+0x4DE4 US_ALU_CONST_G_30 -+0x4DE8 US_ALU_CONST_B_30 -+0x4DEC US_ALU_CONST_A_30 -+0x4DF0 US_ALU_CONST_R_31 -+0x4DF4 US_ALU_CONST_G_31 -+0x4DF8 US_ALU_CONST_B_31 -+0x4DFC US_ALU_CONST_A_31 -+0x4E04 RB3D_BLENDCNTL_R3 -+0x4E08 RB3D_ABLENDCNTL_R3 -+0x4E0C RB3D_COLOR_CHANNEL_MASK -+0x4E10 RB3D_CONSTANT_COLOR -+0x4E14 RB3D_COLOR_CLEAR_VALUE -+0x4E18 RB3D_ROPCNTL_R3 -+0x4E1C RB3D_CLRCMP_FLIPE_R3 -+0x4E20 RB3D_CLRCMP_CLR_R3 -+0x4E24 RB3D_CLRCMP_MSK_R3 -+0x4E48 RB3D_DEBUG_CTL -+0x4E4C RB3D_DSTCACHE_CTLSTAT_R3 -+0x4E50 RB3D_DITHER_CTL -+0x4E54 RB3D_CMASK_OFFSET0 -+0x4E58 RB3D_CMASK_OFFSET1 -+0x4E5C RB3D_CMASK_OFFSET2 -+0x4E60 RB3D_CMASK_OFFSET3 -+0x4E64 RB3D_CMASK_PITCH0 -+0x4E68 RB3D_CMASK_PITCH1 -+0x4E6C RB3D_CMASK_PITCH2 -+0x4E70 RB3D_CMASK_PITCH3 -+0x4E74 RB3D_CMASK_WRINDEX -+0x4E78 RB3D_CMASK_DWORD -+0x4E7C RB3D_CMASK_RDINDEX -+0x4E80 RB3D_AARESOLVE_OFFSET -+0x4E84 RB3D_AARESOLVE_PITCH -+0x4E88 RB3D_AARESOLVE_CTL -+0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD -+0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD -+0x4EF8 RB3D_CONSTANT_COLOR_AR -+0x4EFC RB3D_CONSTANT_COLOR_GB -+0x4F04 ZB_ZSTENCILCNTL -+0x4F08 ZB_STENCILREFMASK -+0x4F14 ZB_ZTOP -+0x4F18 ZB_ZCACHE_CTLSTAT -+0x4F1C ZB_BW_CNTL -+0x4F28 ZB_DEPTHCLEARVALUE -+0x4F30 ZB_ZMASK_OFFSET -+0x4F34 ZB_ZMASK_PITCH -+0x4F38 ZB_ZMASK_WRINDEX -+0x4F3C ZB_ZMASK_DWORD -+0x4F40 ZB_ZMASK_RDINDEX -+0x4F44 ZB_HIZ_OFFSET -+0x4F48 ZB_HIZ_WRINDEX -+0x4F4C ZB_HIZ_DWORD -+0x4F50 ZB_HIZ_RDINDEX -+0x4F54 ZB_HIZ_PITCH -+0x4F58 ZB_ZPASS_DATA -+0x4FD4 ZB_STENCILREFMASK_BF -diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c -index b29affd..8c3ea7e 100644 ---- a/drivers/gpu/drm/radeon/rs400.c -+++ b/drivers/gpu/drm/radeon/rs400.c -@@ -63,7 +63,7 @@ void rs400_gart_adjust_size(struct radeon_device *rdev) - break; - default: - DRM_ERROR("Unable to use IGP GART size %uM\n", -- rdev->mc.gtt_size >> 20); -+ (unsigned)(rdev->mc.gtt_size >> 20)); - DRM_ERROR("Valid GART size for IGP are 32M,64M,128M,256M,512M,1G,2G\n"); - DRM_ERROR("Forcing to 32M GART size\n"); - rdev->mc.gtt_size = 32 * 1024 * 1024; -diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c -index 02fd11a..1b8d62f 100644 ---- a/drivers/gpu/drm/radeon/rs600.c -+++ b/drivers/gpu/drm/radeon/rs600.c -@@ -29,6 +29,8 @@ - #include "radeon_reg.h" - #include "radeon.h" - -+#include "rs600_reg_safe.h" -+ - /* rs600 depends on : */ - void r100_hdp_reset(struct radeon_device *rdev); - int r100_gui_wait_for_idle(struct radeon_device *rdev); -@@ -410,64 +412,6 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) - WREG32(RS600_MC_DATA, v); - } - --static const unsigned rs600_reg_safe_bm[219] = { -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF, -- 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, -- 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, -- 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF, -- 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -- 0x00000000, 0x0000C100, 0x00000000, 0x00000000, -- 0x00000000, 0x00000000, 0x00000000, 0x00000000, -- 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, -- 0x00000000, 0x00000000, 0x00000000, 0x00000000, -- 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, --}; -- - int rs600_init(struct radeon_device *rdev) - { - rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; -diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c -index 8798825..839595b 100644 ---- a/drivers/gpu/drm/radeon/rs690.c -+++ b/drivers/gpu/drm/radeon/rs690.c -@@ -652,4 +652,3 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) - WREG32(RS690_MC_DATA, v); - WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); - } -- -diff --git a/drivers/gpu/drm/radeon/rs780.c b/drivers/gpu/drm/radeon/rs780.c -deleted file mode 100644 -index 0affcff..0000000 ---- a/drivers/gpu/drm/radeon/rs780.c -+++ /dev/null -@@ -1,102 +0,0 @@ --/* -- * Copyright 2008 Advanced Micro Devices, Inc. -- * Copyright 2008 Red Hat Inc. -- * Copyright 2009 Jerome Glisse. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -- * -- * Authors: Dave Airlie -- * Alex Deucher -- * Jerome Glisse -- */ --#include "drmP.h" --#include "radeon_reg.h" --#include "radeon.h" -- --/* rs780 depends on : */ --void rs600_mc_disable_clients(struct radeon_device *rdev); -- --/* This files gather functions specifics to: -- * rs780 -- * -- * Some of these functions might be used by newer ASICs. -- */ --int rs780_mc_wait_for_idle(struct radeon_device *rdev); --void rs780_gpu_init(struct radeon_device *rdev); -- -- --/* -- * MC -- */ --int rs780_mc_init(struct radeon_device *rdev) --{ -- rs780_gpu_init(rdev); -- /* FIXME: implement */ -- -- rs600_mc_disable_clients(rdev); -- if (rs780_mc_wait_for_idle(rdev)) { -- printk(KERN_WARNING "Failed to wait MC idle while " -- "programming pipes. Bad things might happen.\n"); -- } -- return 0; --} -- --void rs780_mc_fini(struct radeon_device *rdev) --{ -- /* FIXME: implement */ --} -- -- --/* -- * Global GPU functions -- */ --void rs780_errata(struct radeon_device *rdev) --{ -- rdev->pll_errata = 0; --} -- --int rs780_mc_wait_for_idle(struct radeon_device *rdev) --{ -- /* FIXME: implement */ -- return 0; --} -- --void rs780_gpu_init(struct radeon_device *rdev) --{ -- /* FIXME: implement */ --} -- -- --/* -- * VRAM info -- */ --void rs780_vram_get_type(struct radeon_device *rdev) --{ -- /* FIXME: implement */ --} -- --void rs780_vram_info(struct radeon_device *rdev) --{ -- rs780_vram_get_type(rdev); -- -- /* FIXME: implement */ -- /* Could aper size report 0 ? */ -- rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); -- rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); --} -diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c -index 0566fb6..99e397f 100644 ---- a/drivers/gpu/drm/radeon/rv515.c -+++ b/drivers/gpu/drm/radeon/rv515.c -@@ -27,10 +27,11 @@ - */ - #include - #include "drmP.h" --#include "rv515r.h" -+#include "rv515d.h" - #include "radeon.h" - #include "radeon_share.h" - -+#include "rv515_reg_safe.h" - /* rv515 depends on : */ - void r100_hdp_reset(struct radeon_device *rdev); - int r100_cp_reset(struct radeon_device *rdev); -@@ -464,301 +465,244 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) - #endif - } - -- - /* - * Asic initialization - */ --static const unsigned r500_reg_safe_bm[219] = { -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF, -- 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, -- 0xF0000038, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0x1FFFFC78, 0xFFFFE000, 0xFFFFFFFE, 0xFFFFFFFF, -- 0x38CF8F50, 0xFFF88082, 0xFF0000FC, 0xFAE009FF, -- 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, -- 0xFFFF8CFC, 0xFFFFC1FF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, -- 0x00000000, 0x00000000, 0x00000000, 0x00000000, -- 0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -- 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, --}; -- - int rv515_init(struct radeon_device *rdev) - { -- rdev->config.r300.reg_safe_bm = r500_reg_safe_bm; -- rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r500_reg_safe_bm); -+ rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; -+ rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); - return 0; - } - --void atom_rv515_force_tv_scaler(struct radeon_device *rdev) -+void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) - { -- -- WREG32(0x659C, 0x0); -- WREG32(0x6594, 0x705); -- WREG32(0x65A4, 0x10001); -- WREG32(0x65D8, 0x0); -- WREG32(0x65B0, 0x0); -- WREG32(0x65C0, 0x0); -- WREG32(0x65D4, 0x0); -- WREG32(0x6578, 0x0); -- WREG32(0x657C, 0x841880A8); -- WREG32(0x6578, 0x1); -- WREG32(0x657C, 0x84208680); -- WREG32(0x6578, 0x2); -- WREG32(0x657C, 0xBFF880B0); -- WREG32(0x6578, 0x100); -- WREG32(0x657C, 0x83D88088); -- WREG32(0x6578, 0x101); -- WREG32(0x657C, 0x84608680); -- WREG32(0x6578, 0x102); -- WREG32(0x657C, 0xBFF080D0); -- WREG32(0x6578, 0x200); -- WREG32(0x657C, 0x83988068); -- WREG32(0x6578, 0x201); -- WREG32(0x657C, 0x84A08680); -- WREG32(0x6578, 0x202); -- WREG32(0x657C, 0xBFF080F8); -- WREG32(0x6578, 0x300); -- WREG32(0x657C, 0x83588058); -- WREG32(0x6578, 0x301); -- WREG32(0x657C, 0x84E08660); -- WREG32(0x6578, 0x302); -- WREG32(0x657C, 0xBFF88120); -- WREG32(0x6578, 0x400); -- WREG32(0x657C, 0x83188040); -- WREG32(0x6578, 0x401); -- WREG32(0x657C, 0x85008660); -- WREG32(0x6578, 0x402); -- WREG32(0x657C, 0xBFF88150); -- WREG32(0x6578, 0x500); -- WREG32(0x657C, 0x82D88030); -- WREG32(0x6578, 0x501); -- WREG32(0x657C, 0x85408640); -- WREG32(0x6578, 0x502); -- WREG32(0x657C, 0xBFF88180); -- WREG32(0x6578, 0x600); -- WREG32(0x657C, 0x82A08018); -- WREG32(0x6578, 0x601); -- WREG32(0x657C, 0x85808620); -- WREG32(0x6578, 0x602); -- WREG32(0x657C, 0xBFF081B8); -- WREG32(0x6578, 0x700); -- WREG32(0x657C, 0x82608010); -- WREG32(0x6578, 0x701); -- WREG32(0x657C, 0x85A08600); -- WREG32(0x6578, 0x702); -- WREG32(0x657C, 0x800081F0); -- WREG32(0x6578, 0x800); -- WREG32(0x657C, 0x8228BFF8); -- WREG32(0x6578, 0x801); -- WREG32(0x657C, 0x85E085E0); -- WREG32(0x6578, 0x802); -- WREG32(0x657C, 0xBFF88228); -- WREG32(0x6578, 0x10000); -- WREG32(0x657C, 0x82A8BF00); -- WREG32(0x6578, 0x10001); -- WREG32(0x657C, 0x82A08CC0); -- WREG32(0x6578, 0x10002); -- WREG32(0x657C, 0x8008BEF8); -- WREG32(0x6578, 0x10100); -- WREG32(0x657C, 0x81F0BF28); -- WREG32(0x6578, 0x10101); -- WREG32(0x657C, 0x83608CA0); -- WREG32(0x6578, 0x10102); -- WREG32(0x657C, 0x8018BED0); -- WREG32(0x6578, 0x10200); -- WREG32(0x657C, 0x8148BF38); -- WREG32(0x6578, 0x10201); -- WREG32(0x657C, 0x84408C80); -- WREG32(0x6578, 0x10202); -- WREG32(0x657C, 0x8008BEB8); -- WREG32(0x6578, 0x10300); -- WREG32(0x657C, 0x80B0BF78); -- WREG32(0x6578, 0x10301); -- WREG32(0x657C, 0x85008C20); -- WREG32(0x6578, 0x10302); -- WREG32(0x657C, 0x8020BEA0); -- WREG32(0x6578, 0x10400); -- WREG32(0x657C, 0x8028BF90); -- WREG32(0x6578, 0x10401); -- WREG32(0x657C, 0x85E08BC0); -- WREG32(0x6578, 0x10402); -- WREG32(0x657C, 0x8018BE90); -- WREG32(0x6578, 0x10500); -- WREG32(0x657C, 0xBFB8BFB0); -- WREG32(0x6578, 0x10501); -- WREG32(0x657C, 0x86C08B40); -- WREG32(0x6578, 0x10502); -- WREG32(0x657C, 0x8010BE90); -- WREG32(0x6578, 0x10600); -- WREG32(0x657C, 0xBF58BFC8); -- WREG32(0x6578, 0x10601); -- WREG32(0x657C, 0x87A08AA0); -- WREG32(0x6578, 0x10602); -- WREG32(0x657C, 0x8010BE98); -- WREG32(0x6578, 0x10700); -- WREG32(0x657C, 0xBF10BFF0); -- WREG32(0x6578, 0x10701); -- WREG32(0x657C, 0x886089E0); -- WREG32(0x6578, 0x10702); -- WREG32(0x657C, 0x8018BEB0); -- WREG32(0x6578, 0x10800); -- WREG32(0x657C, 0xBED8BFE8); -- WREG32(0x6578, 0x10801); -- WREG32(0x657C, 0x89408940); -- WREG32(0x6578, 0x10802); -- WREG32(0x657C, 0xBFE8BED8); -- WREG32(0x6578, 0x20000); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20001); -- WREG32(0x657C, 0x90008000); -- WREG32(0x6578, 0x20002); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20003); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20100); -- WREG32(0x657C, 0x80108000); -- WREG32(0x6578, 0x20101); -- WREG32(0x657C, 0x8FE0BF70); -- WREG32(0x6578, 0x20102); -- WREG32(0x657C, 0xBFE880C0); -- WREG32(0x6578, 0x20103); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20200); -- WREG32(0x657C, 0x8018BFF8); -- WREG32(0x6578, 0x20201); -- WREG32(0x657C, 0x8F80BF08); -- WREG32(0x6578, 0x20202); -- WREG32(0x657C, 0xBFD081A0); -- WREG32(0x6578, 0x20203); -- WREG32(0x657C, 0xBFF88000); -- WREG32(0x6578, 0x20300); -- WREG32(0x657C, 0x80188000); -- WREG32(0x6578, 0x20301); -- WREG32(0x657C, 0x8EE0BEC0); -- WREG32(0x6578, 0x20302); -- WREG32(0x657C, 0xBFB082A0); -- WREG32(0x6578, 0x20303); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20400); -- WREG32(0x657C, 0x80188000); -- WREG32(0x6578, 0x20401); -- WREG32(0x657C, 0x8E00BEA0); -- WREG32(0x6578, 0x20402); -- WREG32(0x657C, 0xBF8883C0); -- WREG32(0x6578, 0x20403); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x20500); -- WREG32(0x657C, 0x80188000); -- WREG32(0x6578, 0x20501); -- WREG32(0x657C, 0x8D00BE90); -- WREG32(0x6578, 0x20502); -- WREG32(0x657C, 0xBF588500); -- WREG32(0x6578, 0x20503); -- WREG32(0x657C, 0x80008008); -- WREG32(0x6578, 0x20600); -- WREG32(0x657C, 0x80188000); -- WREG32(0x6578, 0x20601); -- WREG32(0x657C, 0x8BC0BE98); -- WREG32(0x6578, 0x20602); -- WREG32(0x657C, 0xBF308660); -- WREG32(0x6578, 0x20603); -- WREG32(0x657C, 0x80008008); -- WREG32(0x6578, 0x20700); -- WREG32(0x657C, 0x80108000); -- WREG32(0x6578, 0x20701); -- WREG32(0x657C, 0x8A80BEB0); -- WREG32(0x6578, 0x20702); -- WREG32(0x657C, 0xBF0087C0); -- WREG32(0x6578, 0x20703); -- WREG32(0x657C, 0x80008008); -- WREG32(0x6578, 0x20800); -- WREG32(0x657C, 0x80108000); -- WREG32(0x6578, 0x20801); -- WREG32(0x657C, 0x8920BED0); -- WREG32(0x6578, 0x20802); -- WREG32(0x657C, 0xBED08920); -- WREG32(0x6578, 0x20803); -- WREG32(0x657C, 0x80008010); -- WREG32(0x6578, 0x30000); -- WREG32(0x657C, 0x90008000); -- WREG32(0x6578, 0x30001); -- WREG32(0x657C, 0x80008000); -- WREG32(0x6578, 0x30100); -- WREG32(0x657C, 0x8FE0BF90); -- WREG32(0x6578, 0x30101); -- WREG32(0x657C, 0xBFF880A0); -- WREG32(0x6578, 0x30200); -- WREG32(0x657C, 0x8F60BF40); -- WREG32(0x6578, 0x30201); -- WREG32(0x657C, 0xBFE88180); -- WREG32(0x6578, 0x30300); -- WREG32(0x657C, 0x8EC0BF00); -- WREG32(0x6578, 0x30301); -- WREG32(0x657C, 0xBFC88280); -- WREG32(0x6578, 0x30400); -- WREG32(0x657C, 0x8DE0BEE0); -- WREG32(0x6578, 0x30401); -- WREG32(0x657C, 0xBFA083A0); -- WREG32(0x6578, 0x30500); -- WREG32(0x657C, 0x8CE0BED0); -- WREG32(0x6578, 0x30501); -- WREG32(0x657C, 0xBF7884E0); -- WREG32(0x6578, 0x30600); -- WREG32(0x657C, 0x8BA0BED8); -- WREG32(0x6578, 0x30601); -- WREG32(0x657C, 0xBF508640); -- WREG32(0x6578, 0x30700); -- WREG32(0x657C, 0x8A60BEE8); -- WREG32(0x6578, 0x30701); -- WREG32(0x657C, 0xBF2087A0); -- WREG32(0x6578, 0x30800); -- WREG32(0x657C, 0x8900BF00); -- WREG32(0x6578, 0x30801); -- WREG32(0x657C, 0xBF008900); -+ int index_reg = 0x6578 + crtc->crtc_offset; -+ int data_reg = 0x657c + crtc->crtc_offset; -+ -+ WREG32(0x659C + crtc->crtc_offset, 0x0); -+ WREG32(0x6594 + crtc->crtc_offset, 0x705); -+ WREG32(0x65A4 + crtc->crtc_offset, 0x10001); -+ WREG32(0x65D8 + crtc->crtc_offset, 0x0); -+ WREG32(0x65B0 + crtc->crtc_offset, 0x0); -+ WREG32(0x65C0 + crtc->crtc_offset, 0x0); -+ WREG32(0x65D4 + crtc->crtc_offset, 0x0); -+ WREG32(index_reg, 0x0); -+ WREG32(data_reg, 0x841880A8); -+ WREG32(index_reg, 0x1); -+ WREG32(data_reg, 0x84208680); -+ WREG32(index_reg, 0x2); -+ WREG32(data_reg, 0xBFF880B0); -+ WREG32(index_reg, 0x100); -+ WREG32(data_reg, 0x83D88088); -+ WREG32(index_reg, 0x101); -+ WREG32(data_reg, 0x84608680); -+ WREG32(index_reg, 0x102); -+ WREG32(data_reg, 0xBFF080D0); -+ WREG32(index_reg, 0x200); -+ WREG32(data_reg, 0x83988068); -+ WREG32(index_reg, 0x201); -+ WREG32(data_reg, 0x84A08680); -+ WREG32(index_reg, 0x202); -+ WREG32(data_reg, 0xBFF080F8); -+ WREG32(index_reg, 0x300); -+ WREG32(data_reg, 0x83588058); -+ WREG32(index_reg, 0x301); -+ WREG32(data_reg, 0x84E08660); -+ WREG32(index_reg, 0x302); -+ WREG32(data_reg, 0xBFF88120); -+ WREG32(index_reg, 0x400); -+ WREG32(data_reg, 0x83188040); -+ WREG32(index_reg, 0x401); -+ WREG32(data_reg, 0x85008660); -+ WREG32(index_reg, 0x402); -+ WREG32(data_reg, 0xBFF88150); -+ WREG32(index_reg, 0x500); -+ WREG32(data_reg, 0x82D88030); -+ WREG32(index_reg, 0x501); -+ WREG32(data_reg, 0x85408640); -+ WREG32(index_reg, 0x502); -+ WREG32(data_reg, 0xBFF88180); -+ WREG32(index_reg, 0x600); -+ WREG32(data_reg, 0x82A08018); -+ WREG32(index_reg, 0x601); -+ WREG32(data_reg, 0x85808620); -+ WREG32(index_reg, 0x602); -+ WREG32(data_reg, 0xBFF081B8); -+ WREG32(index_reg, 0x700); -+ WREG32(data_reg, 0x82608010); -+ WREG32(index_reg, 0x701); -+ WREG32(data_reg, 0x85A08600); -+ WREG32(index_reg, 0x702); -+ WREG32(data_reg, 0x800081F0); -+ WREG32(index_reg, 0x800); -+ WREG32(data_reg, 0x8228BFF8); -+ WREG32(index_reg, 0x801); -+ WREG32(data_reg, 0x85E085E0); -+ WREG32(index_reg, 0x802); -+ WREG32(data_reg, 0xBFF88228); -+ WREG32(index_reg, 0x10000); -+ WREG32(data_reg, 0x82A8BF00); -+ WREG32(index_reg, 0x10001); -+ WREG32(data_reg, 0x82A08CC0); -+ WREG32(index_reg, 0x10002); -+ WREG32(data_reg, 0x8008BEF8); -+ WREG32(index_reg, 0x10100); -+ WREG32(data_reg, 0x81F0BF28); -+ WREG32(index_reg, 0x10101); -+ WREG32(data_reg, 0x83608CA0); -+ WREG32(index_reg, 0x10102); -+ WREG32(data_reg, 0x8018BED0); -+ WREG32(index_reg, 0x10200); -+ WREG32(data_reg, 0x8148BF38); -+ WREG32(index_reg, 0x10201); -+ WREG32(data_reg, 0x84408C80); -+ WREG32(index_reg, 0x10202); -+ WREG32(data_reg, 0x8008BEB8); -+ WREG32(index_reg, 0x10300); -+ WREG32(data_reg, 0x80B0BF78); -+ WREG32(index_reg, 0x10301); -+ WREG32(data_reg, 0x85008C20); -+ WREG32(index_reg, 0x10302); -+ WREG32(data_reg, 0x8020BEA0); -+ WREG32(index_reg, 0x10400); -+ WREG32(data_reg, 0x8028BF90); -+ WREG32(index_reg, 0x10401); -+ WREG32(data_reg, 0x85E08BC0); -+ WREG32(index_reg, 0x10402); -+ WREG32(data_reg, 0x8018BE90); -+ WREG32(index_reg, 0x10500); -+ WREG32(data_reg, 0xBFB8BFB0); -+ WREG32(index_reg, 0x10501); -+ WREG32(data_reg, 0x86C08B40); -+ WREG32(index_reg, 0x10502); -+ WREG32(data_reg, 0x8010BE90); -+ WREG32(index_reg, 0x10600); -+ WREG32(data_reg, 0xBF58BFC8); -+ WREG32(index_reg, 0x10601); -+ WREG32(data_reg, 0x87A08AA0); -+ WREG32(index_reg, 0x10602); -+ WREG32(data_reg, 0x8010BE98); -+ WREG32(index_reg, 0x10700); -+ WREG32(data_reg, 0xBF10BFF0); -+ WREG32(index_reg, 0x10701); -+ WREG32(data_reg, 0x886089E0); -+ WREG32(index_reg, 0x10702); -+ WREG32(data_reg, 0x8018BEB0); -+ WREG32(index_reg, 0x10800); -+ WREG32(data_reg, 0xBED8BFE8); -+ WREG32(index_reg, 0x10801); -+ WREG32(data_reg, 0x89408940); -+ WREG32(index_reg, 0x10802); -+ WREG32(data_reg, 0xBFE8BED8); -+ WREG32(index_reg, 0x20000); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20001); -+ WREG32(data_reg, 0x90008000); -+ WREG32(index_reg, 0x20002); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20003); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20100); -+ WREG32(data_reg, 0x80108000); -+ WREG32(index_reg, 0x20101); -+ WREG32(data_reg, 0x8FE0BF70); -+ WREG32(index_reg, 0x20102); -+ WREG32(data_reg, 0xBFE880C0); -+ WREG32(index_reg, 0x20103); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20200); -+ WREG32(data_reg, 0x8018BFF8); -+ WREG32(index_reg, 0x20201); -+ WREG32(data_reg, 0x8F80BF08); -+ WREG32(index_reg, 0x20202); -+ WREG32(data_reg, 0xBFD081A0); -+ WREG32(index_reg, 0x20203); -+ WREG32(data_reg, 0xBFF88000); -+ WREG32(index_reg, 0x20300); -+ WREG32(data_reg, 0x80188000); -+ WREG32(index_reg, 0x20301); -+ WREG32(data_reg, 0x8EE0BEC0); -+ WREG32(index_reg, 0x20302); -+ WREG32(data_reg, 0xBFB082A0); -+ WREG32(index_reg, 0x20303); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20400); -+ WREG32(data_reg, 0x80188000); -+ WREG32(index_reg, 0x20401); -+ WREG32(data_reg, 0x8E00BEA0); -+ WREG32(index_reg, 0x20402); -+ WREG32(data_reg, 0xBF8883C0); -+ WREG32(index_reg, 0x20403); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x20500); -+ WREG32(data_reg, 0x80188000); -+ WREG32(index_reg, 0x20501); -+ WREG32(data_reg, 0x8D00BE90); -+ WREG32(index_reg, 0x20502); -+ WREG32(data_reg, 0xBF588500); -+ WREG32(index_reg, 0x20503); -+ WREG32(data_reg, 0x80008008); -+ WREG32(index_reg, 0x20600); -+ WREG32(data_reg, 0x80188000); -+ WREG32(index_reg, 0x20601); -+ WREG32(data_reg, 0x8BC0BE98); -+ WREG32(index_reg, 0x20602); -+ WREG32(data_reg, 0xBF308660); -+ WREG32(index_reg, 0x20603); -+ WREG32(data_reg, 0x80008008); -+ WREG32(index_reg, 0x20700); -+ WREG32(data_reg, 0x80108000); -+ WREG32(index_reg, 0x20701); -+ WREG32(data_reg, 0x8A80BEB0); -+ WREG32(index_reg, 0x20702); -+ WREG32(data_reg, 0xBF0087C0); -+ WREG32(index_reg, 0x20703); -+ WREG32(data_reg, 0x80008008); -+ WREG32(index_reg, 0x20800); -+ WREG32(data_reg, 0x80108000); -+ WREG32(index_reg, 0x20801); -+ WREG32(data_reg, 0x8920BED0); -+ WREG32(index_reg, 0x20802); -+ WREG32(data_reg, 0xBED08920); -+ WREG32(index_reg, 0x20803); -+ WREG32(data_reg, 0x80008010); -+ WREG32(index_reg, 0x30000); -+ WREG32(data_reg, 0x90008000); -+ WREG32(index_reg, 0x30001); -+ WREG32(data_reg, 0x80008000); -+ WREG32(index_reg, 0x30100); -+ WREG32(data_reg, 0x8FE0BF90); -+ WREG32(index_reg, 0x30101); -+ WREG32(data_reg, 0xBFF880A0); -+ WREG32(index_reg, 0x30200); -+ WREG32(data_reg, 0x8F60BF40); -+ WREG32(index_reg, 0x30201); -+ WREG32(data_reg, 0xBFE88180); -+ WREG32(index_reg, 0x30300); -+ WREG32(data_reg, 0x8EC0BF00); -+ WREG32(index_reg, 0x30301); -+ WREG32(data_reg, 0xBFC88280); -+ WREG32(index_reg, 0x30400); -+ WREG32(data_reg, 0x8DE0BEE0); -+ WREG32(index_reg, 0x30401); -+ WREG32(data_reg, 0xBFA083A0); -+ WREG32(index_reg, 0x30500); -+ WREG32(data_reg, 0x8CE0BED0); -+ WREG32(index_reg, 0x30501); -+ WREG32(data_reg, 0xBF7884E0); -+ WREG32(index_reg, 0x30600); -+ WREG32(data_reg, 0x8BA0BED8); -+ WREG32(index_reg, 0x30601); -+ WREG32(data_reg, 0xBF508640); -+ WREG32(index_reg, 0x30700); -+ WREG32(data_reg, 0x8A60BEE8); -+ WREG32(index_reg, 0x30701); -+ WREG32(data_reg, 0xBF2087A0); -+ WREG32(index_reg, 0x30800); -+ WREG32(data_reg, 0x8900BF00); -+ WREG32(index_reg, 0x30801); -+ WREG32(data_reg, 0xBF008900); - } - - struct rv515_watermark { -diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h -new file mode 100644 -index 0000000..a65e17e ---- /dev/null -+++ b/drivers/gpu/drm/radeon/rv515d.h -@@ -0,0 +1,220 @@ -+/* -+ * Copyright 2008 Advanced Micro Devices, Inc. -+ * Copyright 2008 Red Hat Inc. -+ * Copyright 2009 Jerome Glisse. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef __RV515D_H__ -+#define __RV515D_H__ -+ -+/* -+ * RV515 registers -+ */ -+#define PCIE_INDEX 0x0030 -+#define PCIE_DATA 0x0034 -+#define MC_IND_INDEX 0x0070 -+#define MC_IND_WR_EN (1 << 24) -+#define MC_IND_DATA 0x0074 -+#define RBBM_SOFT_RESET 0x00F0 -+#define CONFIG_MEMSIZE 0x00F8 -+#define HDP_FB_LOCATION 0x0134 -+#define CP_CSQ_CNTL 0x0740 -+#define CP_CSQ_MODE 0x0744 -+#define CP_CSQ_ADDR 0x07F0 -+#define CP_CSQ_DATA 0x07F4 -+#define CP_CSQ_STAT 0x07F8 -+#define CP_CSQ2_STAT 0x07FC -+#define RBBM_STATUS 0x0E40 -+#define DST_PIPE_CONFIG 0x170C -+#define WAIT_UNTIL 0x1720 -+#define WAIT_2D_IDLE (1 << 14) -+#define WAIT_3D_IDLE (1 << 15) -+#define WAIT_2D_IDLECLEAN (1 << 16) -+#define WAIT_3D_IDLECLEAN (1 << 17) -+#define ISYNC_CNTL 0x1724 -+#define ISYNC_ANY2D_IDLE3D (1 << 0) -+#define ISYNC_ANY3D_IDLE2D (1 << 1) -+#define ISYNC_TRIG2D_IDLE3D (1 << 2) -+#define ISYNC_TRIG3D_IDLE2D (1 << 3) -+#define ISYNC_WAIT_IDLEGUI (1 << 4) -+#define ISYNC_CPSCRATCH_IDLEGUI (1 << 5) -+#define VAP_INDEX_OFFSET 0x208C -+#define VAP_PVS_STATE_FLUSH_REG 0x2284 -+#define GB_ENABLE 0x4008 -+#define GB_MSPOS0 0x4010 -+#define MS_X0_SHIFT 0 -+#define MS_Y0_SHIFT 4 -+#define MS_X1_SHIFT 8 -+#define MS_Y1_SHIFT 12 -+#define MS_X2_SHIFT 16 -+#define MS_Y2_SHIFT 20 -+#define MSBD0_Y_SHIFT 24 -+#define MSBD0_X_SHIFT 28 -+#define GB_MSPOS1 0x4014 -+#define MS_X3_SHIFT 0 -+#define MS_Y3_SHIFT 4 -+#define MS_X4_SHIFT 8 -+#define MS_Y4_SHIFT 12 -+#define MS_X5_SHIFT 16 -+#define MS_Y5_SHIFT 20 -+#define MSBD1_SHIFT 24 -+#define GB_TILE_CONFIG 0x4018 -+#define ENABLE_TILING (1 << 0) -+#define PIPE_COUNT_MASK 0x0000000E -+#define PIPE_COUNT_SHIFT 1 -+#define TILE_SIZE_8 (0 << 4) -+#define TILE_SIZE_16 (1 << 4) -+#define TILE_SIZE_32 (2 << 4) -+#define SUBPIXEL_1_12 (0 << 16) -+#define SUBPIXEL_1_16 (1 << 16) -+#define GB_SELECT 0x401C -+#define GB_AA_CONFIG 0x4020 -+#define GB_PIPE_SELECT 0x402C -+#define GA_ENHANCE 0x4274 -+#define GA_DEADLOCK_CNTL (1 << 0) -+#define GA_FASTSYNC_CNTL (1 << 1) -+#define GA_POLY_MODE 0x4288 -+#define FRONT_PTYPE_POINT (0 << 4) -+#define FRONT_PTYPE_LINE (1 << 4) -+#define FRONT_PTYPE_TRIANGE (2 << 4) -+#define BACK_PTYPE_POINT (0 << 7) -+#define BACK_PTYPE_LINE (1 << 7) -+#define BACK_PTYPE_TRIANGE (2 << 7) -+#define GA_ROUND_MODE 0x428C -+#define GEOMETRY_ROUND_TRUNC (0 << 0) -+#define GEOMETRY_ROUND_NEAREST (1 << 0) -+#define COLOR_ROUND_TRUNC (0 << 2) -+#define COLOR_ROUND_NEAREST (1 << 2) -+#define SU_REG_DEST 0x42C8 -+#define RB3D_DSTCACHE_CTLSTAT 0x4E4C -+#define RB3D_DC_FLUSH (2 << 0) -+#define RB3D_DC_FREE (2 << 2) -+#define RB3D_DC_FINISH (1 << 4) -+#define ZB_ZCACHE_CTLSTAT 0x4F18 -+#define ZC_FLUSH (1 << 0) -+#define ZC_FREE (1 << 1) -+#define DC_LB_MEMORY_SPLIT 0x6520 -+#define DC_LB_MEMORY_SPLIT_MASK 0x00000003 -+#define DC_LB_MEMORY_SPLIT_SHIFT 0 -+#define DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 -+#define DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 -+#define DC_LB_MEMORY_SPLIT_D1_ONLY 2 -+#define DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 -+#define DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2) -+#define DC_LB_DISP1_END_ADR_SHIFT 4 -+#define DC_LB_DISP1_END_ADR_MASK 0x00007FF0 -+#define D1MODE_PRIORITY_A_CNT 0x6548 -+#define MODE_PRIORITY_MARK_MASK 0x00007FFF -+#define MODE_PRIORITY_OFF (1 << 16) -+#define MODE_PRIORITY_ALWAYS_ON (1 << 20) -+#define MODE_PRIORITY_FORCE_MASK (1 << 24) -+#define D1MODE_PRIORITY_B_CNT 0x654C -+#define LB_MAX_REQ_OUTSTANDING 0x6D58 -+#define LB_D1_MAX_REQ_OUTSTANDING_MASK 0x0000000F -+#define LB_D1_MAX_REQ_OUTSTANDING_SHIFT 0 -+#define LB_D2_MAX_REQ_OUTSTANDING_MASK 0x000F0000 -+#define LB_D2_MAX_REQ_OUTSTANDING_SHIFT 16 -+#define D2MODE_PRIORITY_A_CNT 0x6D48 -+#define D2MODE_PRIORITY_B_CNT 0x6D4C -+ -+/* ix[MC] registers */ -+#define MC_FB_LOCATION 0x01 -+#define MC_FB_START_MASK 0x0000FFFF -+#define MC_FB_START_SHIFT 0 -+#define MC_FB_TOP_MASK 0xFFFF0000 -+#define MC_FB_TOP_SHIFT 16 -+#define MC_AGP_LOCATION 0x02 -+#define MC_AGP_START_MASK 0x0000FFFF -+#define MC_AGP_START_SHIFT 0 -+#define MC_AGP_TOP_MASK 0xFFFF0000 -+#define MC_AGP_TOP_SHIFT 16 -+#define MC_AGP_BASE 0x03 -+#define MC_AGP_BASE_2 0x04 -+#define MC_CNTL 0x5 -+#define MEM_NUM_CHANNELS_MASK 0x00000003 -+#define MC_STATUS 0x08 -+#define MC_STATUS_IDLE (1 << 4) -+#define MC_MISC_LAT_TIMER 0x09 -+#define MC_CPR_INIT_LAT_MASK 0x0000000F -+#define MC_VF_INIT_LAT_MASK 0x000000F0 -+#define MC_DISP0R_INIT_LAT_MASK 0x00000F00 -+#define MC_DISP0R_INIT_LAT_SHIFT 8 -+#define MC_DISP1R_INIT_LAT_MASK 0x0000F000 -+#define MC_DISP1R_INIT_LAT_SHIFT 12 -+#define MC_FIXED_INIT_LAT_MASK 0x000F0000 -+#define MC_E2R_INIT_LAT_MASK 0x00F00000 -+#define SAME_PAGE_PRIO_MASK 0x0F000000 -+#define MC_GLOBW_INIT_LAT_MASK 0xF0000000 -+ -+ -+/* -+ * PM4 packet -+ */ -+#define CP_PACKET0 0x00000000 -+#define PACKET0_BASE_INDEX_SHIFT 0 -+#define PACKET0_BASE_INDEX_MASK (0x1ffff << 0) -+#define PACKET0_COUNT_SHIFT 16 -+#define PACKET0_COUNT_MASK (0x3fff << 16) -+#define CP_PACKET1 0x40000000 -+#define CP_PACKET2 0x80000000 -+#define PACKET2_PAD_SHIFT 0 -+#define PACKET2_PAD_MASK (0x3fffffff << 0) -+#define CP_PACKET3 0xC0000000 -+#define PACKET3_IT_OPCODE_SHIFT 8 -+#define PACKET3_IT_OPCODE_MASK (0xff << 8) -+#define PACKET3_COUNT_SHIFT 16 -+#define PACKET3_COUNT_MASK (0x3fff << 16) -+/* PACKET3 op code */ -+#define PACKET3_NOP 0x10 -+#define PACKET3_3D_DRAW_VBUF 0x28 -+#define PACKET3_3D_DRAW_IMMD 0x29 -+#define PACKET3_3D_DRAW_INDX 0x2A -+#define PACKET3_3D_LOAD_VBPNTR 0x2F -+#define PACKET3_INDX_BUFFER 0x33 -+#define PACKET3_3D_DRAW_VBUF_2 0x34 -+#define PACKET3_3D_DRAW_IMMD_2 0x35 -+#define PACKET3_3D_DRAW_INDX_2 0x36 -+#define PACKET3_BITBLT_MULTI 0x9B -+ -+#define PACKET0(reg, n) (CP_PACKET0 | \ -+ REG_SET(PACKET0_BASE_INDEX, (reg) >> 2) | \ -+ REG_SET(PACKET0_COUNT, (n))) -+#define PACKET2(v) (CP_PACKET2 | REG_SET(PACKET2_PAD, (v))) -+#define PACKET3(op, n) (CP_PACKET3 | \ -+ REG_SET(PACKET3_IT_OPCODE, (op)) | \ -+ REG_SET(PACKET3_COUNT, (n))) -+ -+#define PACKET_TYPE0 0 -+#define PACKET_TYPE1 1 -+#define PACKET_TYPE2 2 -+#define PACKET_TYPE3 3 -+ -+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) -+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) -+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) -+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) -+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) -+ -+#endif -+ -diff --git a/drivers/gpu/drm/radeon/rv515r.h b/drivers/gpu/drm/radeon/rv515r.h -deleted file mode 100644 -index f3cf840..0000000 ---- a/drivers/gpu/drm/radeon/rv515r.h -+++ /dev/null -@@ -1,170 +0,0 @@ --/* -- * Copyright 2008 Advanced Micro Devices, Inc. -- * Copyright 2008 Red Hat Inc. -- * Copyright 2009 Jerome Glisse. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice shall be included in -- * all copies or substantial portions of the Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -- * OTHER DEALINGS IN THE SOFTWARE. -- * -- * Authors: Dave Airlie -- * Alex Deucher -- * Jerome Glisse -- */ --#ifndef RV515R_H --#define RV515R_H -- --/* RV515 registers */ --#define PCIE_INDEX 0x0030 --#define PCIE_DATA 0x0034 --#define MC_IND_INDEX 0x0070 --#define MC_IND_WR_EN (1 << 24) --#define MC_IND_DATA 0x0074 --#define RBBM_SOFT_RESET 0x00F0 --#define CONFIG_MEMSIZE 0x00F8 --#define HDP_FB_LOCATION 0x0134 --#define CP_CSQ_CNTL 0x0740 --#define CP_CSQ_MODE 0x0744 --#define CP_CSQ_ADDR 0x07F0 --#define CP_CSQ_DATA 0x07F4 --#define CP_CSQ_STAT 0x07F8 --#define CP_CSQ2_STAT 0x07FC --#define RBBM_STATUS 0x0E40 --#define DST_PIPE_CONFIG 0x170C --#define WAIT_UNTIL 0x1720 --#define WAIT_2D_IDLE (1 << 14) --#define WAIT_3D_IDLE (1 << 15) --#define WAIT_2D_IDLECLEAN (1 << 16) --#define WAIT_3D_IDLECLEAN (1 << 17) --#define ISYNC_CNTL 0x1724 --#define ISYNC_ANY2D_IDLE3D (1 << 0) --#define ISYNC_ANY3D_IDLE2D (1 << 1) --#define ISYNC_TRIG2D_IDLE3D (1 << 2) --#define ISYNC_TRIG3D_IDLE2D (1 << 3) --#define ISYNC_WAIT_IDLEGUI (1 << 4) --#define ISYNC_CPSCRATCH_IDLEGUI (1 << 5) --#define VAP_INDEX_OFFSET 0x208C --#define VAP_PVS_STATE_FLUSH_REG 0x2284 --#define GB_ENABLE 0x4008 --#define GB_MSPOS0 0x4010 --#define MS_X0_SHIFT 0 --#define MS_Y0_SHIFT 4 --#define MS_X1_SHIFT 8 --#define MS_Y1_SHIFT 12 --#define MS_X2_SHIFT 16 --#define MS_Y2_SHIFT 20 --#define MSBD0_Y_SHIFT 24 --#define MSBD0_X_SHIFT 28 --#define GB_MSPOS1 0x4014 --#define MS_X3_SHIFT 0 --#define MS_Y3_SHIFT 4 --#define MS_X4_SHIFT 8 --#define MS_Y4_SHIFT 12 --#define MS_X5_SHIFT 16 --#define MS_Y5_SHIFT 20 --#define MSBD1_SHIFT 24 --#define GB_TILE_CONFIG 0x4018 --#define ENABLE_TILING (1 << 0) --#define PIPE_COUNT_MASK 0x0000000E --#define PIPE_COUNT_SHIFT 1 --#define TILE_SIZE_8 (0 << 4) --#define TILE_SIZE_16 (1 << 4) --#define TILE_SIZE_32 (2 << 4) --#define SUBPIXEL_1_12 (0 << 16) --#define SUBPIXEL_1_16 (1 << 16) --#define GB_SELECT 0x401C --#define GB_AA_CONFIG 0x4020 --#define GB_PIPE_SELECT 0x402C --#define GA_ENHANCE 0x4274 --#define GA_DEADLOCK_CNTL (1 << 0) --#define GA_FASTSYNC_CNTL (1 << 1) --#define GA_POLY_MODE 0x4288 --#define FRONT_PTYPE_POINT (0 << 4) --#define FRONT_PTYPE_LINE (1 << 4) --#define FRONT_PTYPE_TRIANGE (2 << 4) --#define BACK_PTYPE_POINT (0 << 7) --#define BACK_PTYPE_LINE (1 << 7) --#define BACK_PTYPE_TRIANGE (2 << 7) --#define GA_ROUND_MODE 0x428C --#define GEOMETRY_ROUND_TRUNC (0 << 0) --#define GEOMETRY_ROUND_NEAREST (1 << 0) --#define COLOR_ROUND_TRUNC (0 << 2) --#define COLOR_ROUND_NEAREST (1 << 2) --#define SU_REG_DEST 0x42C8 --#define RB3D_DSTCACHE_CTLSTAT 0x4E4C --#define RB3D_DC_FLUSH (2 << 0) --#define RB3D_DC_FREE (2 << 2) --#define RB3D_DC_FINISH (1 << 4) --#define ZB_ZCACHE_CTLSTAT 0x4F18 --#define ZC_FLUSH (1 << 0) --#define ZC_FREE (1 << 1) --#define DC_LB_MEMORY_SPLIT 0x6520 --#define DC_LB_MEMORY_SPLIT_MASK 0x00000003 --#define DC_LB_MEMORY_SPLIT_SHIFT 0 --#define DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0 --#define DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1 --#define DC_LB_MEMORY_SPLIT_D1_ONLY 2 --#define DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3 --#define DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2) --#define DC_LB_DISP1_END_ADR_SHIFT 4 --#define DC_LB_DISP1_END_ADR_MASK 0x00007FF0 --#define D1MODE_PRIORITY_A_CNT 0x6548 --#define MODE_PRIORITY_MARK_MASK 0x00007FFF --#define MODE_PRIORITY_OFF (1 << 16) --#define MODE_PRIORITY_ALWAYS_ON (1 << 20) --#define MODE_PRIORITY_FORCE_MASK (1 << 24) --#define D1MODE_PRIORITY_B_CNT 0x654C --#define LB_MAX_REQ_OUTSTANDING 0x6D58 --#define LB_D1_MAX_REQ_OUTSTANDING_MASK 0x0000000F --#define LB_D1_MAX_REQ_OUTSTANDING_SHIFT 0 --#define LB_D2_MAX_REQ_OUTSTANDING_MASK 0x000F0000 --#define LB_D2_MAX_REQ_OUTSTANDING_SHIFT 16 --#define D2MODE_PRIORITY_A_CNT 0x6D48 --#define D2MODE_PRIORITY_B_CNT 0x6D4C -- --/* ix[MC] registers */ --#define MC_FB_LOCATION 0x01 --#define MC_FB_START_MASK 0x0000FFFF --#define MC_FB_START_SHIFT 0 --#define MC_FB_TOP_MASK 0xFFFF0000 --#define MC_FB_TOP_SHIFT 16 --#define MC_AGP_LOCATION 0x02 --#define MC_AGP_START_MASK 0x0000FFFF --#define MC_AGP_START_SHIFT 0 --#define MC_AGP_TOP_MASK 0xFFFF0000 --#define MC_AGP_TOP_SHIFT 16 --#define MC_AGP_BASE 0x03 --#define MC_AGP_BASE_2 0x04 --#define MC_CNTL 0x5 --#define MEM_NUM_CHANNELS_MASK 0x00000003 --#define MC_STATUS 0x08 --#define MC_STATUS_IDLE (1 << 4) --#define MC_MISC_LAT_TIMER 0x09 --#define MC_CPR_INIT_LAT_MASK 0x0000000F --#define MC_VF_INIT_LAT_MASK 0x000000F0 --#define MC_DISP0R_INIT_LAT_MASK 0x00000F00 --#define MC_DISP0R_INIT_LAT_SHIFT 8 --#define MC_DISP1R_INIT_LAT_MASK 0x0000F000 --#define MC_DISP1R_INIT_LAT_SHIFT 12 --#define MC_FIXED_INIT_LAT_MASK 0x000F0000 --#define MC_E2R_INIT_LAT_MASK 0x00F00000 --#define SAME_PAGE_PRIO_MASK 0x0F000000 --#define MC_GLOBW_INIT_LAT_MASK 0xF0000000 -- -- --#endif -- -diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c -index 21d8ffd..57765f6 100644 ---- a/drivers/gpu/drm/radeon/rv770.c -+++ b/drivers/gpu/drm/radeon/rv770.c -@@ -25,100 +25,975 @@ - * Alex Deucher - * Jerome Glisse - */ -+#include -+#include - #include "drmP.h" --#include "radeon_reg.h" - #include "radeon.h" -+#include "radeon_share.h" -+#include "rv770d.h" -+#include "avivod.h" -+#include "atom.h" - --/* rv770,rv730,rv710 depends on : */ --void rs600_mc_disable_clients(struct radeon_device *rdev); -+#define R700_PFP_UCODE_SIZE 848 -+#define R700_PM4_UCODE_SIZE 1360 - --/* This files gather functions specifics to: -- * rv770,rv730,rv710 -- * -- * Some of these functions might be used by newer ASICs. -- */ --int rv770_mc_wait_for_idle(struct radeon_device *rdev); --void rv770_gpu_init(struct radeon_device *rdev); -+static void rv770_gpu_init(struct radeon_device *rdev); -+void rv770_fini(struct radeon_device *rdev); - - - /* -- * MC -+ * GART - */ --int rv770_mc_init(struct radeon_device *rdev) -+int rv770_pcie_gart_enable(struct radeon_device *rdev) - { -- uint32_t tmp; -+ u32 tmp; -+ int r, i; - -- rv770_gpu_init(rdev); -+ /* Initialize common gart structure */ -+ r = radeon_gart_init(rdev); -+ if (r) { -+ return r; -+ } -+ rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; -+ r = radeon_gart_table_vram_alloc(rdev); -+ if (r) { -+ return r; -+ } -+ for (i = 0; i < rdev->gart.num_gpu_pages; i++) -+ r600_gart_clear_page(rdev, i); -+ /* Setup L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | -+ ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | -+ EFFECTIVE_L2_QUEUE_SIZE(7)); -+ WREG32(VM_L2_CNTL2, 0); -+ WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); -+ /* Setup TLB control */ -+ tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | -+ SYSTEM_ACCESS_MODE_NOT_IN_SYS | -+ SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | -+ EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); -+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); -+ WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); -+ WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | -+ RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); -+ WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, -+ (u32)(rdev->dummy_page.addr >> 12)); -+ for (i = 1; i < 7; i++) -+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); - -- /* setup the gart before changing location so we can ask to -- * discard unmapped mc request -- */ -- /* FIXME: disable out of gart access */ -- tmp = rdev->mc.gtt_location / 4096; -- tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp); -- WREG32(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, tmp); -- tmp = (rdev->mc.gtt_location + rdev->mc.gtt_size) / 4096; -- tmp = REG_SET(R700_LOGICAL_PAGE_NUMBER, tmp); -- WREG32(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, tmp); -- -- rs600_mc_disable_clients(rdev); -- if (rv770_mc_wait_for_idle(rdev)) { -- printk(KERN_WARNING "Failed to wait MC idle while " -- "programming pipes. Bad things might happen.\n"); -- } -- -- tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; -- tmp = REG_SET(R700_MC_FB_TOP, tmp >> 24); -- tmp |= REG_SET(R700_MC_FB_BASE, rdev->mc.vram_location >> 24); -- WREG32(R700_MC_VM_FB_LOCATION, tmp); -- tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; -- tmp = REG_SET(R700_MC_AGP_TOP, tmp >> 22); -- WREG32(R700_MC_VM_AGP_TOP, tmp); -- tmp = REG_SET(R700_MC_AGP_BOT, rdev->mc.gtt_location >> 22); -- WREG32(R700_MC_VM_AGP_BOT, tmp); -+ r600_pcie_gart_tlb_flush(rdev); -+ rdev->gart.ready = true; - return 0; - } - --void rv770_mc_fini(struct radeon_device *rdev) -+void rv770_pcie_gart_disable(struct radeon_device *rdev) - { -- /* FIXME: implement */ -+ u32 tmp; -+ int i; -+ -+ /* Clear ptes*/ -+ for (i = 0; i < rdev->gart.num_gpu_pages; i++) -+ r600_gart_clear_page(rdev, i); -+ r600_pcie_gart_tlb_flush(rdev); -+ /* Disable all tables */ -+ for (i = 0; i < 7; i++) -+ WREG32(VM_CONTEXT0_CNTL + (i * 4), 0); -+ -+ /* Setup L2 cache */ -+ WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | -+ EFFECTIVE_L2_QUEUE_SIZE(7)); -+ WREG32(VM_L2_CNTL2, 0); -+ WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); -+ /* Setup TLB control */ -+ tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); -+ WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); -+ WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); - } - - - /* -- * Global GPU functions -+ * MC - */ --void rv770_errata(struct radeon_device *rdev) -+static void rv770_mc_resume(struct radeon_device *rdev) - { -- rdev->pll_errata = 0; -+ u32 d1vga_control, d2vga_control; -+ u32 vga_render_control, vga_hdp_control; -+ u32 d1crtc_control, d2crtc_control; -+ u32 new_d1grph_primary, new_d1grph_secondary; -+ u32 new_d2grph_primary, new_d2grph_secondary; -+ u64 old_vram_start; -+ u32 tmp; -+ int i, j; -+ -+ /* Initialize HDP */ -+ for (i = 0, j = 0; i < 32; i++, j += 0x18) { -+ WREG32((0x2c14 + j), 0x00000000); -+ WREG32((0x2c18 + j), 0x00000000); -+ WREG32((0x2c1c + j), 0x00000000); -+ WREG32((0x2c20 + j), 0x00000000); -+ WREG32((0x2c24 + j), 0x00000000); -+ } -+ WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); -+ -+ d1vga_control = RREG32(D1VGA_CONTROL); -+ d2vga_control = RREG32(D2VGA_CONTROL); -+ vga_render_control = RREG32(VGA_RENDER_CONTROL); -+ vga_hdp_control = RREG32(VGA_HDP_CONTROL); -+ d1crtc_control = RREG32(D1CRTC_CONTROL); -+ d2crtc_control = RREG32(D2CRTC_CONTROL); -+ old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; -+ new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS); -+ new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS); -+ new_d1grph_primary += rdev->mc.vram_start - old_vram_start; -+ new_d1grph_secondary += rdev->mc.vram_start - old_vram_start; -+ new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS); -+ new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS); -+ new_d2grph_primary += rdev->mc.vram_start - old_vram_start; -+ new_d2grph_secondary += rdev->mc.vram_start - old_vram_start; -+ -+ /* Stop all video */ -+ WREG32(D1VGA_CONTROL, 0); -+ WREG32(D2VGA_CONTROL, 0); -+ WREG32(VGA_RENDER_CONTROL, 0); -+ WREG32(D1CRTC_UPDATE_LOCK, 1); -+ WREG32(D2CRTC_UPDATE_LOCK, 1); -+ WREG32(D1CRTC_CONTROL, 0); -+ WREG32(D2CRTC_CONTROL, 0); -+ WREG32(D1CRTC_UPDATE_LOCK, 0); -+ WREG32(D2CRTC_UPDATE_LOCK, 0); -+ -+ mdelay(1); -+ if (r600_mc_wait_for_idle(rdev)) { -+ printk(KERN_WARNING "[drm] MC not idle !\n"); -+ } -+ -+ /* Lockout access through VGA aperture*/ -+ WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); -+ -+ /* Update configuration */ -+ WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); -+ WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); -+ WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); -+ tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; -+ tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); -+ WREG32(MC_VM_FB_LOCATION, tmp); -+ WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); -+ WREG32(HDP_NONSURFACE_INFO, (2 << 7)); -+ WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); -+ if (rdev->flags & RADEON_IS_AGP) { -+ WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); -+ WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); -+ WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); -+ } else { -+ WREG32(MC_VM_AGP_BASE, 0); -+ WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); -+ WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); -+ } -+ WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary); -+ WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary); -+ WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary); -+ WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary); -+ WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); -+ -+ /* Unlock host access */ -+ WREG32(VGA_HDP_CONTROL, vga_hdp_control); -+ -+ mdelay(1); -+ if (r600_mc_wait_for_idle(rdev)) { -+ printk(KERN_WARNING "[drm] MC not idle !\n"); -+ } -+ -+ /* Restore video state */ -+ WREG32(D1CRTC_UPDATE_LOCK, 1); -+ WREG32(D2CRTC_UPDATE_LOCK, 1); -+ WREG32(D1CRTC_CONTROL, d1crtc_control); -+ WREG32(D2CRTC_CONTROL, d2crtc_control); -+ WREG32(D1CRTC_UPDATE_LOCK, 0); -+ WREG32(D2CRTC_UPDATE_LOCK, 0); -+ WREG32(D1VGA_CONTROL, d1vga_control); -+ WREG32(D2VGA_CONTROL, d2vga_control); -+ WREG32(VGA_RENDER_CONTROL, vga_render_control); - } - --int rv770_mc_wait_for_idle(struct radeon_device *rdev) -+ -+/* -+ * CP. -+ */ -+void r700_cp_stop(struct radeon_device *rdev) - { -- /* FIXME: implement */ -- return 0; -+ WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); - } - --void rv770_gpu_init(struct radeon_device *rdev) -+ -+static int rv770_cp_load_microcode(struct radeon_device *rdev) - { -- /* FIXME: implement */ -+ const __be32 *fw_data; -+ int i; -+ -+ if (!rdev->me_fw || !rdev->pfp_fw) -+ return -EINVAL; -+ -+ r700_cp_stop(rdev); -+ WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); -+ -+ /* Reset cp */ -+ WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); -+ RREG32(GRBM_SOFT_RESET); -+ mdelay(15); -+ WREG32(GRBM_SOFT_RESET, 0); -+ -+ fw_data = (const __be32 *)rdev->pfp_fw->data; -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++) -+ WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ -+ fw_data = (const __be32 *)rdev->me_fw->data; -+ WREG32(CP_ME_RAM_WADDR, 0); -+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++) -+ WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); -+ -+ WREG32(CP_PFP_UCODE_ADDR, 0); -+ WREG32(CP_ME_RAM_WADDR, 0); -+ WREG32(CP_ME_RAM_RADDR, 0); -+ return 0; - } - - - /* -- * VRAM info -+ * Core functions - */ --void rv770_vram_get_type(struct radeon_device *rdev) -+static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, -+ u32 num_backends, -+ u32 backend_disable_mask) - { -- /* FIXME: implement */ -+ u32 backend_map = 0; -+ u32 enabled_backends_mask; -+ u32 enabled_backends_count; -+ u32 cur_pipe; -+ u32 swizzle_pipe[R7XX_MAX_PIPES]; -+ u32 cur_backend; -+ u32 i; -+ -+ if (num_tile_pipes > R7XX_MAX_PIPES) -+ num_tile_pipes = R7XX_MAX_PIPES; -+ if (num_tile_pipes < 1) -+ num_tile_pipes = 1; -+ if (num_backends > R7XX_MAX_BACKENDS) -+ num_backends = R7XX_MAX_BACKENDS; -+ if (num_backends < 1) -+ num_backends = 1; -+ -+ enabled_backends_mask = 0; -+ enabled_backends_count = 0; -+ for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { -+ if (((backend_disable_mask >> i) & 1) == 0) { -+ enabled_backends_mask |= (1 << i); -+ ++enabled_backends_count; -+ } -+ if (enabled_backends_count == num_backends) -+ break; -+ } -+ -+ if (enabled_backends_count == 0) { -+ enabled_backends_mask = 1; -+ enabled_backends_count = 1; -+ } -+ -+ if (enabled_backends_count != num_backends) -+ num_backends = enabled_backends_count; -+ -+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); -+ switch (num_tile_pipes) { -+ case 1: -+ swizzle_pipe[0] = 0; -+ break; -+ case 2: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 1; -+ break; -+ case 3: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 1; -+ break; -+ case 4: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 3; -+ swizzle_pipe[3] = 1; -+ break; -+ case 5: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 1; -+ swizzle_pipe[4] = 3; -+ break; -+ case 6: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 5; -+ swizzle_pipe[4] = 3; -+ swizzle_pipe[5] = 1; -+ break; -+ case 7: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 6; -+ swizzle_pipe[4] = 3; -+ swizzle_pipe[5] = 1; -+ swizzle_pipe[6] = 5; -+ break; -+ case 8: -+ swizzle_pipe[0] = 0; -+ swizzle_pipe[1] = 2; -+ swizzle_pipe[2] = 4; -+ swizzle_pipe[3] = 6; -+ swizzle_pipe[4] = 3; -+ swizzle_pipe[5] = 1; -+ swizzle_pipe[6] = 7; -+ swizzle_pipe[7] = 5; -+ break; -+ } -+ -+ cur_backend = 0; -+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { -+ while (((1 << cur_backend) & enabled_backends_mask) == 0) -+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; -+ -+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); -+ -+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; -+ } -+ -+ return backend_map; - } - --void rv770_vram_info(struct radeon_device *rdev) -+static void rv770_gpu_init(struct radeon_device *rdev) - { -- rv770_vram_get_type(rdev); -+ int i, j, num_qd_pipes; -+ u32 sx_debug_1; -+ u32 smx_dc_ctl0; -+ u32 num_gs_verts_per_thread; -+ u32 vgt_gs_per_es; -+ u32 gs_prim_buffer_depth = 0; -+ u32 sq_ms_fifo_sizes; -+ u32 sq_config; -+ u32 sq_thread_resource_mgmt; -+ u32 hdp_host_path_cntl; -+ u32 sq_dyn_gpr_size_simd_ab_0; -+ u32 backend_map; -+ u32 gb_tiling_config = 0; -+ u32 cc_rb_backend_disable = 0; -+ u32 cc_gc_shader_pipe_config = 0; -+ u32 mc_arb_ramcfg; -+ u32 db_debug4; - -- /* FIXME: implement */ -+ /* setup chip specs */ -+ switch (rdev->family) { -+ case CHIP_RV770: -+ rdev->config.rv770.max_pipes = 4; -+ rdev->config.rv770.max_tile_pipes = 8; -+ rdev->config.rv770.max_simds = 10; -+ rdev->config.rv770.max_backends = 4; -+ rdev->config.rv770.max_gprs = 256; -+ rdev->config.rv770.max_threads = 248; -+ rdev->config.rv770.max_stack_entries = 512; -+ rdev->config.rv770.max_hw_contexts = 8; -+ rdev->config.rv770.max_gs_threads = 16 * 2; -+ rdev->config.rv770.sx_max_export_size = 128; -+ rdev->config.rv770.sx_max_export_pos_size = 16; -+ rdev->config.rv770.sx_max_export_smx_size = 112; -+ rdev->config.rv770.sq_num_cf_insts = 2; -+ -+ rdev->config.rv770.sx_num_of_sets = 7; -+ rdev->config.rv770.sc_prim_fifo_size = 0xF9; -+ rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; -+ rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; -+ break; -+ case CHIP_RV730: -+ rdev->config.rv770.max_pipes = 2; -+ rdev->config.rv770.max_tile_pipes = 4; -+ rdev->config.rv770.max_simds = 8; -+ rdev->config.rv770.max_backends = 2; -+ rdev->config.rv770.max_gprs = 128; -+ rdev->config.rv770.max_threads = 248; -+ rdev->config.rv770.max_stack_entries = 256; -+ rdev->config.rv770.max_hw_contexts = 8; -+ rdev->config.rv770.max_gs_threads = 16 * 2; -+ rdev->config.rv770.sx_max_export_size = 256; -+ rdev->config.rv770.sx_max_export_pos_size = 32; -+ rdev->config.rv770.sx_max_export_smx_size = 224; -+ rdev->config.rv770.sq_num_cf_insts = 2; -+ -+ rdev->config.rv770.sx_num_of_sets = 7; -+ rdev->config.rv770.sc_prim_fifo_size = 0xf9; -+ rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; -+ rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; -+ if (rdev->config.rv770.sx_max_export_pos_size > 16) { -+ rdev->config.rv770.sx_max_export_pos_size -= 16; -+ rdev->config.rv770.sx_max_export_smx_size += 16; -+ } -+ break; -+ case CHIP_RV710: -+ rdev->config.rv770.max_pipes = 2; -+ rdev->config.rv770.max_tile_pipes = 2; -+ rdev->config.rv770.max_simds = 2; -+ rdev->config.rv770.max_backends = 1; -+ rdev->config.rv770.max_gprs = 256; -+ rdev->config.rv770.max_threads = 192; -+ rdev->config.rv770.max_stack_entries = 256; -+ rdev->config.rv770.max_hw_contexts = 4; -+ rdev->config.rv770.max_gs_threads = 8 * 2; -+ rdev->config.rv770.sx_max_export_size = 128; -+ rdev->config.rv770.sx_max_export_pos_size = 16; -+ rdev->config.rv770.sx_max_export_smx_size = 112; -+ rdev->config.rv770.sq_num_cf_insts = 1; -+ -+ rdev->config.rv770.sx_num_of_sets = 7; -+ rdev->config.rv770.sc_prim_fifo_size = 0x40; -+ rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; -+ rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; -+ break; -+ case CHIP_RV740: -+ rdev->config.rv770.max_pipes = 4; -+ rdev->config.rv770.max_tile_pipes = 4; -+ rdev->config.rv770.max_simds = 8; -+ rdev->config.rv770.max_backends = 4; -+ rdev->config.rv770.max_gprs = 256; -+ rdev->config.rv770.max_threads = 248; -+ rdev->config.rv770.max_stack_entries = 512; -+ rdev->config.rv770.max_hw_contexts = 8; -+ rdev->config.rv770.max_gs_threads = 16 * 2; -+ rdev->config.rv770.sx_max_export_size = 256; -+ rdev->config.rv770.sx_max_export_pos_size = 32; -+ rdev->config.rv770.sx_max_export_smx_size = 224; -+ rdev->config.rv770.sq_num_cf_insts = 2; -+ -+ rdev->config.rv770.sx_num_of_sets = 7; -+ rdev->config.rv770.sc_prim_fifo_size = 0x100; -+ rdev->config.rv770.sc_hiz_tile_fifo_size = 0x30; -+ rdev->config.rv770.sc_earlyz_tile_fifo_fize = 0x130; -+ -+ if (rdev->config.rv770.sx_max_export_pos_size > 16) { -+ rdev->config.rv770.sx_max_export_pos_size -= 16; -+ rdev->config.rv770.sx_max_export_smx_size += 16; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ /* Initialize HDP */ -+ j = 0; -+ for (i = 0; i < 32; i++) { -+ WREG32((0x2c14 + j), 0x00000000); -+ WREG32((0x2c18 + j), 0x00000000); -+ WREG32((0x2c1c + j), 0x00000000); -+ WREG32((0x2c20 + j), 0x00000000); -+ WREG32((0x2c24 + j), 0x00000000); -+ j += 0x18; -+ } -+ -+ WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); -+ -+ /* setup tiling, simd, pipe config */ -+ mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); -+ -+ switch (rdev->config.rv770.max_tile_pipes) { -+ case 1: -+ gb_tiling_config |= PIPE_TILING(0); -+ break; -+ case 2: -+ gb_tiling_config |= PIPE_TILING(1); -+ break; -+ case 4: -+ gb_tiling_config |= PIPE_TILING(2); -+ break; -+ case 8: -+ gb_tiling_config |= PIPE_TILING(3); -+ break; -+ default: -+ break; -+ } -+ -+ if (rdev->family == CHIP_RV770) -+ gb_tiling_config |= BANK_TILING(1); -+ else -+ gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_SHIFT) >> NOOFBANK_MASK); -+ -+ gb_tiling_config |= GROUP_SIZE(0); -+ -+ if (((mc_arb_ramcfg & NOOFROWS_MASK) & NOOFROWS_SHIFT) > 3) { -+ gb_tiling_config |= ROW_TILING(3); -+ gb_tiling_config |= SAMPLE_SPLIT(3); -+ } else { -+ gb_tiling_config |= -+ ROW_TILING(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); -+ gb_tiling_config |= -+ SAMPLE_SPLIT(((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT)); -+ } -+ -+ gb_tiling_config |= BANK_SWAPS(1); -+ -+ backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, -+ rdev->config.rv770.max_backends, -+ (0xff << rdev->config.rv770.max_backends) & 0xff); -+ gb_tiling_config |= BACKEND_MAP(backend_map); -+ -+ cc_gc_shader_pipe_config = -+ INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << rdev->config.rv770.max_pipes) & R7XX_MAX_PIPES_MASK); -+ cc_gc_shader_pipe_config |= -+ INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << rdev->config.rv770.max_simds) & R7XX_MAX_SIMDS_MASK); -+ -+ cc_rb_backend_disable = -+ BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << rdev->config.rv770.max_backends) & R7XX_MAX_BACKENDS_MASK); -+ -+ WREG32(GB_TILING_CONFIG, gb_tiling_config); -+ WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); -+ WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); -+ -+ WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); -+ WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); -+ -+ WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); -+ WREG32(CGTS_SYS_TCC_DISABLE, 0); -+ WREG32(CGTS_TCC_DISABLE, 0); -+ WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); -+ WREG32(CGTS_USER_TCC_DISABLE, 0); -+ -+ num_qd_pipes = -+ R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK); -+ WREG32(VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & DEALLOC_DIST_MASK); -+ WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & VTX_REUSE_DEPTH_MASK); -+ -+ /* set HW defaults for 3D engine */ -+ WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | -+ ROQ_IB2_START(0x2b))); -+ -+ WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); -+ -+ WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | -+ SYNC_GRADIENT | -+ SYNC_WALKER | -+ SYNC_ALIGNER)); -+ -+ sx_debug_1 = RREG32(SX_DEBUG_1); -+ sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; -+ WREG32(SX_DEBUG_1, sx_debug_1); -+ -+ smx_dc_ctl0 = RREG32(SMX_DC_CTL0); -+ smx_dc_ctl0 &= ~CACHE_DEPTH(0x1ff); -+ smx_dc_ctl0 |= CACHE_DEPTH((rdev->config.rv770.sx_num_of_sets * 64) - 1); -+ WREG32(SMX_DC_CTL0, smx_dc_ctl0); -+ -+ WREG32(SMX_EVENT_CTL, (ES_FLUSH_CTL(4) | -+ GS_FLUSH_CTL(4) | -+ ACK_FLUSH_CTL(3) | -+ SYNC_FLUSH_CTL)); -+ -+ if (rdev->family == CHIP_RV770) -+ WREG32(DB_DEBUG3, DB_CLK_OFF_DELAY(0x1f)); -+ else { -+ db_debug4 = RREG32(DB_DEBUG4); -+ db_debug4 |= DISABLE_TILE_COVERED_FOR_PS_ITER; -+ WREG32(DB_DEBUG4, db_debug4); -+ } -+ -+ WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.rv770.sx_max_export_size / 4) - 1) | -+ POSITION_BUFFER_SIZE((rdev->config.rv770.sx_max_export_pos_size / 4) - 1) | -+ SMX_BUFFER_SIZE((rdev->config.rv770.sx_max_export_smx_size / 4) - 1))); -+ -+ WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.rv770.sc_prim_fifo_size) | -+ SC_HIZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_hiz_tile_fifo_size) | -+ SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.rv770.sc_earlyz_tile_fifo_fize))); -+ -+ WREG32(PA_SC_MULTI_CHIP_CNTL, 0); -+ -+ WREG32(VGT_NUM_INSTANCES, 1); -+ -+ WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0)); -+ -+ WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); -+ -+ WREG32(CP_PERFMON_CNTL, 0); -+ -+ sq_ms_fifo_sizes = (CACHE_FIFO_SIZE(16 * rdev->config.rv770.sq_num_cf_insts) | -+ DONE_FIFO_HIWATER(0xe0) | -+ ALU_UPDATE_FIFO_HIWATER(0x8)); -+ switch (rdev->family) { -+ case CHIP_RV770: -+ sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x1); -+ break; -+ case CHIP_RV730: -+ case CHIP_RV710: -+ case CHIP_RV740: -+ default: -+ sq_ms_fifo_sizes |= FETCH_FIFO_HIWATER(0x4); -+ break; -+ } -+ WREG32(SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); -+ -+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT -+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values -+ */ -+ sq_config = RREG32(SQ_CONFIG); -+ sq_config &= ~(PS_PRIO(3) | -+ VS_PRIO(3) | -+ GS_PRIO(3) | -+ ES_PRIO(3)); -+ sq_config |= (DX9_CONSTS | -+ VC_ENABLE | -+ EXPORT_SRC_C | -+ PS_PRIO(0) | -+ VS_PRIO(1) | -+ GS_PRIO(2) | -+ ES_PRIO(3)); -+ if (rdev->family == CHIP_RV710) -+ /* no vertex cache */ -+ sq_config &= ~VC_ENABLE; -+ -+ WREG32(SQ_CONFIG, sq_config); -+ -+ WREG32(SQ_GPR_RESOURCE_MGMT_1, (NUM_PS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | -+ NUM_VS_GPRS((rdev->config.rv770.max_gprs * 24)/64) | -+ NUM_CLAUSE_TEMP_GPRS(((rdev->config.rv770.max_gprs * 24)/64)/2))); -+ -+ WREG32(SQ_GPR_RESOURCE_MGMT_2, (NUM_GS_GPRS((rdev->config.rv770.max_gprs * 7)/64) | -+ NUM_ES_GPRS((rdev->config.rv770.max_gprs * 7)/64))); -+ -+ sq_thread_resource_mgmt = (NUM_PS_THREADS((rdev->config.rv770.max_threads * 4)/8) | -+ NUM_VS_THREADS((rdev->config.rv770.max_threads * 2)/8) | -+ NUM_ES_THREADS((rdev->config.rv770.max_threads * 1)/8)); -+ if (((rdev->config.rv770.max_threads * 1) / 8) > rdev->config.rv770.max_gs_threads) -+ sq_thread_resource_mgmt |= NUM_GS_THREADS(rdev->config.rv770.max_gs_threads); -+ else -+ sq_thread_resource_mgmt |= NUM_GS_THREADS((rdev->config.rv770.max_gs_threads * 1)/8); -+ WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); -+ -+ WREG32(SQ_STACK_RESOURCE_MGMT_1, (NUM_PS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | -+ NUM_VS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); -+ -+ WREG32(SQ_STACK_RESOURCE_MGMT_2, (NUM_GS_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4) | -+ NUM_ES_STACK_ENTRIES((rdev->config.rv770.max_stack_entries * 1)/4))); -+ -+ sq_dyn_gpr_size_simd_ab_0 = (SIMDA_RING0((rdev->config.rv770.max_gprs * 38)/64) | -+ SIMDA_RING1((rdev->config.rv770.max_gprs * 38)/64) | -+ SIMDB_RING0((rdev->config.rv770.max_gprs * 38)/64) | -+ SIMDB_RING1((rdev->config.rv770.max_gprs * 38)/64)); -+ -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); -+ WREG32(SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); -+ -+ WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | -+ FORCE_EOV_MAX_REZ_CNT(255))); -+ -+ if (rdev->family == CHIP_RV710) -+ WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(TC_ONLY) | -+ AUTO_INVLD_EN(ES_AND_GS_AUTO))); -+ else -+ WREG32(VGT_CACHE_INVALIDATION, (CACHE_INVALIDATION(VC_AND_TC) | -+ AUTO_INVLD_EN(ES_AND_GS_AUTO))); -+ -+ switch (rdev->family) { -+ case CHIP_RV770: -+ case CHIP_RV730: -+ case CHIP_RV740: -+ gs_prim_buffer_depth = 384; -+ break; -+ case CHIP_RV710: -+ gs_prim_buffer_depth = 128; -+ break; -+ default: -+ break; -+ } -+ -+ num_gs_verts_per_thread = rdev->config.rv770.max_pipes * 16; -+ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; -+ /* Max value for this is 256 */ -+ if (vgt_gs_per_es > 256) -+ vgt_gs_per_es = 256; -+ -+ WREG32(VGT_ES_PER_GS, 128); -+ WREG32(VGT_GS_PER_ES, vgt_gs_per_es); -+ WREG32(VGT_GS_PER_VS, 2); -+ -+ /* more default values. 2D/3D driver should adjust as needed */ -+ WREG32(VGT_GS_VERTEX_REUSE, 16); -+ WREG32(PA_SC_LINE_STIPPLE_STATE, 0); -+ WREG32(VGT_STRMOUT_EN, 0); -+ WREG32(SX_MISC, 0); -+ WREG32(PA_SC_MODE_CNTL, 0); -+ WREG32(PA_SC_EDGERULE, 0xaaaaaaaa); -+ WREG32(PA_SC_AA_CONFIG, 0); -+ WREG32(PA_SC_CLIPRECT_RULE, 0xffff); -+ WREG32(PA_SC_LINE_STIPPLE, 0); -+ WREG32(SPI_INPUT_Z, 0); -+ WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2)); -+ WREG32(CB_COLOR7_FRAG, 0); -+ -+ /* clear render buffer base addresses */ -+ WREG32(CB_COLOR0_BASE, 0); -+ WREG32(CB_COLOR1_BASE, 0); -+ WREG32(CB_COLOR2_BASE, 0); -+ WREG32(CB_COLOR3_BASE, 0); -+ WREG32(CB_COLOR4_BASE, 0); -+ WREG32(CB_COLOR5_BASE, 0); -+ WREG32(CB_COLOR6_BASE, 0); -+ WREG32(CB_COLOR7_BASE, 0); -+ -+ WREG32(TCP_CNTL, 0); -+ -+ hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); -+ WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); -+ -+ WREG32(PA_SC_MULTI_CHIP_CNTL, 0); -+ -+ WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | -+ NUM_CLIP_SEQ(3))); -+ -+} -+ -+int rv770_mc_init(struct radeon_device *rdev) -+{ -+ fixed20_12 a; -+ u32 tmp; -+ int r; -+ -+ /* Get VRAM informations */ -+ /* FIXME: Don't know how to determine vram width, need to check -+ * vram_width usage -+ */ -+ rdev->mc.vram_width = 128; -+ rdev->mc.vram_is_ddr = true; - /* Could aper size report 0 ? */ - rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); - rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); -+ /* Setup GPU memory space */ -+ rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); -+ rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); -+ if (rdev->flags & RADEON_IS_AGP) { -+ r = radeon_agp_init(rdev); -+ if (r) -+ return r; -+ /* gtt_size is setup by radeon_agp_init */ -+ rdev->mc.gtt_location = rdev->mc.agp_base; -+ tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; -+ /* Try to put vram before or after AGP because we -+ * we want SYSTEM_APERTURE to cover both VRAM and -+ * AGP so that GPU can catch out of VRAM/AGP access -+ */ -+ if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { -+ /* Enought place before */ -+ rdev->mc.vram_location = rdev->mc.gtt_location - -+ rdev->mc.mc_vram_size; -+ } else if (tmp > rdev->mc.mc_vram_size) { -+ /* Enought place after */ -+ rdev->mc.vram_location = rdev->mc.gtt_location + -+ rdev->mc.gtt_size; -+ } else { -+ /* Try to setup VRAM then AGP might not -+ * not work on some card -+ */ -+ rdev->mc.vram_location = 0x00000000UL; -+ rdev->mc.gtt_location = rdev->mc.mc_vram_size; -+ } -+ } else { -+ rdev->mc.vram_location = 0x00000000UL; -+ rdev->mc.gtt_location = rdev->mc.mc_vram_size; -+ rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; -+ } -+ rdev->mc.vram_start = rdev->mc.vram_location; -+ rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; -+ rdev->mc.gtt_start = rdev->mc.gtt_location; -+ rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; -+ /* FIXME: we should enforce default clock in case GPU is not in -+ * default setup -+ */ -+ a.full = rfixed_const(100); -+ rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); -+ rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); -+ return 0; -+} -+int rv770_gpu_reset(struct radeon_device *rdev) -+{ -+ /* FIXME: implement */ -+ return 0; -+} -+ -+int rv770_resume(struct radeon_device *rdev) -+{ -+ int r; -+ -+ rv770_mc_resume(rdev); -+ r = rv770_pcie_gart_enable(rdev); -+ if (r) -+ return r; -+ rv770_gpu_init(rdev); -+ r = radeon_ring_init(rdev, rdev->cp.ring_size); -+ if (r) -+ return r; -+ r = rv770_cp_load_microcode(rdev); -+ if (r) -+ return r; -+ r = r600_cp_resume(rdev); -+ if (r) -+ return r; -+ r = r600_wb_init(rdev); -+ if (r) -+ return r; -+ return 0; -+} -+ -+int rv770_suspend(struct radeon_device *rdev) -+{ -+ /* FIXME: we should wait for ring to be empty */ -+ r700_cp_stop(rdev); -+ return 0; -+} -+ -+/* Plan is to move initialization in that function and use -+ * helper function so that radeon_device_init pretty much -+ * do nothing more than calling asic specific function. This -+ * should also allow to remove a bunch of callback function -+ * like vram_info. -+ */ -+int rv770_init(struct radeon_device *rdev) -+{ -+ int r; -+ -+ rdev->new_init_path = true; -+ r = radeon_dummy_page_init(rdev); -+ if (r) -+ return r; -+ /* This don't do much */ -+ r = radeon_gem_init(rdev); -+ if (r) -+ return r; -+ /* Read BIOS */ -+ if (!radeon_get_bios(rdev)) { -+ if (ASIC_IS_AVIVO(rdev)) -+ return -EINVAL; -+ } -+ /* Must be an ATOMBIOS */ -+ if (!rdev->is_atom_bios) -+ return -EINVAL; -+ r = radeon_atombios_init(rdev); -+ if (r) -+ return r; -+ /* Post card if necessary */ -+ if (!r600_card_posted(rdev) && rdev->bios) { -+ DRM_INFO("GPU not posted. posting now...\n"); -+ atom_asic_init(rdev->mode_info.atom_context); -+ } -+ /* Initialize scratch registers */ -+ r600_scratch_init(rdev); -+ /* Initialize surface registers */ -+ radeon_surface_init(rdev); -+ r = radeon_clocks_init(rdev); -+ if (r) -+ return r; -+ /* Fence driver */ -+ r = radeon_fence_driver_init(rdev); -+ if (r) -+ return r; -+ r = rv770_mc_init(rdev); -+ if (r) { -+ if (rdev->flags & RADEON_IS_AGP) { -+ /* Retry with disabling AGP */ -+ rv770_fini(rdev); -+ rdev->flags &= ~RADEON_IS_AGP; -+ return rv770_init(rdev); -+ } -+ return r; -+ } -+ /* Memory manager */ -+ r = radeon_object_init(rdev); -+ if (r) -+ return r; -+ rdev->cp.ring_obj = NULL; -+ r600_ring_init(rdev, 1024 * 1024); -+ -+ if (!rdev->me_fw || !rdev->pfp_fw) { -+ r = r600_cp_init_microcode(rdev); -+ if (r) { -+ DRM_ERROR("Failed to load firmware!\n"); -+ return r; -+ } -+ } -+ -+ r = rv770_resume(rdev); -+ if (r) { -+ if (rdev->flags & RADEON_IS_AGP) { -+ /* Retry with disabling AGP */ -+ rv770_fini(rdev); -+ rdev->flags &= ~RADEON_IS_AGP; -+ return rv770_init(rdev); -+ } -+ return r; -+ } -+ r = r600_blit_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled blitter (%d).\n", r); -+ return r; -+ } -+ r = radeon_ib_pool_init(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); -+ return r; -+ } -+ r = radeon_ib_test(rdev); -+ if (r) { -+ DRM_ERROR("radeon: failled testing IB (%d).\n", r); -+ return r; -+ } -+ return 0; -+} -+ -+void rv770_fini(struct radeon_device *rdev) -+{ -+ r600_blit_fini(rdev); -+ radeon_ring_fini(rdev); -+ rv770_pcie_gart_disable(rdev); -+ radeon_gart_table_vram_free(rdev); -+ radeon_gart_fini(rdev); -+ radeon_gem_fini(rdev); -+ radeon_fence_driver_fini(rdev); -+ radeon_clocks_fini(rdev); -+#if __OS_HAS_AGP -+ if (rdev->flags & RADEON_IS_AGP) -+ radeon_agp_fini(rdev); -+#endif -+ radeon_object_fini(rdev); -+ if (rdev->is_atom_bios) { -+ radeon_atombios_fini(rdev); -+ } else { -+ radeon_combios_fini(rdev); -+ } -+ kfree(rdev->bios); -+ rdev->bios = NULL; -+ radeon_dummy_page_fini(rdev); - } -diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h -new file mode 100644 -index 0000000..4b9c3d6 ---- /dev/null -+++ b/drivers/gpu/drm/radeon/rv770d.h -@@ -0,0 +1,341 @@ -+/* -+ * Copyright 2009 Advanced Micro Devices, Inc. -+ * Copyright 2009 Red Hat Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: Dave Airlie -+ * Alex Deucher -+ * Jerome Glisse -+ */ -+#ifndef RV770_H -+#define RV770_H -+ -+#define R7XX_MAX_SH_GPRS 256 -+#define R7XX_MAX_TEMP_GPRS 16 -+#define R7XX_MAX_SH_THREADS 256 -+#define R7XX_MAX_SH_STACK_ENTRIES 4096 -+#define R7XX_MAX_BACKENDS 8 -+#define R7XX_MAX_BACKENDS_MASK 0xff -+#define R7XX_MAX_SIMDS 16 -+#define R7XX_MAX_SIMDS_MASK 0xffff -+#define R7XX_MAX_PIPES 8 -+#define R7XX_MAX_PIPES_MASK 0xff -+ -+/* Registers */ -+#define CB_COLOR0_BASE 0x28040 -+#define CB_COLOR1_BASE 0x28044 -+#define CB_COLOR2_BASE 0x28048 -+#define CB_COLOR3_BASE 0x2804C -+#define CB_COLOR4_BASE 0x28050 -+#define CB_COLOR5_BASE 0x28054 -+#define CB_COLOR6_BASE 0x28058 -+#define CB_COLOR7_BASE 0x2805C -+#define CB_COLOR7_FRAG 0x280FC -+ -+#define CC_GC_SHADER_PIPE_CONFIG 0x8950 -+#define CC_RB_BACKEND_DISABLE 0x98F4 -+#define BACKEND_DISABLE(x) ((x) << 16) -+#define CC_SYS_RB_BACKEND_DISABLE 0x3F88 -+ -+#define CGTS_SYS_TCC_DISABLE 0x3F90 -+#define CGTS_TCC_DISABLE 0x9148 -+#define CGTS_USER_SYS_TCC_DISABLE 0x3F94 -+#define CGTS_USER_TCC_DISABLE 0x914C -+ -+#define CONFIG_MEMSIZE 0x5428 -+ -+#define CP_ME_CNTL 0x86D8 -+#define CP_ME_HALT (1<<28) -+#define CP_PFP_HALT (1<<26) -+#define CP_ME_RAM_DATA 0xC160 -+#define CP_ME_RAM_RADDR 0xC158 -+#define CP_ME_RAM_WADDR 0xC15C -+#define CP_MEQ_THRESHOLDS 0x8764 -+#define STQ_SPLIT(x) ((x) << 0) -+#define CP_PERFMON_CNTL 0x87FC -+#define CP_PFP_UCODE_ADDR 0xC150 -+#define CP_PFP_UCODE_DATA 0xC154 -+#define CP_QUEUE_THRESHOLDS 0x8760 -+#define ROQ_IB1_START(x) ((x) << 0) -+#define ROQ_IB2_START(x) ((x) << 8) -+#define CP_RB_CNTL 0xC104 -+#define RB_BUFSZ(x) ((x)<<0) -+#define RB_BLKSZ(x) ((x)<<8) -+#define RB_NO_UPDATE (1<<27) -+#define RB_RPTR_WR_ENA (1<<31) -+#define BUF_SWAP_32BIT (2 << 16) -+#define CP_RB_RPTR 0x8700 -+#define CP_RB_RPTR_ADDR 0xC10C -+#define CP_RB_RPTR_ADDR_HI 0xC110 -+#define CP_RB_RPTR_WR 0xC108 -+#define CP_RB_WPTR 0xC114 -+#define CP_RB_WPTR_ADDR 0xC118 -+#define CP_RB_WPTR_ADDR_HI 0xC11C -+#define CP_RB_WPTR_DELAY 0x8704 -+#define CP_SEM_WAIT_TIMER 0x85BC -+ -+#define DB_DEBUG3 0x98B0 -+#define DB_CLK_OFF_DELAY(x) ((x) << 11) -+#define DB_DEBUG4 0x9B8C -+#define DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) -+ -+#define DCP_TILING_CONFIG 0x6CA0 -+#define PIPE_TILING(x) ((x) << 1) -+#define BANK_TILING(x) ((x) << 4) -+#define GROUP_SIZE(x) ((x) << 6) -+#define ROW_TILING(x) ((x) << 8) -+#define BANK_SWAPS(x) ((x) << 11) -+#define SAMPLE_SPLIT(x) ((x) << 14) -+#define BACKEND_MAP(x) ((x) << 16) -+ -+#define GB_TILING_CONFIG 0x98F0 -+ -+#define GC_USER_SHADER_PIPE_CONFIG 0x8954 -+#define INACTIVE_QD_PIPES(x) ((x) << 8) -+#define INACTIVE_QD_PIPES_MASK 0x0000FF00 -+#define INACTIVE_SIMDS(x) ((x) << 16) -+#define INACTIVE_SIMDS_MASK 0x00FF0000 -+ -+#define GRBM_CNTL 0x8000 -+#define GRBM_READ_TIMEOUT(x) ((x) << 0) -+#define GRBM_SOFT_RESET 0x8020 -+#define SOFT_RESET_CP (1<<0) -+#define GRBM_STATUS 0x8010 -+#define CMDFIFO_AVAIL_MASK 0x0000000F -+#define GUI_ACTIVE (1<<31) -+#define GRBM_STATUS2 0x8014 -+ -+#define HDP_HOST_PATH_CNTL 0x2C00 -+#define HDP_NONSURFACE_BASE 0x2C04 -+#define HDP_NONSURFACE_INFO 0x2C08 -+#define HDP_NONSURFACE_SIZE 0x2C0C -+#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 -+#define HDP_TILING_CONFIG 0x2F3C -+ -+#define MC_ARB_RAMCFG 0x2760 -+#define NOOFBANK_SHIFT 0 -+#define NOOFBANK_MASK 0x00000003 -+#define NOOFRANK_SHIFT 2 -+#define NOOFRANK_MASK 0x00000004 -+#define NOOFROWS_SHIFT 3 -+#define NOOFROWS_MASK 0x00000038 -+#define NOOFCOLS_SHIFT 6 -+#define NOOFCOLS_MASK 0x000000C0 -+#define CHANSIZE_SHIFT 8 -+#define CHANSIZE_MASK 0x00000100 -+#define BURSTLENGTH_SHIFT 9 -+#define BURSTLENGTH_MASK 0x00000200 -+#define MC_VM_AGP_TOP 0x2028 -+#define MC_VM_AGP_BOT 0x202C -+#define MC_VM_AGP_BASE 0x2030 -+#define MC_VM_FB_LOCATION 0x2024 -+#define MC_VM_MB_L1_TLB0_CNTL 0x2234 -+#define MC_VM_MB_L1_TLB1_CNTL 0x2238 -+#define MC_VM_MB_L1_TLB2_CNTL 0x223C -+#define MC_VM_MB_L1_TLB3_CNTL 0x2240 -+#define ENABLE_L1_TLB (1 << 0) -+#define ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) -+#define SYSTEM_ACCESS_MODE_PA_ONLY (0 << 3) -+#define SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 3) -+#define SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) -+#define SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 3) -+#define SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) -+#define EFFECTIVE_L1_TLB_SIZE(x) ((x)<<15) -+#define EFFECTIVE_L1_QUEUE_SIZE(x) ((x)<<18) -+#define MC_VM_MD_L1_TLB0_CNTL 0x2654 -+#define MC_VM_MD_L1_TLB1_CNTL 0x2658 -+#define MC_VM_MD_L1_TLB2_CNTL 0x265C -+#define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C -+#define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 -+#define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 -+ -+#define PA_CL_ENHANCE 0x8A14 -+#define CLIP_VTX_REORDER_ENA (1 << 0) -+#define NUM_CLIP_SEQ(x) ((x) << 1) -+#define PA_SC_AA_CONFIG 0x28C04 -+#define PA_SC_CLIPRECT_RULE 0x2820C -+#define PA_SC_EDGERULE 0x28230 -+#define PA_SC_FIFO_SIZE 0x8BCC -+#define SC_PRIM_FIFO_SIZE(x) ((x) << 0) -+#define SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) -+#define PA_SC_FORCE_EOV_MAX_CNTS 0x8B24 -+#define FORCE_EOV_MAX_CLK_CNT(x) ((x)<<0) -+#define FORCE_EOV_MAX_REZ_CNT(x) ((x)<<16) -+#define PA_SC_LINE_STIPPLE 0x28A0C -+#define PA_SC_LINE_STIPPLE_STATE 0x8B10 -+#define PA_SC_MODE_CNTL 0x28A4C -+#define PA_SC_MULTI_CHIP_CNTL 0x8B20 -+#define SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) -+ -+#define SCRATCH_REG0 0x8500 -+#define SCRATCH_REG1 0x8504 -+#define SCRATCH_REG2 0x8508 -+#define SCRATCH_REG3 0x850C -+#define SCRATCH_REG4 0x8510 -+#define SCRATCH_REG5 0x8514 -+#define SCRATCH_REG6 0x8518 -+#define SCRATCH_REG7 0x851C -+#define SCRATCH_UMSK 0x8540 -+#define SCRATCH_ADDR 0x8544 -+ -+#define SMX_DC_CTL0 0xA020 -+#define USE_HASH_FUNCTION (1 << 0) -+#define CACHE_DEPTH(x) ((x) << 1) -+#define FLUSH_ALL_ON_EVENT (1 << 10) -+#define STALL_ON_EVENT (1 << 11) -+#define SMX_EVENT_CTL 0xA02C -+#define ES_FLUSH_CTL(x) ((x) << 0) -+#define GS_FLUSH_CTL(x) ((x) << 3) -+#define ACK_FLUSH_CTL(x) ((x) << 6) -+#define SYNC_FLUSH_CTL (1 << 8) -+ -+#define SPI_CONFIG_CNTL 0x9100 -+#define GPR_WRITE_PRIORITY(x) ((x) << 0) -+#define DISABLE_INTERP_1 (1 << 5) -+#define SPI_CONFIG_CNTL_1 0x913C -+#define VTX_DONE_DELAY(x) ((x) << 0) -+#define INTERP_ONE_PRIM_PER_ROW (1 << 4) -+#define SPI_INPUT_Z 0x286D8 -+#define SPI_PS_IN_CONTROL_0 0x286CC -+#define NUM_INTERP(x) ((x)<<0) -+#define POSITION_ENA (1<<8) -+#define POSITION_CENTROID (1<<9) -+#define POSITION_ADDR(x) ((x)<<10) -+#define PARAM_GEN(x) ((x)<<15) -+#define PARAM_GEN_ADDR(x) ((x)<<19) -+#define BARYC_SAMPLE_CNTL(x) ((x)<<26) -+#define PERSP_GRADIENT_ENA (1<<28) -+#define LINEAR_GRADIENT_ENA (1<<29) -+#define POSITION_SAMPLE (1<<30) -+#define BARYC_AT_SAMPLE_ENA (1<<31) -+ -+#define SQ_CONFIG 0x8C00 -+#define VC_ENABLE (1 << 0) -+#define EXPORT_SRC_C (1 << 1) -+#define DX9_CONSTS (1 << 2) -+#define ALU_INST_PREFER_VECTOR (1 << 3) -+#define DX10_CLAMP (1 << 4) -+#define CLAUSE_SEQ_PRIO(x) ((x) << 8) -+#define PS_PRIO(x) ((x) << 24) -+#define VS_PRIO(x) ((x) << 26) -+#define GS_PRIO(x) ((x) << 28) -+#define SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8DB0 -+#define SIMDA_RING0(x) ((x)<<0) -+#define SIMDA_RING1(x) ((x)<<8) -+#define SIMDB_RING0(x) ((x)<<16) -+#define SIMDB_RING1(x) ((x)<<24) -+#define SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8DB4 -+#define SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8DB8 -+#define SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8DBC -+#define SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8DC0 -+#define SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8DC4 -+#define SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8DC8 -+#define SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8DCC -+#define ES_PRIO(x) ((x) << 30) -+#define SQ_GPR_RESOURCE_MGMT_1 0x8C04 -+#define NUM_PS_GPRS(x) ((x) << 0) -+#define NUM_VS_GPRS(x) ((x) << 16) -+#define DYN_GPR_ENABLE (1 << 27) -+#define NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) -+#define SQ_GPR_RESOURCE_MGMT_2 0x8C08 -+#define NUM_GS_GPRS(x) ((x) << 0) -+#define NUM_ES_GPRS(x) ((x) << 16) -+#define SQ_MS_FIFO_SIZES 0x8CF0 -+#define CACHE_FIFO_SIZE(x) ((x) << 0) -+#define FETCH_FIFO_HIWATER(x) ((x) << 8) -+#define DONE_FIFO_HIWATER(x) ((x) << 16) -+#define ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) -+#define SQ_STACK_RESOURCE_MGMT_1 0x8C10 -+#define NUM_PS_STACK_ENTRIES(x) ((x) << 0) -+#define NUM_VS_STACK_ENTRIES(x) ((x) << 16) -+#define SQ_STACK_RESOURCE_MGMT_2 0x8C14 -+#define NUM_GS_STACK_ENTRIES(x) ((x) << 0) -+#define NUM_ES_STACK_ENTRIES(x) ((x) << 16) -+#define SQ_THREAD_RESOURCE_MGMT 0x8C0C -+#define NUM_PS_THREADS(x) ((x) << 0) -+#define NUM_VS_THREADS(x) ((x) << 8) -+#define NUM_GS_THREADS(x) ((x) << 16) -+#define NUM_ES_THREADS(x) ((x) << 24) -+ -+#define SX_DEBUG_1 0x9058 -+#define ENABLE_NEW_SMX_ADDRESS (1 << 16) -+#define SX_EXPORT_BUFFER_SIZES 0x900C -+#define COLOR_BUFFER_SIZE(x) ((x) << 0) -+#define POSITION_BUFFER_SIZE(x) ((x) << 8) -+#define SMX_BUFFER_SIZE(x) ((x) << 16) -+#define SX_MISC 0x28350 -+ -+#define TA_CNTL_AUX 0x9508 -+#define DISABLE_CUBE_WRAP (1 << 0) -+#define DISABLE_CUBE_ANISO (1 << 1) -+#define SYNC_GRADIENT (1 << 24) -+#define SYNC_WALKER (1 << 25) -+#define SYNC_ALIGNER (1 << 26) -+#define BILINEAR_PRECISION_6_BIT (0 << 31) -+#define BILINEAR_PRECISION_8_BIT (1 << 31) -+ -+#define TCP_CNTL 0x9610 -+ -+#define VGT_CACHE_INVALIDATION 0x88C4 -+#define CACHE_INVALIDATION(x) ((x)<<0) -+#define VC_ONLY 0 -+#define TC_ONLY 1 -+#define VC_AND_TC 2 -+#define AUTO_INVLD_EN(x) ((x) << 6) -+#define NO_AUTO 0 -+#define ES_AUTO 1 -+#define GS_AUTO 2 -+#define ES_AND_GS_AUTO 3 -+#define VGT_ES_PER_GS 0x88CC -+#define VGT_GS_PER_ES 0x88C8 -+#define VGT_GS_PER_VS 0x88E8 -+#define VGT_GS_VERTEX_REUSE 0x88D4 -+#define VGT_NUM_INSTANCES 0x8974 -+#define VGT_OUT_DEALLOC_CNTL 0x28C5C -+#define DEALLOC_DIST_MASK 0x0000007F -+#define VGT_STRMOUT_EN 0x28AB0 -+#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 -+#define VTX_REUSE_DEPTH_MASK 0x000000FF -+ -+#define VM_CONTEXT0_CNTL 0x1410 -+#define ENABLE_CONTEXT (1 << 0) -+#define PAGE_TABLE_DEPTH(x) (((x) & 3) << 1) -+#define RANGE_PROTECTION_FAULT_ENABLE_DEFAULT (1 << 4) -+#define VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153C -+#define VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157C -+#define VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155C -+#define VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR 0x1518 -+#define VM_L2_CNTL 0x1400 -+#define ENABLE_L2_CACHE (1 << 0) -+#define ENABLE_L2_FRAGMENT_PROCESSING (1 << 1) -+#define ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE (1 << 9) -+#define EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 7) << 14) -+#define VM_L2_CNTL2 0x1404 -+#define INVALIDATE_ALL_L1_TLBS (1 << 0) -+#define INVALIDATE_L2_CACHE (1 << 1) -+#define VM_L2_CNTL3 0x1408 -+#define BANK_SELECT(x) ((x) << 0) -+#define CACHE_UPDATE_MODE(x) ((x) << 6) -+#define VM_L2_STATUS 0x140C -+#define L2_BUSY (1 << 0) -+ -+#define WAIT_UNTIL 0x8040 -+ -+#endif -diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c -index c2b0d71..87c0625 100644 ---- a/drivers/gpu/drm/ttm/ttm_bo.c -+++ b/drivers/gpu/drm/ttm/ttm_bo.c -@@ -44,6 +44,39 @@ - - static int ttm_bo_setup_vm(struct ttm_buffer_object *bo); - static int ttm_bo_swapout(struct ttm_mem_shrink *shrink); -+static void ttm_bo_global_kobj_release(struct kobject *kobj); -+ -+static struct attribute ttm_bo_count = { -+ .name = "bo_count", -+ .mode = S_IRUGO -+}; -+ -+static ssize_t ttm_bo_global_show(struct kobject *kobj, -+ struct attribute *attr, -+ char *buffer) -+{ -+ struct ttm_bo_global *glob = -+ container_of(kobj, struct ttm_bo_global, kobj); -+ -+ return snprintf(buffer, PAGE_SIZE, "%lu\n", -+ (unsigned long) atomic_read(&glob->bo_count)); -+} -+ -+static struct attribute *ttm_bo_global_attrs[] = { -+ &ttm_bo_count, -+ NULL -+}; -+ -+static struct sysfs_ops ttm_bo_global_ops = { -+ .show = &ttm_bo_global_show -+}; -+ -+static struct kobj_type ttm_bo_glob_kobj_type = { -+ .release = &ttm_bo_global_kobj_release, -+ .sysfs_ops = &ttm_bo_global_ops, -+ .default_attrs = ttm_bo_global_attrs -+}; -+ - - static inline uint32_t ttm_bo_type_flags(unsigned type) - { -@@ -66,10 +99,11 @@ static void ttm_bo_release_list(struct kref *list_kref) - - if (bo->ttm) - ttm_tt_destroy(bo->ttm); -+ atomic_dec(&bo->glob->bo_count); - if (bo->destroy) - bo->destroy(bo); - else { -- ttm_mem_global_free(bdev->mem_glob, bo->acc_size, false); -+ ttm_mem_global_free(bdev->glob->mem_glob, bo->acc_size); - kfree(bo); - } - } -@@ -106,7 +140,7 @@ static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) - kref_get(&bo->list_kref); - - if (bo->ttm != NULL) { -- list_add_tail(&bo->swap, &bdev->swap_lru); -+ list_add_tail(&bo->swap, &bo->glob->swap_lru); - kref_get(&bo->list_kref); - } - } -@@ -141,7 +175,7 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, - bool interruptible, - bool no_wait, bool use_sequence, uint32_t sequence) - { -- struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - int ret; - - while (unlikely(atomic_cmpxchg(&bo->reserved, 0, 1) != 0)) { -@@ -153,9 +187,9 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, - if (no_wait) - return -EBUSY; - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - ret = ttm_bo_wait_unreserved(bo, interruptible); -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - - if (unlikely(ret)) - return ret; -@@ -181,16 +215,16 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, - bool interruptible, - bool no_wait, bool use_sequence, uint32_t sequence) - { -- struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - int put_count = 0; - int ret; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - ret = ttm_bo_reserve_locked(bo, interruptible, no_wait, use_sequence, - sequence); - if (likely(ret == 0)) - put_count = ttm_bo_del_from_lru(bo); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); -@@ -200,13 +234,13 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, - - void ttm_bo_unreserve(struct ttm_buffer_object *bo) - { -- struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - ttm_bo_add_to_lru(bo); - atomic_set(&bo->reserved, 0); - wake_up_all(&bo->event_queue); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - } - EXPORT_SYMBOL(ttm_bo_unreserve); - -@@ -217,6 +251,7 @@ EXPORT_SYMBOL(ttm_bo_unreserve); - static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) - { - struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - int ret = 0; - uint32_t page_flags = 0; - -@@ -232,14 +267,14 @@ static int ttm_bo_add_ttm(struct ttm_buffer_object *bo, bool zero_alloc) - page_flags |= TTM_PAGE_FLAG_ZERO_ALLOC; - case ttm_bo_type_kernel: - bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, -- page_flags, bdev->dummy_read_page); -+ page_flags, glob->dummy_read_page); - if (unlikely(bo->ttm == NULL)) - ret = -ENOMEM; - break; - case ttm_bo_type_user: - bo->ttm = ttm_tt_create(bdev, bo->num_pages << PAGE_SHIFT, - page_flags | TTM_PAGE_FLAG_USER, -- bdev->dummy_read_page); -+ glob->dummy_read_page); - if (unlikely(bo->ttm == NULL)) - ret = -ENOMEM; - break; -@@ -360,6 +395,7 @@ out_err: - static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - { - struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - struct ttm_bo_driver *driver = bdev->driver; - int ret; - -@@ -371,7 +407,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - - spin_unlock(&bo->lock); - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - ret = ttm_bo_reserve_locked(bo, false, false, false, 0); - BUG_ON(ret); - if (bo->ttm) -@@ -386,7 +422,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - bo->mem.mm_node = NULL; - } - put_count = ttm_bo_del_from_lru(bo); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - atomic_set(&bo->reserved, 0); - -@@ -396,14 +432,14 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - return 0; - } - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - if (list_empty(&bo->ddestroy)) { - void *sync_obj = bo->sync_obj; - void *sync_obj_arg = bo->sync_obj_arg; - - kref_get(&bo->list_kref); - list_add_tail(&bo->ddestroy, &bdev->ddestroy); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - spin_unlock(&bo->lock); - - if (sync_obj) -@@ -413,7 +449,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - ret = 0; - - } else { -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - spin_unlock(&bo->lock); - ret = -EBUSY; - } -@@ -428,11 +464,12 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all) - - static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) - { -+ struct ttm_bo_global *glob = bdev->glob; - struct ttm_buffer_object *entry, *nentry; - struct list_head *list, *next; - int ret; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - list_for_each_safe(list, next, &bdev->ddestroy) { - entry = list_entry(list, struct ttm_buffer_object, ddestroy); - nentry = NULL; -@@ -449,16 +486,16 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) - } - kref_get(&entry->list_kref); - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - ret = ttm_bo_cleanup_refs(entry, remove_all); - kref_put(&entry->list_kref, ttm_bo_release_list); - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - if (nentry) { - bool next_onlist = !list_empty(next); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - kref_put(&nentry->list_kref, ttm_bo_release_list); -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - /* - * Someone might have raced us and removed the - * next entry from the list. We don't bother restarting -@@ -472,7 +509,7 @@ static int ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all) - break; - } - ret = !list_empty(&bdev->ddestroy); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - return ret; - } -@@ -522,6 +559,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type, - { - int ret = 0; - struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - struct ttm_mem_reg evict_mem; - uint32_t proposed_placement; - -@@ -570,12 +608,12 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type, - goto out; - } - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - if (evict_mem.mm_node) { - drm_mm_put_block(evict_mem.mm_node); - evict_mem.mm_node = NULL; - } -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - bo->evicted = true; - out: - return ret; -@@ -590,6 +628,7 @@ static int ttm_bo_mem_force_space(struct ttm_bo_device *bdev, - uint32_t mem_type, - bool interruptible, bool no_wait) - { -+ struct ttm_bo_global *glob = bdev->glob; - struct drm_mm_node *node; - struct ttm_buffer_object *entry; - struct ttm_mem_type_manager *man = &bdev->man[mem_type]; -@@ -603,7 +642,7 @@ retry_pre_get: - if (unlikely(ret != 0)) - return ret; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - do { - node = drm_mm_search_free(&man->manager, num_pages, - mem->page_alignment, 1); -@@ -624,7 +663,7 @@ retry_pre_get: - if (likely(ret == 0)) - put_count = ttm_bo_del_from_lru(entry); - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - if (unlikely(ret != 0)) - return ret; -@@ -640,21 +679,21 @@ retry_pre_get: - if (ret) - return ret; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - } while (1); - - if (!node) { -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - return -ENOMEM; - } - - node = drm_mm_get_block_atomic(node, num_pages, mem->page_alignment); - if (unlikely(!node)) { -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - goto retry_pre_get; - } - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - mem->mm_node = node; - mem->mem_type = mem_type; - return 0; -@@ -723,6 +762,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, - bool interruptible, bool no_wait) - { - struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - struct ttm_mem_type_manager *man; - - uint32_t num_prios = bdev->driver->num_mem_type_prio; -@@ -762,20 +802,20 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, - if (unlikely(ret)) - return ret; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - node = drm_mm_search_free(&man->manager, - mem->num_pages, - mem->page_alignment, - 1); - if (unlikely(!node)) { -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - break; - } - node = drm_mm_get_block_atomic(node, - mem->num_pages, - mem-> - page_alignment); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - } while (!node); - } - if (node) -@@ -848,7 +888,7 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, - uint32_t proposed_placement, - bool interruptible, bool no_wait) - { -- struct ttm_bo_device *bdev = bo->bdev; -+ struct ttm_bo_global *glob = bo->glob; - int ret = 0; - struct ttm_mem_reg mem; - -@@ -884,9 +924,9 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, - - out_unlock: - if (ret && mem.mm_node) { -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - drm_mm_put_block(mem.mm_node); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - } - return ret; - } -@@ -1022,6 +1062,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev, - INIT_LIST_HEAD(&bo->ddestroy); - INIT_LIST_HEAD(&bo->swap); - bo->bdev = bdev; -+ bo->glob = bdev->glob; - bo->type = type; - bo->num_pages = num_pages; - bo->mem.mem_type = TTM_PL_SYSTEM; -@@ -1034,6 +1075,7 @@ int ttm_buffer_object_init(struct ttm_bo_device *bdev, - bo->seq_valid = false; - bo->persistant_swap_storage = persistant_swap_storage; - bo->acc_size = acc_size; -+ atomic_inc(&bo->glob->bo_count); - - ret = ttm_bo_check_placement(bo, flags, 0ULL); - if (unlikely(ret != 0)) -@@ -1072,13 +1114,13 @@ out_err: - } - EXPORT_SYMBOL(ttm_buffer_object_init); - --static inline size_t ttm_bo_size(struct ttm_bo_device *bdev, -+static inline size_t ttm_bo_size(struct ttm_bo_global *glob, - unsigned long num_pages) - { - size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) & - PAGE_MASK; - -- return bdev->ttm_bo_size + 2 * page_array_size; -+ return glob->ttm_bo_size + 2 * page_array_size; - } - - int ttm_buffer_object_create(struct ttm_bo_device *bdev, -@@ -1093,18 +1135,18 @@ int ttm_buffer_object_create(struct ttm_bo_device *bdev, - { - struct ttm_buffer_object *bo; - int ret; -- struct ttm_mem_global *mem_glob = bdev->mem_glob; -+ struct ttm_mem_global *mem_glob = bdev->glob->mem_glob; - - size_t acc_size = -- ttm_bo_size(bdev, (size + PAGE_SIZE - 1) >> PAGE_SHIFT); -- ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false, false); -+ ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT); -+ ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false); - if (unlikely(ret != 0)) - return ret; - - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - - if (unlikely(bo == NULL)) { -- ttm_mem_global_free(mem_glob, acc_size, false); -+ ttm_mem_global_free(mem_glob, acc_size); - return -ENOMEM; - } - -@@ -1150,6 +1192,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, - struct list_head *head, - unsigned mem_type, bool allow_errors) - { -+ struct ttm_bo_global *glob = bdev->glob; - struct ttm_buffer_object *entry; - int ret; - int put_count; -@@ -1158,30 +1201,31 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, - * Can't use standard list traversal since we're unlocking. - */ - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - - while (!list_empty(head)) { - entry = list_first_entry(head, struct ttm_buffer_object, lru); - kref_get(&entry->list_kref); - ret = ttm_bo_reserve_locked(entry, false, false, false, 0); - put_count = ttm_bo_del_from_lru(entry); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - while (put_count--) - kref_put(&entry->list_kref, ttm_bo_ref_bug); - BUG_ON(ret); - ret = ttm_bo_leave_list(entry, mem_type, allow_errors); - ttm_bo_unreserve(entry); - kref_put(&entry->list_kref, ttm_bo_release_list); -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - } - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - return 0; - } - - int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) - { -+ struct ttm_bo_global *glob = bdev->glob; - struct ttm_mem_type_manager *man; - int ret = -EINVAL; - -@@ -1204,13 +1248,13 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type) - if (mem_type > 0) { - ttm_bo_force_list_clean(bdev, &man->lru, mem_type, false); - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - if (drm_mm_clean(&man->manager)) - drm_mm_takedown(&man->manager); - else - ret = -EBUSY; - -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - } - - return ret; -@@ -1284,11 +1328,82 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, - } - EXPORT_SYMBOL(ttm_bo_init_mm); - -+static void ttm_bo_global_kobj_release(struct kobject *kobj) -+{ -+ struct ttm_bo_global *glob = -+ container_of(kobj, struct ttm_bo_global, kobj); -+ -+ ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink); -+ __free_page(glob->dummy_read_page); -+ kfree(glob); -+} -+ -+void ttm_bo_global_release(struct ttm_global_reference *ref) -+{ -+ struct ttm_bo_global *glob = ref->object; -+ -+ kobject_del(&glob->kobj); -+ kobject_put(&glob->kobj); -+} -+EXPORT_SYMBOL(ttm_bo_global_release); -+ -+int ttm_bo_global_init(struct ttm_global_reference *ref) -+{ -+ struct ttm_bo_global_ref *bo_ref = -+ container_of(ref, struct ttm_bo_global_ref, ref); -+ struct ttm_bo_global *glob = ref->object; -+ int ret; -+ -+ mutex_init(&glob->device_list_mutex); -+ spin_lock_init(&glob->lru_lock); -+ glob->mem_glob = bo_ref->mem_glob; -+ glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); -+ -+ if (unlikely(glob->dummy_read_page == NULL)) { -+ ret = -ENOMEM; -+ goto out_no_drp; -+ } -+ -+ INIT_LIST_HEAD(&glob->swap_lru); -+ INIT_LIST_HEAD(&glob->device_list); -+ -+ ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout); -+ ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink); -+ if (unlikely(ret != 0)) { -+ printk(KERN_ERR TTM_PFX -+ "Could not register buffer object swapout.\n"); -+ goto out_no_shrink; -+ } -+ -+ glob->ttm_bo_extra_size = -+ ttm_round_pot(sizeof(struct ttm_tt)) + -+ ttm_round_pot(sizeof(struct ttm_backend)); -+ -+ glob->ttm_bo_size = glob->ttm_bo_extra_size + -+ ttm_round_pot(sizeof(struct ttm_buffer_object)); -+ -+ atomic_set(&glob->bo_count, 0); -+ -+ kobject_init(&glob->kobj, &ttm_bo_glob_kobj_type); -+ ret = kobject_add(&glob->kobj, ttm_get_kobj(), "buffer_objects"); -+ if (unlikely(ret != 0)) -+ kobject_put(&glob->kobj); -+ return ret; -+out_no_shrink: -+ __free_page(glob->dummy_read_page); -+out_no_drp: -+ kfree(glob); -+ return ret; -+} -+EXPORT_SYMBOL(ttm_bo_global_init); -+ -+ - int ttm_bo_device_release(struct ttm_bo_device *bdev) - { - int ret = 0; - unsigned i = TTM_NUM_MEM_TYPES; - struct ttm_mem_type_manager *man; -+ struct ttm_bo_global *glob = bdev->glob; - - while (i--) { - man = &bdev->man[i]; -@@ -1304,100 +1419,74 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) - } - } - -+ mutex_lock(&glob->device_list_mutex); -+ list_del(&bdev->device_list); -+ mutex_unlock(&glob->device_list_mutex); -+ - if (!cancel_delayed_work(&bdev->wq)) - flush_scheduled_work(); - - while (ttm_bo_delayed_delete(bdev, true)) - ; - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - if (list_empty(&bdev->ddestroy)) - TTM_DEBUG("Delayed destroy list was clean\n"); - - if (list_empty(&bdev->man[0].lru)) - TTM_DEBUG("Swap list was clean\n"); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - -- ttm_mem_unregister_shrink(bdev->mem_glob, &bdev->shrink); - BUG_ON(!drm_mm_clean(&bdev->addr_space_mm)); - write_lock(&bdev->vm_lock); - drm_mm_takedown(&bdev->addr_space_mm); - write_unlock(&bdev->vm_lock); - -- __free_page(bdev->dummy_read_page); - return ret; - } - EXPORT_SYMBOL(ttm_bo_device_release); - --/* -- * This function is intended to be called on drm driver load. -- * If you decide to call it from firstopen, you must protect the call -- * from a potentially racing ttm_bo_driver_finish in lastclose. -- * (This may happen on X server restart). -- */ -- - int ttm_bo_device_init(struct ttm_bo_device *bdev, -- struct ttm_mem_global *mem_glob, -- struct ttm_bo_driver *driver, uint64_t file_page_offset, -+ struct ttm_bo_global *glob, -+ struct ttm_bo_driver *driver, -+ uint64_t file_page_offset, - bool need_dma32) - { - int ret = -EINVAL; - -- bdev->dummy_read_page = NULL; - rwlock_init(&bdev->vm_lock); -- spin_lock_init(&bdev->lru_lock); -- - bdev->driver = driver; -- bdev->mem_glob = mem_glob; - - memset(bdev->man, 0, sizeof(bdev->man)); - -- bdev->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); -- if (unlikely(bdev->dummy_read_page == NULL)) { -- ret = -ENOMEM; -- goto out_err0; -- } -- - /* - * Initialize the system memory buffer type. - * Other types need to be driver / IOCTL initialized. - */ - ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0, 0); - if (unlikely(ret != 0)) -- goto out_err1; -+ goto out_no_sys; - - bdev->addr_space_rb = RB_ROOT; - ret = drm_mm_init(&bdev->addr_space_mm, file_page_offset, 0x10000000); - if (unlikely(ret != 0)) -- goto out_err2; -+ goto out_no_addr_mm; - - INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); - bdev->nice_mode = true; - INIT_LIST_HEAD(&bdev->ddestroy); -- INIT_LIST_HEAD(&bdev->swap_lru); - bdev->dev_mapping = NULL; -+ bdev->glob = glob; - bdev->need_dma32 = need_dma32; -- ttm_mem_init_shrink(&bdev->shrink, ttm_bo_swapout); -- ret = ttm_mem_register_shrink(mem_glob, &bdev->shrink); -- if (unlikely(ret != 0)) { -- printk(KERN_ERR TTM_PFX -- "Could not register buffer object swapout.\n"); -- goto out_err2; -- } - -- bdev->ttm_bo_extra_size = -- ttm_round_pot(sizeof(struct ttm_tt)) + -- ttm_round_pot(sizeof(struct ttm_backend)); -- -- bdev->ttm_bo_size = bdev->ttm_bo_extra_size + -- ttm_round_pot(sizeof(struct ttm_buffer_object)); -+ mutex_lock(&glob->device_list_mutex); -+ list_add_tail(&bdev->device_list, &glob->device_list); -+ mutex_unlock(&glob->device_list_mutex); - - return 0; --out_err2: -+out_no_addr_mm: - ttm_bo_clean_mm(bdev, 0); --out_err1: -- __free_page(bdev->dummy_read_page); --out_err0: -+out_no_sys: - return ret; - } - EXPORT_SYMBOL(ttm_bo_device_init); -@@ -1647,21 +1736,21 @@ void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo) - - static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) - { -- struct ttm_bo_device *bdev = -- container_of(shrink, struct ttm_bo_device, shrink); -+ struct ttm_bo_global *glob = -+ container_of(shrink, struct ttm_bo_global, shrink); - struct ttm_buffer_object *bo; - int ret = -EBUSY; - int put_count; - uint32_t swap_placement = (TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM); - -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - while (ret == -EBUSY) { -- if (unlikely(list_empty(&bdev->swap_lru))) { -- spin_unlock(&bdev->lru_lock); -+ if (unlikely(list_empty(&glob->swap_lru))) { -+ spin_unlock(&glob->lru_lock); - return -EBUSY; - } - -- bo = list_first_entry(&bdev->swap_lru, -+ bo = list_first_entry(&glob->swap_lru, - struct ttm_buffer_object, swap); - kref_get(&bo->list_kref); - -@@ -1673,16 +1762,16 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) - - ret = ttm_bo_reserve_locked(bo, false, true, false, 0); - if (unlikely(ret == -EBUSY)) { -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - ttm_bo_wait_unreserved(bo, false); - kref_put(&bo->list_kref, ttm_bo_release_list); -- spin_lock(&bdev->lru_lock); -+ spin_lock(&glob->lru_lock); - } - } - - BUG_ON(ret != 0); - put_count = ttm_bo_del_from_lru(bo); -- spin_unlock(&bdev->lru_lock); -+ spin_unlock(&glob->lru_lock); - - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); -@@ -1736,6 +1825,6 @@ out: - - void ttm_bo_swapout_all(struct ttm_bo_device *bdev) - { -- while (ttm_bo_swapout(&bdev->shrink) == 0) -+ while (ttm_bo_swapout(&bdev->glob->shrink) == 0) - ; - } -diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c -index ad4ada0..c70927e 100644 ---- a/drivers/gpu/drm/ttm/ttm_bo_util.c -+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c -@@ -41,9 +41,9 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo) - struct ttm_mem_reg *old_mem = &bo->mem; - - if (old_mem->mm_node) { -- spin_lock(&bo->bdev->lru_lock); -+ spin_lock(&bo->glob->lru_lock); - drm_mm_put_block(old_mem->mm_node); -- spin_unlock(&bo->bdev->lru_lock); -+ spin_unlock(&bo->glob->lru_lock); - } - old_mem->mm_node = NULL; - } -diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c -index 0b14eb1..541744d 100644 ---- a/drivers/gpu/drm/ttm/ttm_global.c -+++ b/drivers/gpu/drm/ttm/ttm_global.c -@@ -71,7 +71,7 @@ int ttm_global_item_ref(struct ttm_global_reference *ref) - - mutex_lock(&item->mutex); - if (item->refcount == 0) { -- item->object = kmalloc(ref->size, GFP_KERNEL); -+ item->object = kzalloc(ref->size, GFP_KERNEL); - if (unlikely(item->object == NULL)) { - ret = -ENOMEM; - goto out_err; -@@ -89,7 +89,6 @@ int ttm_global_item_ref(struct ttm_global_reference *ref) - mutex_unlock(&item->mutex); - return 0; - out_err: -- kfree(item->object); - mutex_unlock(&item->mutex); - item->object = NULL; - return ret; -@@ -105,7 +104,6 @@ void ttm_global_item_unref(struct ttm_global_reference *ref) - BUG_ON(ref->object != item->object); - if (--item->refcount == 0) { - ref->release(ref); -- kfree(item->object); - item->object = NULL; - } - mutex_unlock(&item->mutex); -diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c -index 87323d4..072c281 100644 ---- a/drivers/gpu/drm/ttm/ttm_memory.c -+++ b/drivers/gpu/drm/ttm/ttm_memory.c -@@ -26,15 +26,180 @@ - **************************************************************************/ - - #include "ttm/ttm_memory.h" -+#include "ttm/ttm_module.h" - #include - #include - #include - #include - #include - --#define TTM_PFX "[TTM] " - #define TTM_MEMORY_ALLOC_RETRIES 4 - -+struct ttm_mem_zone { -+ struct kobject kobj; -+ struct ttm_mem_global *glob; -+ const char *name; -+ uint64_t zone_mem; -+ uint64_t emer_mem; -+ uint64_t max_mem; -+ uint64_t swap_limit; -+ uint64_t used_mem; -+}; -+ -+static struct attribute ttm_mem_sys = { -+ .name = "zone_memory", -+ .mode = S_IRUGO -+}; -+static struct attribute ttm_mem_emer = { -+ .name = "emergency_memory", -+ .mode = S_IRUGO | S_IWUSR -+}; -+static struct attribute ttm_mem_max = { -+ .name = "available_memory", -+ .mode = S_IRUGO | S_IWUSR -+}; -+static struct attribute ttm_mem_swap = { -+ .name = "swap_limit", -+ .mode = S_IRUGO | S_IWUSR -+}; -+static struct attribute ttm_mem_used = { -+ .name = "used_memory", -+ .mode = S_IRUGO -+}; -+ -+static void ttm_mem_zone_kobj_release(struct kobject *kobj) -+{ -+ struct ttm_mem_zone *zone = -+ container_of(kobj, struct ttm_mem_zone, kobj); -+ -+ printk(KERN_INFO TTM_PFX -+ "Zone %7s: Used memory at exit: %llu kiB.\n", -+ zone->name, (unsigned long long) zone->used_mem >> 10); -+ kfree(zone); -+} -+ -+static ssize_t ttm_mem_zone_show(struct kobject *kobj, -+ struct attribute *attr, -+ char *buffer) -+{ -+ struct ttm_mem_zone *zone = -+ container_of(kobj, struct ttm_mem_zone, kobj); -+ uint64_t val = 0; -+ -+ spin_lock(&zone->glob->lock); -+ if (attr == &ttm_mem_sys) -+ val = zone->zone_mem; -+ else if (attr == &ttm_mem_emer) -+ val = zone->emer_mem; -+ else if (attr == &ttm_mem_max) -+ val = zone->max_mem; -+ else if (attr == &ttm_mem_swap) -+ val = zone->swap_limit; -+ else if (attr == &ttm_mem_used) -+ val = zone->used_mem; -+ spin_unlock(&zone->glob->lock); -+ -+ return snprintf(buffer, PAGE_SIZE, "%llu\n", -+ (unsigned long long) val >> 10); -+} -+ -+static void ttm_check_swapping(struct ttm_mem_global *glob); -+ -+static ssize_t ttm_mem_zone_store(struct kobject *kobj, -+ struct attribute *attr, -+ const char *buffer, -+ size_t size) -+{ -+ struct ttm_mem_zone *zone = -+ container_of(kobj, struct ttm_mem_zone, kobj); -+ int chars; -+ unsigned long val; -+ uint64_t val64; -+ -+ chars = sscanf(buffer, "%lu", &val); -+ if (chars == 0) -+ return size; -+ -+ val64 = val; -+ val64 <<= 10; -+ -+ spin_lock(&zone->glob->lock); -+ if (val64 > zone->zone_mem) -+ val64 = zone->zone_mem; -+ if (attr == &ttm_mem_emer) { -+ zone->emer_mem = val64; -+ if (zone->max_mem > val64) -+ zone->max_mem = val64; -+ } else if (attr == &ttm_mem_max) { -+ zone->max_mem = val64; -+ if (zone->emer_mem < val64) -+ zone->emer_mem = val64; -+ } else if (attr == &ttm_mem_swap) -+ zone->swap_limit = val64; -+ spin_unlock(&zone->glob->lock); -+ -+ ttm_check_swapping(zone->glob); -+ -+ return size; -+} -+ -+static struct attribute *ttm_mem_zone_attrs[] = { -+ &ttm_mem_sys, -+ &ttm_mem_emer, -+ &ttm_mem_max, -+ &ttm_mem_swap, -+ &ttm_mem_used, -+ NULL -+}; -+ -+static struct sysfs_ops ttm_mem_zone_ops = { -+ .show = &ttm_mem_zone_show, -+ .store = &ttm_mem_zone_store -+}; -+ -+static struct kobj_type ttm_mem_zone_kobj_type = { -+ .release = &ttm_mem_zone_kobj_release, -+ .sysfs_ops = &ttm_mem_zone_ops, -+ .default_attrs = ttm_mem_zone_attrs, -+}; -+ -+static void ttm_mem_global_kobj_release(struct kobject *kobj) -+{ -+ struct ttm_mem_global *glob = -+ container_of(kobj, struct ttm_mem_global, kobj); -+ -+ kfree(glob); -+} -+ -+static struct kobj_type ttm_mem_glob_kobj_type = { -+ .release = &ttm_mem_global_kobj_release, -+}; -+ -+static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob, -+ bool from_wq, uint64_t extra) -+{ -+ unsigned int i; -+ struct ttm_mem_zone *zone; -+ uint64_t target; -+ -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ -+ if (from_wq) -+ target = zone->swap_limit; -+ else if (capable(CAP_SYS_ADMIN)) -+ target = zone->emer_mem; -+ else -+ target = zone->max_mem; -+ -+ target = (extra > target) ? 0ULL : target; -+ -+ if (zone->used_mem > target) -+ return true; -+ } -+ return false; -+} -+ - /** - * At this point we only support a single shrink callback. - * Extend this if needed, perhaps using a linked list of callbacks. -@@ -42,34 +207,17 @@ - * many threads may try to swap out at any given time. - */ - --static void ttm_shrink(struct ttm_mem_global *glob, bool from_workqueue, -+static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq, - uint64_t extra) - { - int ret; - struct ttm_mem_shrink *shrink; -- uint64_t target; -- uint64_t total_target; - - spin_lock(&glob->lock); - if (glob->shrink == NULL) - goto out; - -- if (from_workqueue) { -- target = glob->swap_limit; -- total_target = glob->total_memory_swap_limit; -- } else if (capable(CAP_SYS_ADMIN)) { -- total_target = glob->emer_total_memory; -- target = glob->emer_memory; -- } else { -- total_target = glob->max_total_memory; -- target = glob->max_memory; -- } -- -- total_target = (extra >= total_target) ? 0 : total_target - extra; -- target = (extra >= target) ? 0 : target - extra; -- -- while (glob->used_memory > target || -- glob->used_total_memory > total_target) { -+ while (ttm_zones_above_swap_target(glob, from_wq, extra)) { - shrink = glob->shrink; - spin_unlock(&glob->lock); - ret = shrink->do_shrink(shrink); -@@ -81,6 +229,8 @@ out: - spin_unlock(&glob->lock); - } - -+ -+ - static void ttm_shrink_work(struct work_struct *work) - { - struct ttm_mem_global *glob = -@@ -89,63 +239,198 @@ static void ttm_shrink_work(struct work_struct *work) - ttm_shrink(glob, true, 0ULL); - } - -+static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob, -+ const struct sysinfo *si) -+{ -+ struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL); -+ uint64_t mem; -+ int ret; -+ -+ if (unlikely(!zone)) -+ return -ENOMEM; -+ -+ mem = si->totalram - si->totalhigh; -+ mem *= si->mem_unit; -+ -+ zone->name = "kernel"; -+ zone->zone_mem = mem; -+ zone->max_mem = mem >> 1; -+ zone->emer_mem = (mem >> 1) + (mem >> 2); -+ zone->swap_limit = zone->max_mem - (mem >> 3); -+ zone->used_mem = 0; -+ zone->glob = glob; -+ glob->zone_kernel = zone; -+ kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -+ ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); -+ if (unlikely(ret != 0)) { -+ kobject_put(&zone->kobj); -+ return ret; -+ } -+ glob->zones[glob->num_zones++] = zone; -+ return 0; -+} -+ -+#ifdef CONFIG_HIGHMEM -+static int ttm_mem_init_highmem_zone(struct ttm_mem_global *glob, -+ const struct sysinfo *si) -+{ -+ struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL); -+ uint64_t mem; -+ int ret; -+ -+ if (unlikely(!zone)) -+ return -ENOMEM; -+ -+ if (si->totalhigh == 0) -+ return 0; -+ -+ mem = si->totalram; -+ mem *= si->mem_unit; -+ -+ zone->name = "highmem"; -+ zone->zone_mem = mem; -+ zone->max_mem = mem >> 1; -+ zone->emer_mem = (mem >> 1) + (mem >> 2); -+ zone->swap_limit = zone->max_mem - (mem >> 3); -+ zone->used_mem = 0; -+ zone->glob = glob; -+ glob->zone_highmem = zone; -+ kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -+ ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); -+ if (unlikely(ret != 0)) { -+ kobject_put(&zone->kobj); -+ return ret; -+ } -+ glob->zones[glob->num_zones++] = zone; -+ return 0; -+} -+#else -+static int ttm_mem_init_dma32_zone(struct ttm_mem_global *glob, -+ const struct sysinfo *si) -+{ -+ struct ttm_mem_zone *zone = kzalloc(sizeof(*zone), GFP_KERNEL); -+ uint64_t mem; -+ int ret; -+ -+ if (unlikely(!zone)) -+ return -ENOMEM; -+ -+ mem = si->totalram; -+ mem *= si->mem_unit; -+ -+ /** -+ * No special dma32 zone needed. -+ */ -+ -+ if (mem <= ((uint64_t) 1ULL << 32)) -+ return 0; -+ -+ /* -+ * Limit max dma32 memory to 4GB for now -+ * until we can figure out how big this -+ * zone really is. -+ */ -+ -+ mem = ((uint64_t) 1ULL << 32); -+ zone->name = "dma32"; -+ zone->zone_mem = mem; -+ zone->max_mem = mem >> 1; -+ zone->emer_mem = (mem >> 1) + (mem >> 2); -+ zone->swap_limit = zone->max_mem - (mem >> 3); -+ zone->used_mem = 0; -+ zone->glob = glob; -+ glob->zone_dma32 = zone; -+ kobject_init(&zone->kobj, &ttm_mem_zone_kobj_type); -+ ret = kobject_add(&zone->kobj, &glob->kobj, zone->name); -+ if (unlikely(ret != 0)) { -+ kobject_put(&zone->kobj); -+ return ret; -+ } -+ glob->zones[glob->num_zones++] = zone; -+ return 0; -+} -+#endif -+ - int ttm_mem_global_init(struct ttm_mem_global *glob) - { - struct sysinfo si; -- uint64_t mem; -+ int ret; -+ int i; -+ struct ttm_mem_zone *zone; - - spin_lock_init(&glob->lock); - glob->swap_queue = create_singlethread_workqueue("ttm_swap"); - INIT_WORK(&glob->work, ttm_shrink_work); - init_waitqueue_head(&glob->queue); -+ kobject_init(&glob->kobj, &ttm_mem_glob_kobj_type); -+ ret = kobject_add(&glob->kobj, -+ ttm_get_kobj(), -+ "memory_accounting"); -+ if (unlikely(ret != 0)) { -+ kobject_put(&glob->kobj); -+ return ret; -+ } - - si_meminfo(&si); - -- mem = si.totalram - si.totalhigh; -- mem *= si.mem_unit; -- -- glob->max_memory = mem >> 1; -- glob->emer_memory = (mem >> 1) + (mem >> 2); -- glob->swap_limit = glob->max_memory - (mem >> 3); -- glob->used_memory = 0; -- glob->used_total_memory = 0; -- glob->shrink = NULL; -- -- mem = si.totalram; -- mem *= si.mem_unit; -- -- glob->max_total_memory = mem >> 1; -- glob->emer_total_memory = (mem >> 1) + (mem >> 2); -- -- glob->total_memory_swap_limit = glob->max_total_memory - (mem >> 3); -- -- printk(KERN_INFO TTM_PFX "TTM available graphics memory: %llu MiB\n", -- glob->max_total_memory >> 20); -- printk(KERN_INFO TTM_PFX "TTM available object memory: %llu MiB\n", -- glob->max_memory >> 20); -- -+ ret = ttm_mem_init_kernel_zone(glob, &si); -+ if (unlikely(ret != 0)) -+ goto out_no_zone; -+#ifdef CONFIG_HIGHMEM -+ ret = ttm_mem_init_highmem_zone(glob, &si); -+ if (unlikely(ret != 0)) -+ goto out_no_zone; -+#else -+ ret = ttm_mem_init_dma32_zone(glob, &si); -+ if (unlikely(ret != 0)) -+ goto out_no_zone; -+#endif -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ printk(KERN_INFO TTM_PFX -+ "Zone %7s: Available graphics memory: %llu kiB.\n", -+ zone->name, (unsigned long long) zone->max_mem >> 10); -+ } - return 0; -+out_no_zone: -+ ttm_mem_global_release(glob); -+ return ret; - } - EXPORT_SYMBOL(ttm_mem_global_init); - - void ttm_mem_global_release(struct ttm_mem_global *glob) - { -- printk(KERN_INFO TTM_PFX "Used total memory is %llu bytes.\n", -- (unsigned long long)glob->used_total_memory); -+ unsigned int i; -+ struct ttm_mem_zone *zone; -+ - flush_workqueue(glob->swap_queue); - destroy_workqueue(glob->swap_queue); - glob->swap_queue = NULL; -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ kobject_del(&zone->kobj); -+ kobject_put(&zone->kobj); -+ } -+ kobject_del(&glob->kobj); -+ kobject_put(&glob->kobj); - } - EXPORT_SYMBOL(ttm_mem_global_release); - --static inline void ttm_check_swapping(struct ttm_mem_global *glob) -+static void ttm_check_swapping(struct ttm_mem_global *glob) - { -- bool needs_swapping; -+ bool needs_swapping = false; -+ unsigned int i; -+ struct ttm_mem_zone *zone; - - spin_lock(&glob->lock); -- needs_swapping = (glob->used_memory > glob->swap_limit || -- glob->used_total_memory > -- glob->total_memory_swap_limit); -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ if (zone->used_mem > zone->swap_limit) { -+ needs_swapping = true; -+ break; -+ } -+ } -+ - spin_unlock(&glob->lock); - - if (unlikely(needs_swapping)) -@@ -153,44 +438,60 @@ static inline void ttm_check_swapping(struct ttm_mem_global *glob) - - } - --void ttm_mem_global_free(struct ttm_mem_global *glob, -- uint64_t amount, bool himem) -+static void ttm_mem_global_free_zone(struct ttm_mem_global *glob, -+ struct ttm_mem_zone *single_zone, -+ uint64_t amount) - { -+ unsigned int i; -+ struct ttm_mem_zone *zone; -+ - spin_lock(&glob->lock); -- glob->used_total_memory -= amount; -- if (!himem) -- glob->used_memory -= amount; -- wake_up_all(&glob->queue); -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ if (single_zone && zone != single_zone) -+ continue; -+ zone->used_mem -= amount; -+ } - spin_unlock(&glob->lock); - } - -+void ttm_mem_global_free(struct ttm_mem_global *glob, -+ uint64_t amount) -+{ -+ return ttm_mem_global_free_zone(glob, NULL, amount); -+} -+ - static int ttm_mem_global_reserve(struct ttm_mem_global *glob, -- uint64_t amount, bool himem, bool reserve) -+ struct ttm_mem_zone *single_zone, -+ uint64_t amount, bool reserve) - { - uint64_t limit; -- uint64_t lomem_limit; - int ret = -ENOMEM; -+ unsigned int i; -+ struct ttm_mem_zone *zone; - - spin_lock(&glob->lock); -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ if (single_zone && zone != single_zone) -+ continue; - -- if (capable(CAP_SYS_ADMIN)) { -- limit = glob->emer_total_memory; -- lomem_limit = glob->emer_memory; -- } else { -- limit = glob->max_total_memory; -- lomem_limit = glob->max_memory; -- } -+ limit = (capable(CAP_SYS_ADMIN)) ? -+ zone->emer_mem : zone->max_mem; - -- if (unlikely(glob->used_total_memory + amount > limit)) -- goto out_unlock; -- if (unlikely(!himem && glob->used_memory + amount > lomem_limit)) -- goto out_unlock; -+ if (zone->used_mem > limit) -+ goto out_unlock; -+ } - - if (reserve) { -- glob->used_total_memory += amount; -- if (!himem) -- glob->used_memory += amount; -+ for (i = 0; i < glob->num_zones; ++i) { -+ zone = glob->zones[i]; -+ if (single_zone && zone != single_zone) -+ continue; -+ zone->used_mem += amount; -+ } - } -+ - ret = 0; - out_unlock: - spin_unlock(&glob->lock); -@@ -199,12 +500,17 @@ out_unlock: - return ret; - } - --int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, -- bool no_wait, bool interruptible, bool himem) -+ -+static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob, -+ struct ttm_mem_zone *single_zone, -+ uint64_t memory, -+ bool no_wait, bool interruptible) - { - int count = TTM_MEMORY_ALLOC_RETRIES; - -- while (unlikely(ttm_mem_global_reserve(glob, memory, himem, true) -+ while (unlikely(ttm_mem_global_reserve(glob, -+ single_zone, -+ memory, true) - != 0)) { - if (no_wait) - return -ENOMEM; -@@ -216,6 +522,56 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, - return 0; - } - -+int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, -+ bool no_wait, bool interruptible) -+{ -+ /** -+ * Normal allocations of kernel memory are registered in -+ * all zones. -+ */ -+ -+ return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait, -+ interruptible); -+} -+ -+int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, -+ struct page *page, -+ bool no_wait, bool interruptible) -+{ -+ -+ struct ttm_mem_zone *zone = NULL; -+ -+ /** -+ * Page allocations may be registed in a single zone -+ * only if highmem or !dma32. -+ */ -+ -+#ifdef CONFIG_HIGHMEM -+ if (PageHighMem(page) && glob->zone_highmem != NULL) -+ zone = glob->zone_highmem; -+#else -+ if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) -+ zone = glob->zone_kernel; -+#endif -+ return ttm_mem_global_alloc_zone(glob, zone, PAGE_SIZE, no_wait, -+ interruptible); -+} -+ -+void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page) -+{ -+ struct ttm_mem_zone *zone = NULL; -+ -+#ifdef CONFIG_HIGHMEM -+ if (PageHighMem(page) && glob->zone_highmem != NULL) -+ zone = glob->zone_highmem; -+#else -+ if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL) -+ zone = glob->zone_kernel; -+#endif -+ ttm_mem_global_free_zone(glob, zone, PAGE_SIZE); -+} -+ -+ - size_t ttm_round_pot(size_t size) - { - if ((size & (size - 1)) == 0) -diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c -index 59ce819..9a6edbf 100644 ---- a/drivers/gpu/drm/ttm/ttm_module.c -+++ b/drivers/gpu/drm/ttm/ttm_module.c -@@ -29,16 +29,72 @@ - * Jerome Glisse - */ - #include --#include -+#include -+#include -+#include "ttm/ttm_module.h" -+#include "drm_sysfs.h" -+ -+static DECLARE_WAIT_QUEUE_HEAD(exit_q); -+atomic_t device_released; -+ -+static struct device_type ttm_drm_class_type = { -+ .name = "ttm", -+ /** -+ * Add pm ops here. -+ */ -+}; -+ -+static void ttm_drm_class_device_release(struct device *dev) -+{ -+ atomic_set(&device_released, 1); -+ wake_up_all(&exit_q); -+} -+ -+static struct device ttm_drm_class_device = { -+ .type = &ttm_drm_class_type, -+ .release = &ttm_drm_class_device_release -+}; -+ -+struct kobject *ttm_get_kobj(void) -+{ -+ struct kobject *kobj = &ttm_drm_class_device.kobj; -+ BUG_ON(kobj == NULL); -+ return kobj; -+} - - static int __init ttm_init(void) - { -+ int ret; -+ -+ ret = dev_set_name(&ttm_drm_class_device, "ttm"); -+ if (unlikely(ret != 0)) -+ return ret; -+ - ttm_global_init(); -+ -+ atomic_set(&device_released, 0); -+ ret = drm_class_device_register(&ttm_drm_class_device); -+ if (unlikely(ret != 0)) -+ goto out_no_dev_reg; -+ - return 0; -+out_no_dev_reg: -+ atomic_set(&device_released, 1); -+ wake_up_all(&exit_q); -+ ttm_global_release(); -+ return ret; - } - - static void __exit ttm_exit(void) - { -+ drm_class_device_unregister(&ttm_drm_class_device); -+ -+ /** -+ * Refuse to unload until the TTM device is released. -+ * Not sure this is 100% needed. -+ */ -+ -+ wait_event(exit_q, atomic_read(&device_released) == 1); - ttm_global_release(); - } - -diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c -index b8b6c4a..a55ee1a 100644 ---- a/drivers/gpu/drm/ttm/ttm_tt.c -+++ b/drivers/gpu/drm/ttm/ttm_tt.c -@@ -34,76 +34,13 @@ - #include - #include - #include -+#include "drm_cache.h" - #include "ttm/ttm_module.h" - #include "ttm/ttm_bo_driver.h" - #include "ttm/ttm_placement.h" - - static int ttm_tt_swapin(struct ttm_tt *ttm); - --#if defined(CONFIG_X86) --static void ttm_tt_clflush_page(struct page *page) --{ -- uint8_t *page_virtual; -- unsigned int i; -- -- if (unlikely(page == NULL)) -- return; -- -- page_virtual = kmap_atomic(page, KM_USER0); -- -- for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) -- clflush(page_virtual + i); -- -- kunmap_atomic(page_virtual, KM_USER0); --} -- --static void ttm_tt_cache_flush_clflush(struct page *pages[], -- unsigned long num_pages) --{ -- unsigned long i; -- -- mb(); -- for (i = 0; i < num_pages; ++i) -- ttm_tt_clflush_page(*pages++); -- mb(); --} --#elif !defined(__powerpc__) --static void ttm_tt_ipi_handler(void *null) --{ -- ; --} --#endif -- --void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages) --{ -- --#if defined(CONFIG_X86) -- if (cpu_has_clflush) { -- ttm_tt_cache_flush_clflush(pages, num_pages); -- return; -- } --#elif defined(__powerpc__) -- unsigned long i; -- -- for (i = 0; i < num_pages; ++i) { -- struct page *page = pages[i]; -- void *page_virtual; -- -- if (unlikely(page == NULL)) -- continue; -- -- page_virtual = kmap_atomic(page, KM_USER0); -- flush_dcache_range((unsigned long) page_virtual, -- (unsigned long) page_virtual + PAGE_SIZE); -- kunmap_atomic(page_virtual, KM_USER0); -- } --#else -- if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0) -- printk(KERN_ERR TTM_PFX -- "Timed out waiting for drm cache flush.\n"); --#endif --} -- - /** - * Allocates storage for pointers to the pages that back the ttm. - * -@@ -179,7 +116,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm) - set_page_dirty_lock(page); - - ttm->pages[i] = NULL; -- ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, false); -+ ttm_mem_global_free(ttm->glob->mem_glob, PAGE_SIZE); - put_page(page); - } - ttm->state = tt_unpopulated; -@@ -190,8 +127,7 @@ static void ttm_tt_free_user_pages(struct ttm_tt *ttm) - static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index) - { - struct page *p; -- struct ttm_bo_device *bdev = ttm->bdev; -- struct ttm_mem_global *mem_glob = bdev->mem_glob; -+ struct ttm_mem_global *mem_glob = ttm->glob->mem_glob; - int ret; - - while (NULL == (p = ttm->pages[index])) { -@@ -200,21 +136,14 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index) - if (!p) - return NULL; - -- if (PageHighMem(p)) { -- ret = -- ttm_mem_global_alloc(mem_glob, PAGE_SIZE, -- false, false, true); -- if (unlikely(ret != 0)) -- goto out_err; -+ ret = ttm_mem_global_alloc_page(mem_glob, p, false, false); -+ if (unlikely(ret != 0)) -+ goto out_err; -+ -+ if (PageHighMem(p)) - ttm->pages[--ttm->first_himem_page] = p; -- } else { -- ret = -- ttm_mem_global_alloc(mem_glob, PAGE_SIZE, -- false, false, false); -- if (unlikely(ret != 0)) -- goto out_err; -+ else - ttm->pages[++ttm->last_lomem_page] = p; -- } - } - return p; - out_err: -@@ -310,7 +239,7 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm, - } - - if (ttm->caching_state == tt_cached) -- ttm_tt_cache_flush(ttm->pages, ttm->num_pages); -+ drm_clflush_pages(ttm->pages, ttm->num_pages); - - for (i = 0; i < ttm->num_pages; ++i) { - cur_page = ttm->pages[i]; -@@ -368,8 +297,8 @@ static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm) - printk(KERN_ERR TTM_PFX - "Erroneous page count. " - "Leaking pages.\n"); -- ttm_mem_global_free(ttm->bdev->mem_glob, PAGE_SIZE, -- PageHighMem(cur_page)); -+ ttm_mem_global_free_page(ttm->glob->mem_glob, -+ cur_page); - __free_page(cur_page); - } - } -@@ -414,7 +343,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm, - struct mm_struct *mm = tsk->mm; - int ret; - int write = (ttm->page_flags & TTM_PAGE_FLAG_WRITE) != 0; -- struct ttm_mem_global *mem_glob = ttm->bdev->mem_glob; -+ struct ttm_mem_global *mem_glob = ttm->glob->mem_glob; - - BUG_ON(num_pages != ttm->num_pages); - BUG_ON((ttm->page_flags & TTM_PAGE_FLAG_USER) == 0); -@@ -424,7 +353,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm, - */ - - ret = ttm_mem_global_alloc(mem_glob, num_pages * PAGE_SIZE, -- false, false, false); -+ false, false); - if (unlikely(ret != 0)) - return ret; - -@@ -435,7 +364,7 @@ int ttm_tt_set_user(struct ttm_tt *ttm, - - if (ret != num_pages && write) { - ttm_tt_free_user_pages(ttm); -- ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE, false); -+ ttm_mem_global_free(mem_glob, num_pages * PAGE_SIZE); - return -ENOMEM; - } - -@@ -459,8 +388,7 @@ struct ttm_tt *ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size, - if (!ttm) - return NULL; - -- ttm->bdev = bdev; -- -+ ttm->glob = bdev->glob; - ttm->num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; - ttm->first_himem_page = ttm->num_pages; - ttm->last_lomem_page = -1; -diff --git a/firmware/Makefile b/firmware/Makefile -index 621de8e..d166a7f 100644 ---- a/firmware/Makefile -+++ b/firmware/Makefile -@@ -42,6 +42,22 @@ fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin - fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ - cxgb3/t3c_psram-1.1.0.bin \ - cxgb3/t3fw-7.4.0.bin -+fw-shipped-$(CONFIG_DRM_MGA) += matrox/g200_warp.fw matrox/g400_warp.fw -+fw-shipped-$(CONFIG_DRM_R128) += r128/r128_cce.bin -+fw-shipped-$(CONFIG_DRM_RADEON) += radeon/R100_cp.bin radeon/R200_cp.bin \ -+ radeon/R300_cp.bin radeon/R420_cp.bin \ -+ radeon/RS690_cp.bin radeon/RS600_cp.bin \ -+ radeon/R520_cp.bin \ -+ radeon/R600_pfp.bin radeon/R600_me.bin \ -+ radeon/RV610_pfp.bin radeon/RV610_me.bin \ -+ radeon/RV630_pfp.bin radeon/RV630_me.bin \ -+ radeon/RV620_pfp.bin radeon/RV620_me.bin \ -+ radeon/RV635_pfp.bin radeon/RV635_me.bin \ -+ radeon/RV670_pfp.bin radeon/RV670_me.bin \ -+ radeon/RS780_pfp.bin radeon/RS780_me.bin \ -+ radeon/RV770_pfp.bin radeon/RV770_me.bin \ -+ radeon/RV730_pfp.bin radeon/RV730_me.bin \ -+ radeon/RV710_pfp.bin radeon/RV710_me.bin - fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin - fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin - fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ -diff --git a/firmware/WHENCE b/firmware/WHENCE -index 0f5649a..00378ee 100644 ---- a/firmware/WHENCE -+++ b/firmware/WHENCE -@@ -698,3 +698,124 @@ Found in hex form in kernel source, with the following comment: - Copyright (c) 1998-2002 by Paul Davis - - -------------------------------------------------------------------------- -+ -+Driver: mga - Matrox G200/G400/G550 -+ -+File: matrox/g200_warp.fw -+File: matrox/g400_warp.fw -+ -+Licence: -+ -+Copyright 1999 Matrox Graphics Inc. -+All Rights Reserved. -+ -+Permission is hereby granted, free of charge, to any person obtaining a -+copy of this software and associated documentation files (the "Software"), -+to deal in the Software without restriction, including without limitation -+the rights to use, copy, modify, merge, publish, distribute, sublicense, -+and/or sell copies of the Software, and to permit persons to whom the -+Software is furnished to do so, subject to the following conditions: -+ -+The above copyright notice and this permission notice shall be included -+in all copies or substantial portions of the Software. -+ -+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, -+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -+OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Found in hex form in kernel source. -+ -+-------------------------------------------------------------------------- -+ -+Driver: r128 - ATI Rage 128 -+ -+File: r128/r128_cce.bin -+ -+Licence: -+ -+Copyright 2000 Advanced Micro Devices, Inc. -+ -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ -+Found in decimal form in kernel source. -+ -+-------------------------------------------------------------------------- -+ -+Driver: radeon - ATI Radeon -+ -+File: radeon/R100_cp.bin -+File: radeon/R200_cp.bin -+File: radeon/R300_cp.bin -+File: radeon/R420_cp.bin -+File: radeon/RS600_cp.bin -+File: radeon/RS690_cp.bin -+File: radeon/R520_cp.bin -+File: radeon/R600_pfp.bin -+File: radeon/R600_me.bin -+File: radeon/RV610_pfp.bin -+File: radeon/RV610_me.bin -+File: radeon/RV630_pfp.bin -+File: radeon/RV630_me.bin -+File: radeon/RV620_pfp.bin -+File: radeon/RV620_me.bin -+File: radeon/RV635_pfp.bin -+File: radeon/RV635_me.bin -+File: radeon/RV670_pfp.bin -+File: radeon/RV670_me.bin -+File: radeon/RS780_pfp.bin -+File: radeon/RS780_me.bin -+File: radeon/RV770_pfp.bin -+File: radeon/RV770_me.bin -+File: radeon/RV730_pfp.bin -+File: radeon/RV730_me.bin -+File: radeon/RV710_pfp.bin -+File: radeon/RV710_me.bin -+ -+Licence: -+ -+ * Copyright 2007-2009 Advanced Micro Devices, Inc. -+ * All Rights Reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ -+Found in hex form in kernel source. -+ -+-------------------------------------------------------------------------- -diff --git a/firmware/matrox/g200_warp.H16 b/firmware/matrox/g200_warp.H16 -new file mode 100644 -index 0000000..5064b6f ---- /dev/null -+++ b/firmware/matrox/g200_warp.H16 -@@ -0,0 +1,28 @@ -+/* -+ * WARP pipes are named according to the functions they perform, where -+ * -+ * - T stands for computation of texture stage 0 -+ * - T2 stands for computation of both texture stage 0 and texture stage 1 -+ * - G stands for computation of triangle intensity (Gouraud interpolation) -+ * - Z stands for computation of Z buffer interpolation -+ * - S stands for computation of specular highlight -+ * - A stands for computation of the alpha channel -+ * - F stands for computation of vertex fog interpolation -+ */ -+/* TGZ */ -+:04B8000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9728007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2608015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E803800AEA17C12BBD008000E8008000E8B3689725008000E833C033AF3C274FE9573920E9281960EC2B3220E91D3B20E9B30500E0162820E9233B33AD1E2B20E91C8020E9573620E90080A0E94040D8ECFF80C0E990E200E085FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E884FF0AEA008000E8C941C8EC42E100E082FF20EA008000E8008000E8008000E8C840C0EC008000E87FFF20EA008000E8008000E8008000E871 -+/* TGZF */ -+:0548000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE91750569F008000E8370F5C9F00E02F20008000E8281960ECB30500E0008000E8233B33AD008000E8172617DF35174FE9008000E8008000E8008000E839374FE92F2F17AF008000E8008000E8008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E078FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E877FF0AEA008000E8C941C8EC42E100E075FF20EA008000E8008000E8008000E8C840C0EC008000E872FF20EA008000E8008000E8008000E8BB -+/* TGZA */ -+:04E80000000098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E97D8007EA241F20E9154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D444CB6254454B603802AEA17C12BBD2D20252007C044C6B3689725008000E833C033AF3C274FE91F62579F008000E83F3D5D9F00E00720008000E8281960ECB30500E0008000E8233B33AD008000E81F261FDF9D1F4FE9008000E8008000E8008000E89E3F4FE907071FAF008000E8008000E8008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E07AFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E879FF0AEA008000E8C941C8EC42E100E077FF20EA008000E8008000E8008000E8C840C0EC008000E874FF20EA008000E8008000E8008000E8D9 -+/* TGZAF */ -+:0568000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9838007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E26F8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E80D211AB6052131B62D444CB6254454B603802AEA17C12BBD0D2005202FC021C6B3689725008000E833C033AF3C274FE900E0252007C044C61750569F00E02D20370F5C9F00E02F201F62579F00E007203F3D5D9F008000E8008000E8281960ECB30500E0172617DF233B33AD35174FE91F261FDF9D1F4FE99E3F4FE939374FE92F2F17AF008000E807071FAF008000E831804FE9008000E89C804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E074FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E873FF0AEA008000E8C941C8EC42E100E071FF20EA008000E8008000E8008000E8C840C0EC008000E86EFF20EA008000E8008000E8008000E830 -+/* TGZS */ -+:05C0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98B8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2778015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F3F2F5D9F00E08F20A5374FE90F170FAF06C021C4008000E8008000E8A3804FE9062000E01F261FDFA11F4FE9A23F4FE9008000E8008000E806061FAF008000E8008000E8008000E8A0804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E06CFF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E86BFF0AEA008000E8C941C8EC42E100E069FF20EA008000E8008000E8008000E8C840C0EC008000E866FF20EA008000E8008000E8008000E85C -+/* TGZSF */ -+:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C63F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82F2000E0A3804FE9062000E01F261FDF172617DF35174FE9A11F4FE9A23F4FE906061FAF39374FE92F2F17AF008000E8A0804FE9008000E831804FE9008000E8008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E8F9 -+/* TGZSA */ -+:05E0000000008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E98F8007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E27B8015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D444CB6054454B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D200520008000E83F2F5D9F00E00F201750569FA5374FE906C021C40F170FAF370F5C9F008000E82FC044C6A3804FE9062000E01F261FDF172617DF9D174FE9A11F4FE9A23F4FE906061FAF00E0AF209E374FE92F172FAFA0804FE9008000E8008000E89C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E068FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E867FF0AEA008000E8C941C8EC42E100E065FF20EA008000E8008000E8008000E8C840C0EC008000E862FF20EA008000E8008000E8008000E883 -+/* TGZAF */ -+:05B8000000008000E8008000E8008000E8008000E8008000E8008000E80098A0E94040D8ECFF80C0E9008000E81FD718BD3FD722BD8104890401040904C941C0EC110400E041CC41CD49CC49CDD141C0EC51CC51CD80041004080400E000CCC0CDD149C0EC8A1F20E98B3F20E9413C41AD493C49AD10CC10CD08CC08CDB94149BB1FF041CD513C51AD009880E9948007EA241F20E9214580E81A4D80E8315580E8008000E8154149BD1D4151BD2E412AB83453A0E815301D3058E300E0B54048BD3D4050BD2443A0E82C4BA0E8157209E300E01D723530B530BD303D309C97579F008000E86C64C8EC98E1B505BD052E3032C0A0E833C0A0E87464C8EC403C40AD326A2A302073336A00E028731C7283E2808015EAB83D28DF303520DF403000E0CCE26472254252BF2D424ABF302E30DF382E38DF181D45E91E1545E92B4951BD00E01F73383840AF303040AF241F24DF1D3220E92C1F2CDF1A3320E9B01008E34010B81026F030CD2FF038CD2B8020E92A8020E9A62088E200E0AF20282A26AF202AC0AF341F34DF462446DF283080BF203880BF472447DF4E2C4EDF4F2C4FDF563456DF281528DF201D20DF573457DF00E01D05048010EA89E22B303FC11DBD008000E8008000E8008000E8A068BF25008000E820C020AF2805977400E02A1016C020E9048010EA8CE2950528C128AD1FC115BD008000E8008000E8A8679F6B008000E828C028AD1D252005283280AD402A40BD1C8020E9203320AD207300E0B64951BB262FB0E8192020E9352035DF3D203DDF152015DF1D201DDF26D026CD29492AB8264080BD3B4850BD3E54579F00E082E11EAF599F008000E826302930483C48AD2B72C2E12CC044C2052434BF0D242CBF2D464EBF254656BF201D6F8F323E5FE93E50569F00E03B301E8F519F331E5FE9054454B20D444CB219C0B0E834C044C4337300E03E62579F1EAF599F00E00D20843E58E9281D6F8F052000E0851E58E99B3B33DF202042AF3042569F803E57E93F8F519F30805FE9282824AF811E57E9054757BF0D474FBF888058E91B291BDF301D6F8F3A304FE91C3026DF09E33B053E50569F3B3F4FE91E8F519F00E0AC202D444CB42C1CC0AF254454B400E0C830304630AF1B1B48AF00E02520382C4FE9868057E9381D6F8F287400E00D444CB0054454B02D209B10823E57E932F01BCD1EBD599F831E57E9384738AF34202A3000E00D2032200520878057E91F54579F1742569F00E03B6A3F8F519F371E4FE937322AAF00E03200008000E827C044C0361F4FE91F1F26DF371B37BF172617DF3E174FE93F3F4FE9341F34AF2B05A720332B37DF2717C0AF34804FE9008000E82D211AB0252131B00D211AB2052131B203802AEA17C12BBD2D20252005200D20B3689725008000E833C033AF2FC021C01642569F3C274FE91E62579F008000E8252131B42D211AB43F2F5D9F008000E8330500E0281960EC0D211AB6052131B6370F5C9F00E02F20233B33AD1E261EDFA71E4FE9172616DF2D2000E0A83F4FE92F2F1EAF252000E0A4164FE90FC021C2A6804FE91F62579F0D2005202FC021C62D444CB6254454B63F2F5D9F00E00F202D20252007C044C61750569FA5374FE906C021C40F170FAF370F5C9F008000E81E62579F008000E83E3D5D9F00E007202F2000E0A30F4FE9062000E01F261FDF172617DFA11F4FE91E261EDF9D1E4FE935174FE9A23F4FE906061FAF39374FE92F2F17AF07071EAFA0804FE99E3E4FE931804FE99C804FE9008000E8573920E9162820E91D3B20E91E2B20E92B3220E91C2320E9573620E90080A0E94040D8ECFF80C0E990E200E063FF20EA19C8C1CD1FD718BD3FD722BD9F4149BD008000E8254149BD2D4151BD0D8007EA008000E8354048BD3D4050BD008000E825302D303530B530BD303D309CA75B9F008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E8008000E862FF0AEA008000E8C941C8EC42E100E060FF20EA008000E8008000E8008000E8C840C0EC008000E85DFF20EA008000E8008000E8008000E8D8 -+:0000000001FF -diff --git a/firmware/matrox/g400_warp.H16 b/firmware/matrox/g400_warp.H16 -new file mode 100644 -index 0000000..b432d10 ---- /dev/null -+++ b/firmware/matrox/g400_warp.H16 -@@ -0,0 +1,44 @@ -+/* -+ * WARP pipes are named according to the functions they perform, where -+ * -+ * - T stands for computation of texture stage 0 -+ * - T2 stands for computation of both texture stage 0 and texture stage 1 -+ * - G stands for computation of triangle intensity (Gouraud interpolation) -+ * - Z stands for computation of Z buffer interpolation -+ * - S stands for computation of specular highlight -+ * - A stands for computation of the alpha channel -+ * - F stands for computation of vertex fog interpolation -+ */ -+/* TGZ */ -+:0338000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900588015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4A8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A444CB0024454B02A444CB21A4454B21D803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A444CB41A4454B439E52C9F383D20E988735EE92A201A202A464EBF1A4656BF31532F9F3E304FE939E52C9F3F384FE90A474FBF024757BF31532F9F3A314FE939E52C9F3B394FE92A434BBF1A4353BF30502E9F36314FE938212C9F37394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AFFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD6FF20EA008000E84E334ECF573B57CF9DFF20EA57C0BFEA0080A0E90000D8EC59 -+/* TGZF */ -+:0360000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005D8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4F8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E827CF75C63C3D20E90A444CB0024454B02A444CB21A4454B220803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F312720E90A444CB4024454B42A454DB61A4555B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9AAFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF98FF20EA57C0BFEA0080A0E90000D8EC90 -+/* TGZA */ -+:0358000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039005C8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF4E8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E927CF74C63DCF74C20A444CB0024454B02A444CB21A4454B220803AEA0A20022088735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A200A474FBF024757BF30502E9F3E304FE938212C9F3F384FE92A464EBF1A4656BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9ABFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFD3FF20EA008000E84E334ECF573B57CF99FF20EA57C0BFEA0080A0E90000D8EC35 -+/* TGZAF */ -+:0380000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900618015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF538007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF32322DDF22222DDF12122DDF3A3A2DDF473747DF573D57DF3DCF74C037CF74C40A444CB0024454B031532F9F343720E939E52C9F3C3D20E92A444CB21A4454B226803AEA0A20022088735EE92A201A203DCF74C227CF74C630502E9F32315FE938212C9F33395FE931532F9F9C2720E90A444CB4024454B42A444CB61A4454B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A454DB6024555B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A464EBF1A4656BF0A474FBF024757BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A6FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCDFF20EA008000E84E334ECF573B57CF94FF20EA57C0BFEA0080A0E90000D8EC89 -+/* TGZS */ -+:03A0000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC31003900658015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF578007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B229803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A454DB21A4555B20A454DB4024555B438212C9F3B394FE90A2002202A201A202A464EBF1A4656BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A474FBF024757BF31532F9FA4314FE939E52C9FA5394FE92A434BBF1A4353BF30502E9FA1304FE938212C9FA2384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E9A2FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFCAFF20EA008000E84E334ECF573B57CF90FF20EA57C0BFEA0080A0E90000D8ECD8 -+/* TGZSF */ -+:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF75C62A201A20A7304FE90A20022031532F9F312720E939E52C9FA8384FE92A454DB61A4555B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F35314FE938212C9F39394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECD3 -+/* TGZSA */ -+:03C8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006A8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF5C8007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B22E803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE9008000E82A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE90A474FBF024757BF31532F9FA1304FE939E52C9FA2384FE92A434BBF1A4353BF30502E9F9D314FE938212C9F9E394FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E99DFF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC5FF20EA008000E84E334ECF573B57CF8BFF20EA57C0BFEA0080A0E90000D8ECA0 -+/* TGZSAF */ -+:03E8000000008898E9008000E80080A0E90000D8ECFF80C0E9008000E8224048BF2A4050BF324149BF3A4151BFC36BCB6B008898E9737BC8EC96E241047B43A0E8734BA0E8ADEE299F00E0490490E251043146B1E84941C0EC3957B1E8000446E27353A0E85141C0EC310039006E8015EA080410045149C0EC2F4160EA312039201F42A0E82A424ABF274AA0E81A4252BF1E4960EA737BC8EC265160EA324048BD224050BD124149BD3A4151BDBF2F26BD00E07B723220222012203A20463146BF4E314EBFB3E22D9F008000E8563156BF473947BF4F394FBF573957BF608007EA244120E94273F8EC00E02D7333720CE3A52F1EBD43432DDF4B4B2DDFAE1E26BD58E3336653532DDF008000E8B83833BF00E059E31E1241E91A2241E92B403DE93F4BA0E82D73307605803DEA3743A0E83D53A0E84870F8EC2B483CE91F27BCE8008000E8008000E8008000E815C020E915C020E915C020E915C020E9183A41E91D3241E92A4020E9563D56DF463746DF4E3F4EDF163020E94F3F4FDF473747DF573D57DF32322DDF22222DDF12122DDF3A3A2DDF27CF74C237CF74C40A444CB0024454B03DCF74C0343720E931532F9F382720E939E52C9F3C3D20E92A444CB21A4454B232803AEA0A20022027CF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA62720E939E52C9FA33D20E92A444CB41A4454B40A454DB0024555B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A454DB21A4555B20A454DB4024555B427CF74C62A201A20A7304FE90A20022031532F9F9C2720E939E52C9FA8384FE92A444CB61A4454B630502E9F36314FE938212C9F37394FE90A454DB6024555B63DCF75C62A201A202A464EBF1A4656BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A474FBF024757BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A434BBF1A4353BF30502E9F35304FE938212C9F39384FE931532F9F803157E939E52C9F813957E9374850BD8A3620E9867657E98B3E20E9823057E9877757E9833857E9354951BD84315EE9301F5FE985395EE9572520E92B4820E91D37E1EA1E35E1EA00E02677244920E999FF20EA162620E9572EBFEA1C46A0E8234EA0E82B56A0E81D47A0E8244FA0E82C57A0E81C0023002B0000E01D0024002C0000E01C6523652B6500E01D6524652C6500E01C2360EC36D736AD2B8060EC1D2460EC3ED73EAD2C8060EC1C2BDEE82380DEE8368036BD3E803EBD33D71CBD3BD723BD468046CF4F804FCF563356CF473B47CFC1FF20EA008000E84E334ECF573B57CF87FF20EA57C0BFEA0080A0E90000D8EC83 -+/* T2GZ */ -+:0438000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900788015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF698007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B225803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F008000E82A4454B41A4464B439E52C9F383D20E988735EE92A201A202A4656BF1A4666BF31532F9F3E304FE939E52C9F3F384FE90A4757BF024767BF31532F9F3A314FE939E52C9F3B394FE92A4353BF1A4363BF30502E9F36314FE938212C9F37394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99FFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBEFF20EA008000E8583358CF693B69CF7DFF20EA57C0BFEA0080A0E90000D8ECAC -+/* T2GZF */ -+:0460000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007D8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6E8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C439E52C9F348020E931532F9F008000E888735EE9008000E80FCF75C63C3D20E90A4454B0024464B02A4454B21A4464B228803AEA0A2002203DCF74C22A201A2030502E9F32315FE938212C9F33395FE931532F9F310F20E90A4454B4024464B42A4555B61A4565B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99AFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBBFF20EA008000E8583358CF693B69CF78FF20EA57C0BFEA0080A0E90000D8ECFB -+/* T2GZA */ -+:0458000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039007C8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF6D8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C431532F9F348020E939E52C9F3C3D20E90A4454B0024464B02A4454B21A4464B229803AEA0A2002200FCF74C63DCF74C288735EE92A201A2030502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A200A4757BF024767BF30502E9F3E304FE938212C9F3F384FE92A4656BF1A4666BF31532F9F3A314FE939E52C9F3B394FE931532F9F36304FE939E52C9F37384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E99BFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFBAFF20EA008000E8583358CF693B69CF79FF20EA57C0BFEA0080A0E90000D8ECA0 -+/* T2GZAF */ -+:0480000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900818015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF728007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF12122DDF22222DDF32322DDF3A3A2DDF683D68DF493749DF3DCF74C037CF74C40A4454B0024464B031532F9F343720E939E52C9F3C3D20E92A4454B21A4464B22E803AEA0A20022088735EE92A201A203DCF74C20FCF74C630502E9F32315FE938212C9F33395FE931532F9F9C0F20E90A4454B4024464B42A4454B61A4464B639E52C9F383D20E90A2002202A201A203DCF75C6008000E830502E9F3E304FE938212C9F3F384FE90A4555B6024565B631532F9F3A314FE939E52C9F3B394FE9313D20E90A2002202A4656BF1A4666BF0A4757BF024767BF30502E9F36304FE938212C9F37384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E996FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB5FF20EA008000E8583358CF693B69CF74FF20EA57C0BFEA0080A0E90000D8ECDC -+/* T2GZS */ -+:04A0000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC31003900858015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF768007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B231803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE92A4555B21A4565B20A4555B4024565B438212C9F3B394FE92A201A200A2002202A4656BF1A4666BF31532F9F36314FE939E52C9F37394FE930502E9FA7304FE938212C9FA8384FE90A4757BF024767BF31532F9FA4314FE939E52C9FA5394FE92A4353BF1A4363BF30502E9FA1304FE938212C9FA2384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E992FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFB2FF20EA008000E8583358CF693B69CF70FF20EA57C0BFEA0080A0E90000D8EC43 -+/* T2GZSF */ -+:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF75C62A201A20A7304FE90A20022031532F9F310F20E939E52C9FA8384FE92A4555B61A4565B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F35314FE938212C9F39394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC56 -+/* T2GZSA */ -+:04C8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008A8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7B8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B236803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE9008000E82A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE90A4757BF024767BF31532F9FA1304FE939E52C9FA2384FE92A4353BF1A4363BF30502E9F9D314FE938212C9F9E394FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E98DFF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFADFF20EA008000E8583358CF693B69CF6BFF20EA57C0BFEA0080A0E90000D8EC23 -+/* T2GZSAF */ -+:04E8000000008A98E9008000E80080A0E90000D8ECFF80C0E9008000E80A4050BF2A4060BF324151BF3A4161BFC36BD36B008A98E9737BC8EC96E241047B43A0E87353A0E8ADEE239F00E0510490E261043146B1E85141E0EC3967B1E8000446E27363A0E86141E0EC310039008E8015EA100420046151E0EC2F4160EA312039201F42A0E82A4252BF0F52A0E81A4262BF1E5160EA737BC8EC0E6160EA324050BD224060BD124151BD3A4161BDBF2F0EBD97E27B723220222012203A203548B1E83D59B1E8463146BF563156BFB3E22D9F008000E8663166BF473947BF573957BF673967BF7F8007EA244120E935003D0000E02D7333720CE38D2F1EBD4375F8EC35203D2043432DDF53532DDFAE1E0EBD58E33366483548BF583558BF683568BF493D49BF593D59BF693D69BF63632DDF4D7DF8EC59E300E0B83833BF2D733076183A41E93F53A0E805803DEA3743A0E83D63A0E85070F8EC2B503CE91F0FBCE8008000E85978F8EC008000E815C020E915C020E915C020E915C020E91E1241E91A2241E9463746DF563F56DF2B403DE9663D66DF1D3241E9673D67DF473747DF573F57DF2A4020E9593F59DF163020E9693D69DF483748DF583F58DF683D68DF493749DF32322DDF22222DDF12122DDF3A3A2DDF0FCF74C237CF74C40A4454B0024464B03DCF74C0343720E931532F9F380F20E939E52C9F3C3D20E92A4454B21A4464B23A803AEA0A2002200FCF75C02A201A2030502E9F32315FE938212C9F33395FE93DCF75C237CF75C431532F9FA60F20E939E52C9FA33D20E92A4454B41A4464B40A4555B0024565B088735EE92A201A20A03720E90A20022031532F9F3E304FE939E52C9F3F384FE930502E9F3A314FE938212C9F3B394FE92A4555B21A4565B20A4555B4024565B40FCF74C62A201A20A7304FE90A20022031532F9F9C0F20E939E52C9FA8384FE92A4454B61A4464B630502E9F36314FE938212C9F37394FE90A4555B6024565B63DCF75C62A201A202A4656BF1A4666BF31532F9FA4314FE939E52C9FA5394FE9313D20E90A2002200A4757BF024767BF30502E9FA1304FE938212C9FA2384FE931532F9F9D314FE939E52C9F9E394FE92A4353BF1A4363BF30502E9F35304FE938212C9F39384FE90A4858BF024868BF31532F9F803157E939E52C9F813957E92A4959BF1A4969BF30502E9F823057E938212C9F833857E931532F9F84315EE939E52C9F85395EE9867657E98A3620E9877757E98B3EBFEA803057E9813857E9823157E9867857E9833957E9877957E9301F5FE98A3420E98B3C20E9375060BD570D20E9355161BD2B5020E91D37E1EA1E35E1EA00E00E77245120E989FF20EA160E20E9572EBFEA0B46A0E81B56A0E82B66A0E80C47A0E81C57A0E82C67A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC36D736AD2B8060EC0C1C60EC3ED73EAD2C8060EC0B2BDEE81B80DEE8368036BD3E803EBD33D70BBD3BD71BBD468046CF578057CF663366CF473B47CF563356CF673B67CF0B48A0E81B58A0E82B68A0E80C49A0E81C59A0E82C69A0E80B001B002B0000E00C001C002C0000E00B651B652B6500E00C651C652C6500E00B1B60EC34D734AD2B8060EC0C1C60EC3CD73CAD2C8060EC0B2BDEE81B80DEE8348034BD3C803CBD33D70BBD3BD71BBD488048CF598059CF683368CF493B49CFA9FF20EA008000E8583358CF693B69CF67FF20EA57C0BFEA0080A0E90000D8ECEE -+:0000000001FF -diff --git a/firmware/r128/r128_cce.bin.ihex b/firmware/r128/r128_cce.bin.ihex -new file mode 100644 -index 0000000..4831315 ---- /dev/null -+++ b/firmware/r128/r128_cce.bin.ihex -@@ -0,0 +1,129 @@ -+:1000000000000000108038000000000010003800E0 -+:10001000000000020000008E0000000200000091BD -+:1000200000000000402E2423000000006062124FF8 -+:10003000000000002E2B596D000000007677753E01 -+:1000400000000000898984820000000023BC8B0D21 -+:10005000000000002323232300000000238DABB405 -+:1000600000000000232323230000000100B028002B -+:100070000000000100032800000000010004C0008F -+:100080000000000100030800000000023660300E8E -+:100090000000000B00040000000000000000000051 -+:1000A000000000010200151D0000000100001D0EEF -+:1000B00000000001000039D900000001000019D73C -+:1000C0000000000C0000001C00000001000019D618 -+:1000D0000000000C0000001C0000000200000017DF -+:1000E0000000000B01200000000000000100358A24 -+:1000F0000000000100064000000000090000001E92 -+:100100000000000108D015B4000000101910100004 -+:100110000000000300002000000000000000280094 -+:1001200000000001000308000000000100003D0E77 -+:10013000000000010000C8000000000A0000882A3A -+:10014000000000090000002A000000010200150F55 -+:1001500000000002000028240000000100003D65AE -+:100160000000000100003D66000000020000002BBE -+:100170000000000100F32DB4000000012200D8BFF0 -+:100180000000000100E088BF0000000C1333383786 -+:1001900000000001020615650000000C0000003799 -+:1001A00000000001020015640000000100003D662F -+:1001B000000000020000002E000000040020083AA9 -+:1001C0000000000100080800000000010006C0FF58 -+:1001D000000000040040003D000000010007C800CE -+:1001E00000000001000700FF000000030000000005 -+:1001F0000000000C0000005C000000020000002E67 -+:100200000000000C000000B00000000100003D767E -+:100210000000000100032800000000010000480069 -+:1002200000000001000208000000000106001D0E91 -+:1002300000000001000248000000000100028800E8 -+:100240000000000100F3C5F80000000100100000EC -+:10025000000000060030004E0000000100003D6379 -+:100260000000001080303DF0000000021000384314 -+:1002700000000002000028430000000C000000B055 -+:100280000000000100003D760000000100003D7705 -+:100290000000000100003D0E0000000100003D0FC5 -+:1002A000000000010050280000000006003000524D -+:1002B0000000001080303DF00000000100003DF81B -+:1002C00000000002000000520000000100053D0E89 -+:1002D0000000000100103D0F00000002003000553A -+:1002E0000000000100003D700000000100001E89B8 -+:1002F0000000000100003D710000000300003D729D -+:100300000000000C0000005C000000020000006221 -+:100310000000000100003F280000000100003F270E -+:100320000000000100003E820000000100003E8845 -+:100330000000000100003E660000000100003E6772 -+:100340000000000100003E760000000100003E6851 -+:100350000000000100003E690000000100003E6C4A -+:100360000000000000003E6D0000000100002800B9 -+:1003700000000001005028000000000100003D685E -+:100380000000000100030800000000060000006EED -+:10039000000000010002C0000000000106303D62C4 -+:1003A0000000000200000070000000020030006F3A -+:1003B00000000000200038C0000000010001C0C0A3 -+:1003C0000000000E0000007D0000000C0003287FEC -+:1003D00000000001020015BB0000000C00030880B3 -+:1003E0000000000002003DBC0000000100003DBB19 -+:1003F0000000000000003DBC00000003000480007D -+:100400000000000100048000000000030006C0029C -+:100410000000000100B0280000000000306038003B -+:100420000000000100C028000000000100B008002A -+:100430000000000100D600000000000712801086B6 -+:10044000000000000000280000000001000039CC7E -+:1004500000000001000039CD00000001000039C992 -+:1004600000000001000039CA00000000000039CB84 -+:10047000000000011003B80000000001009000001F -+:100480000000000110003800000000010003080017 -+:100490000000000100903D1B0000000140203D0ACB -+:1004A0000000000140203D0B00000001000880001A -+:1004B000000000010001C0C00000000E0000009F0D -+:1004C0000000000C000308800000000142203DBD38 -+:1004D0000000000C0003087F0000000142003DBB4B -+:1004E0000000000C000308800000000142203DBC19 -+:1004F00000000002000000A20000000140203DBDFD -+:100500000000000140003DBB0000000140203DBC58 -+:1005100000000001000840000000000100A00000F1 -+:1005200000000006003000A6000000101060380037 -+:1005300000000009000000A80000000300400000C7 -+:100540000000000300403D1D00000000000000000E -+:1005500000000000000001000000000E000000AEDE -+:10056000000000010001C0A900000001020015C741 -+:100570000000000C000000B0000000000000280097 -+:10058000000000010001C0AA00000001020015D215 -+:10059000000000010001C0A900000003020015C70F -+:1005A0000000000100003E88000000010001C0BA08 -+:1005B0000000000102001728000000010001C0BB7C -+:1005C000000000010200165A0000000000003E5B1F -+:1005D000000000000000010000000000000010000A -+:1005E000000000010006400B00000009000000BCF4 -+:1005F00000000000000028000000000000000000D3 -+:1006000000000000000000000000000000000000EA -+:1006100000000000000000000000000000000000DA -+:1006200000000000000000000000000000000000CA -+:1006300000000000000000000000000000000000BA -+:1006400000000000000000000000000000000000AA -+:10065000000000000000000000000000000000009A -+:10066000000000000000000000000000000000008A -+:10067000000000000000000000000000000000007A -+:10068000000000000000000000000000000000006A -+:10069000000000000000000000000000000000005A -+:1006A000000000000000000000000000000000004A -+:1006B000000000000000000000000000000000003A -+:1006C000000000000000000000000000000000002A -+:1006D000000000000000000000000000000000001A -+:1006E000000000000000000000000000000000000A -+:1006F00000000000000000000000000000000000FA -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -diff --git a/firmware/radeon/R100_cp.bin.ihex b/firmware/radeon/R100_cp.bin.ihex -new file mode 100644 -index 0000000..151647b ---- /dev/null -+++ b/firmware/radeon/R100_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:1000000000000000210070000000000020007000CF -+:1000100000000004000000B400000004000000B86C -+:10002000000000006F5B4D4C000000004C4C427F14 -+:10003000000000005B568A92000000004CA09C6DFE -+:1000400000000000AD4C4C4C000000004CE1AF3D06 -+:1000500000000000D8AFAFAF00000000D64C4CDC71 -+:10006000000000004CD10D1000000016000F000031 -+:1000700000000000362F242D0000000400000012B4 -+:1000800000000016000F000000000000362F282D91 -+:1000900000000002000380E70000000204002C972B -+:1000A00000000016000F000100000000333A373056 -+:1000B00000000002000077EF0000000200061000C0 -+:1000C0000000001A000000210000001E0000400097 -+:1000D00000000002000610000000001A00000021CD -+:1000E0000000001E0000400000000002000610009A -+:1000F0000000001A000000210000001E0000400067 -+:100100000000000400000017000000020003802B24 -+:1001100000000002040067E0000000040000001777 -+:1001200000000002000077E000000002000650001E -+:1001300000000002000037E100000006040067E153 -+:1001400000000002000077E000000002000077E1FC -+:1001500000000006000077E100000000FFFFFFFF45 -+:100160000000000010000000000000020003802BCF -+:1001700000000006040067E0000000020000767541 -+:100180000000000200007676000000020000767792 -+:100190000000000600007678000000020003802CBA -+:1001A00000000002040026760000000200007677BE -+:1001B0000000000600007678000000180000002F04 -+:1001C000000000180000002F0000000600000000E2 -+:1001D000000000180000003000000018000000308F -+:1001E0000000000600000000000000020160500056 -+:1001F000000000020006500000000002000980001C -+:1002000000000002000610000000000464C0603E10 -+:1002100000000002000380E600000002040025C583 -+:1002200000000016000800000000000000000000B0 -+:10023000000000020400251D00000002000075807F -+:100240000000000200067581000000020400258005 -+:100250000000000200067581000000040000004953 -+:10026000000000000000500000000002000380E6D3 -+:1002700000000002040025C5000000020006100076 -+:10028000000000020000750E000000020001900056 -+:10029000000000140001105500000012000000557D -+:1002A000000000020400250F000000040000504F71 -+:1002B00000000002000380E600000002040025C5E3 -+:1002C0000000000200007565000000020000756675 -+:1002D000000000040000005800000002000380E657 -+:1002E00000000002040025C50000000201E655B42C -+:1002F000000000024401B0E40000000201C110E46B -+:10030000000000182666706600000002040C2565D7 -+:1003100000000018000000660000000204002564D0 -+:100320000000000200007566000000040000005D8F -+:1003300000000008004010690000000200101000DA -+:1003400000000002000D80FF000000080080006C2B -+:1003500000000002000F900000000002000E00FFED -+:100360000000000600000000000000180000008FE0 -+:10037000000000040000005B00000002000380E6B3 -+:1003800000000002040025C5000000020000757690 -+:100390000000000200065000000000020000900073 -+:1003A0000000000200041000000000020C00350EE6 -+:1003B0000000000200049000000000020005100090 -+:1003C0000000000201E785F80000000200200000A4 -+:1003D0000000000C0060007E000000020000756359 -+:1003E00000000021006075F0000000042000707320 -+:1003F000000000040000507300000002000380E6CB -+:1004000000000002040025C500000002000075760F -+:100410000000000200007577000000020000750E69 -+:10042000000000020000750F0000000200A0500054 -+:100430000000000C0060008300000021006075F0E7 -+:1004400000000002000075F80000000400000083B6 -+:1004500000000002000A750E00000002000380E6A2 -+:1004600000000002040025C5000000020020750FF6 -+:1004700000000004006000860000000200007570AB -+:100480000000000200007571000000060000757297 -+:1004900000000002000380E600000002040025C501 -+:1004A00000000002000050000000000200A0500008 -+:1004B0000000000200007568000000020006100045 -+:1004C0000000000C00000095000000020005800004 -+:1004D000000000020C60756200000004000000973C -+:1004E00000000002000380E600000002040025C5B1 -+:1004F000000000040060009600000000400070E56D -+:1005000000000002000380E600000002040025C590 -+:1005100000000002000380E50000001C000000A8AD -+:1005200000000018000650AA00000002040025BBCD -+:1005300000000018000610AB00000000040075BCAD -+:1005400000000002000075BB00000000000075BC48 -+:100550000000000600090000000000020009000081 -+:1005600000000006000D800200000002000078324A -+:10057000000000020000500000000002000380E7BD -+:100580000000000204002C97000000020000782008 -+:100590000000000200007821000000000000780048 -+:1005A000000000020120000000000002200770008F -+:1005B0000000000201200000000000022000700086 -+:1005C0000000000200061000000000020120751B60 -+:1005D000000000028040750A000000028040750B98 -+:1005E000000000020011000000000002000380E58E -+:1005F0000000001C000000C600000018000610AB40 -+:1006000000000002844075BD00000018000610AA1A -+:1006100000000002840075BB00000018000610AB4B -+:1006200000000002844075BC00000004000000C906 -+:1006300000000002804075BD00000002800075BB14 -+:1006400000000002804075BC000000020010800025 -+:1006500000000002014000000000000C006000CD1E -+:100660000000002020C0700000000012000000CF39 -+:100670000000000600800000000000060080751DDC -+:100680000000000000000000000000020000775C95 -+:100690000000000200A050000000000200661000F0 -+:1006A000000000200460275D000000000000400002 -+:1006B0000000000201E0083000000000210070008E -+:1006C000000000006464614D00000000696874204F -+:1006D00000000000000000730000000000000000A7 -+:1006E000000000020000500000000002000380D063 -+:1006F00000000002040025E000000000000075E199 -+:10070000000000000000000100000002000380E083 -+:1007100000000002040023940000000000005000CC -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000080000000000000004AD -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/R200_cp.bin.ihex b/firmware/radeon/R200_cp.bin.ihex -new file mode 100644 -index 0000000..3a0bd73 ---- /dev/null -+++ b/firmware/radeon/R200_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:1000000000000000210070000000000020007000CF -+:1000100000000004000000BF00000004000000C356 -+:10002000000000007A685E5D000000005D5D55889C -+:100030000000000068659197000000005DA19F78B6 -+:10004000000000005D5D5D5D000000005DEE5D5044 -+:1000500000000000F2ACACAC00000000E75DF9E984 -+:1000600000000000B1DD0E1100000000E2AFAFAFF4 -+:1000700000000016000F000000000000452F232D97 -+:10008000000000040000001300000016000F000034 -+:1000900000000000452F272D00000016000F000172 -+:1000A000000000003E4D4A3700000002000077EFDC -+:1000B00000000002000610000000001A00000020EE -+:1000C0000000001E000040000000000200061000BA -+:1000D0000000001A000000200000001E0000400088 -+:1000E00000000002000610000000001A00000020BE -+:1000F0000000001E00004000000000040000001688 -+:10010000000000020003802A00000002040067E0F3 -+:10011000000000040000001600000002000077E06C -+:10012000000000020006500000000002000037E15D -+:1001300000000006040067E100000002000077E014 -+:1001400000000002000077E100000006000077E1F7 -+:1001500000000000FFFFFFFF000000001000000093 -+:100160000000000007F007F0000000020003802AF2 -+:1001700000000006040067E0000000020003802C7D -+:100180000000000204002741000000020400274193 -+:100190000000000204002743000000020000767502 -+:1001A0000000000200007676000000020000767772 -+:1001B0000000000600007678000000020003802C9A -+:1001C0000000000204002741000000020400274153 -+:1001D00000000002040027430000000200007676C1 -+:1001E000000000020000767700000006000076782C -+:1001F000000000020003802B0000000204002676AD -+:100200000000000200007677000000020003802C4E -+:100210000000000204002741000000020400274300 -+:100220000000000600007678000000020003802C29 -+:1002300000000002040027410000000204002741E2 -+:10024000000000020400274300000006000076784A -+:10025000000000180000002F000000180000002F10 -+:100260000000000600000000000000180000003739 -+:100270000000001800000037000000060000000029 -+:100280000000000201605000000000020006500063 -+:1002900000000002000980000000000200061000BB -+:1002A0000000000464C06051000000160008000057 -+:1002B0000000000000000000000000020400251DF6 -+:1002C0000000000200007580000000020006758139 -+:1002D0000000000204002580000000020006758175 -+:1002E000000000040000005A000000000000500060 -+:1002F0000000000200061000000000020000750E61 -+:1003000000000002000190000000001400011064D1 -+:100310000000001200000064000000020400250F2D -+:10032000000000040000505E00000002000075653F -+:100330000000000200007566000000040000006577 -+:100340000000000201E655B4000000024401B0F0D4 -+:100350000000000201C110F0000000182666707154 -+:1003600000000002040C2565000000180000007168 -+:100370000000000204002564000000020000756611 -+:100380000000000400000068000000080040107435 -+:10039000000000020010100000000002000D80FFAD -+:1003A000000000080080007700000002000F9000AD -+:1003B00000000002000E00FF000000060000000028 -+:1003C0000000001800000094000000040000006815 -+:1003D00000000002000075760000000200065000D8 -+:1003E0000000000200009000000000020004100065 -+:1003F000000000020C00350E000000020004900016 -+:1004000000000002000510000000000201E785F86E -+:1004100000000002002000000000000C00600087C7 -+:10042000000000020000756300000021006075F00C -+:10043000000000042000707C000000040000507CDC -+:1004400000000002000075760000000200007577D1 -+:10045000000000020000750E000000020000750F91 -+:100460000000000200A050000000000C0060008AA4 -+:1004700000000021006075F000000002000075F827 -+:10048000000000040000008A00000002000A750E4F -+:10049000000000020020750F000000040060008DC5 -+:1004A000000000020000757000000002000075717D -+:1004B00000000006000075720000000200005000FD -+:1004C0000000000200A0500000000002000075685B -+:1004D00000000002000610000000000C0000009860 -+:1004E0000000000200058000000000020C60756240 -+:1004F000000000040000009A000000040060009961 -+:1005000000000000400070F100000002000380F1D4 -+:100510000000001C000000A700000018000650A901 -+:1005200000000002040025BB00000018000610AA0D -+:1005300000000000040075BC00000002000075BB54 -+:1005400000000000000075BC00000006000900006B -+:10055000000000020009000000000006000D8002FB -+:10056000000000020000500000000002000078219E -+:100570000000000000007800000000020000782168 -+:10058000000000000000780000000002016650003A -+:1005900000000002000A000000000002000671CC0A -+:1005A000000000020286F1CD00000010000000B73C -+:1005B00000000000210070000000001C000000BED0 -+:1005C000000000020006500000000002000A0000C7 -+:1005D000000000020006100000000002000B0000F6 -+:1005E000000000023806700000000004000A00BA93 -+:1005F0000000000020007000000000020120000048 -+:10060000000000022007700000000002012000002E -+:100610000000000020007000000000020006100032 -+:10062000000000020120751B000000028040750AD6 -+:10063000000000028040750B000000020011000065 -+:1006400000000002000380F10000001C000000D147 -+:1006500000000018000610AA00000002844075BDCA -+:1006600000000018000610A900000002840075BBFD -+:1006700000000018000610AA00000002844075BCAB -+:1006800000000004000000D400000002804075BD9E -+:1006900000000002800075BB00000002804075BCB5 -+:1006A0000000000200108000000000020140000075 -+:1006B0000000000C006000D80000002020C0700086 -+:1006C00000000012000000DA0000000600800000B8 -+:1006D000000000060080751D00000002000025BB20 -+:1006E00000000004000040D4000000020000775C1D -+:1006F0000000000200A05000000000020066100090 -+:10070000000000200460275D0000000000004000A1 -+:1007100000000002000079990000000200A05000D3 -+:100720000000000200661000000000200460299B09 -+:1007300000000000000040000000000201E008305E -+:1007400000000000210070000000000200005000C6 -+:10075000000000020003805600000002040025E0B3 -+:1007600000000000000075E1000000000000000132 -+:1007700000000002000380ED0000000004007394FC -+:100780000000000000000000000000000000000069 -+:1007900000000002000078C400000002000078C5DC -+:1007A00000000002000078C600000002000079246A -+:1007B00000000002000079250000000200007926F8 -+:1007C00000000004000000F2000000020000792494 -+:1007D00000000002000079250000000200007926D8 -+:1007E00000000004000000F900000000000000000C -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/R300_cp.bin.ihex b/firmware/radeon/R300_cp.bin.ihex -new file mode 100644 -index 0000000..d307d56 ---- /dev/null -+++ b/firmware/radeon/R300_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:10000000000000004200E000000000004000E000AE -+:1000100000000008000000AE00000008000000B270 -+:100020000000000067554B4A000000004A4A447532 -+:100030000000000055527D83000000004A8C8B6553 -+:10004000000000004AEF4AF6000000004AE14A4A78 -+:1000500000000000E497979700000000DB4AEBDD0A -+:10006000000000009CCC4A4A00000000D1989898FB -+:10007000000000004A0F9AD600000004000CA00007 -+:1000800000000038000D0012000000040000E8B479 -+:1000900000000038000D0014000000040000E8B665 -+:1000A00000000038000D0016000000040000E854B5 -+:1000B00000000038000D0018000000040000E855A2 -+:1000C00000000038000D001A000000040000E8568F -+:1000D00000000038000D001C000000040000E8577C -+:1000E00000000038000D001E000000040000E8249D -+:1000F00000000038000D0020000000040000E8258A -+:1001000000000038000D0022000000040000E8306C -+:1001100000000038000D0024000000040000F0C0C2 -+:1001200000000038000D0026000000040000F0C1AF -+:1001300000000038000D0028000000040000F0411D -+:1001400000000038000D002A000000040000F184C7 -+:1001500000000038000D002C000000040000F185B4 -+:1001600000000038000D002E000000040000F186A1 -+:1001700000000038000D0030000000040000F1878E -+:1001800000000038000D0032000000040000F18083 -+:1001900000000038000D0034000000040000F3935C -+:1001A00000000038000D0036000000040000F38A53 -+:1001B00000000038000D0038000000040000F38E3D -+:1001C000000000040000E821000000040140A0003D -+:1001D00000000018000000430000000400CCE8000C -+:1001E00000000004001B000100000004080048009B -+:1001F00000000004001B000100000004080048008B -+:1002000000000004001B000100000004080048007A -+:10021000000000080000003A000000000000A000FC -+:10022000000000042000451D000000040000E580DF -+:1002300000000004000CE581000000040800458077 -+:1002400000000004000CE5810000000800000047E9 -+:10025000000000000000A00000000004000C2000CE -+:10026000000000040000E50E000000040003200070 -+:10027000000000280002205100000024000000516E -+:10028000000000040800450F000000080000A04B1B -+:10029000000000040000E565000000040000E566C1 -+:1002A00000000008000000520000000403CCA5B4C8 -+:1002B00000000004054320000000000400022000AC -+:1002C000000000304CCCE05E0000000408274565CB -+:1002D000000000300000005E0000000408004564DB -+:1002E000000000040000E566000000080000005562 -+:1002F00000000010008020610000000400202000A9 -+:1003000000000004001B00FF00000010010000645A -+:1003100000000004001F200000000004001C00FF7B -+:100320000000000C00000000000000300000008011 -+:100330000000000800000055000000040000E57601 -+:1003400000000004000CA0000000000400012000D8 -+:100350000000000400082000000000041800650EE2 -+:10036000000000040009200000000004000A200032 -+:1003700000000004000F0000000000040040000026 -+:100380000000001800000074000000040000E56395 -+:10039000000000C200C0E5F900000008000000698C -+:1003A000000000080000A069000000040000E576DD -+:1003B000000000040000E577000000040000E50EE6 -+:1003C000000000040000E50F000000040140A00050 -+:1003D0000000001800000077000000C200C0E5F92E -+:1003E0000000000800000077000000040014E50E83 -+:1003F000000000040040E50F0000000800C0007A83 -+:10040000000000040000E570000000040000E57139 -+:100410000000000C0000E572000000040000A000D5 -+:10042000000000040140A000000000040000E56896 -+:1004300000000004000C20000000001800000084F0 -+:1004400000000004000B00000000000418C0E5627A -+:1004500000000008000000860000000800C00085C1 -+:1004600000000004000700E30000003800000092D4 -+:1004700000000030000CA09400000004080045BB00 -+:1004800000000030000C2095000000000800E5BCD2 -+:10049000000000040000E5BB000000000000E5BC17 -+:1004A0000000000C00120000000000040012000018 -+:1004B0000000000C001B0002000000040000A0006F -+:1004C000000000040000E821000000000000E80037 -+:1004D000000000040000E821000000000000E82EF9 -+:1004E0000000000402CCA000000000040014000082 -+:1004F00000000004000CE1CC00000004050DE1CD7B -+:10050000000000040040000000000018000000A4EB -+:100510000000000400C0A00000000008000000A1CE -+:1005200000000020000000A6000000004200E000E3 -+:1005300000000038000000AD00000004000CA00026 -+:10054000000000040014000000000004000C200063 -+:10055000000000040016000000000004700CE00021 -+:1005600000000008001400A9000000004000E000A6 -+:10057000000000040240000000000004400EE00003 -+:100580000000000402400000000000004000E00005 -+:1005900000000004000C2000000000040240E51BE5 -+:1005A000000000050080E50A000000050080E50B62 -+:1005B000000000040022000000000004000700E327 -+:1005C00000000038000000C000000030000C209542 -+:1005D000000000050880E5BD00000030000C2094FC -+:1005E000000000050800E5BB00000030000C20956D -+:1005F000000000050880E5BC00000008000000C302 -+:10060000000000050080E5BD000000050000E5BB1E -+:10061000000000050080E5BC00000004002100008F -+:1006200000000004028000000000001800C000C7A5 -+:10063000000000404180E00000000024000000C9EC -+:100640000000000C010000000000000C0100E51D8E -+:1006500000000004000045BB00000008000080C34B -+:10066000000000040000F3CE000000040140A000E0 -+:100670000000000400CC20000000004008C053CF60 -+:100680000000000000008000000000040000F3D221 -+:10069000000000040140A0000000000400CC200085 -+:1006A0000000004008C053D300000000000080009C -+:1006B000000000040000F39D000000040140A000C1 -+:1006C0000000000400CC20000000004008C0539E41 -+:1006D00000000000000080000000000403C008309B -+:1006E000000000004200E000000000040000A00044 -+:1006F00000000004200045E0000000000000E5E1EB -+:10070000000000000000000100000004000700E0FD -+:10071000000000000800E39400000000000000005A -+:10072000000000040000E8C4000000040000E8C568 -+:10073000000000040000E8C6000000040000E928F2 -+:10074000000000040000E929000000040000E92A7C -+:1007500000000008000000E4000000040000E92898 -+:10076000000000040000E929000000040000E92A5C -+:1007700000000008000000EB0000000402C02000A0 -+:10078000000000040006000000000034000000F338 -+:1007900000000008000000F00000000400008000DD -+:1007A00000000000C000E0000000000000000000A9 -+:1007B00000000004000C200000000004001D0018D0 -+:1007C00000000004001A000100000034000000FBDB -+:1007D000000000080000004A000000080500A04AD0 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/R420_cp.bin.ihex b/firmware/radeon/R420_cp.bin.ihex -new file mode 100644 -index 0000000..3815891 ---- /dev/null -+++ b/firmware/radeon/R420_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:10000000000000004200E000000000004000E000AE -+:100010000000000800000099000000080000009D9A -+:10002000000000004A554B4A000000004A4A44675D -+:100030000000000055526F75000000004A7E7D658B -+:1000400000000000D9D3DFF6000000004AC54A4A8C -+:1000500000000000C882828200000000BF4ACFC1B9 -+:100060000000000087B04A4A00000000B583838387 -+:10007000000000004A0F85BA00000004000CA00038 -+:1000800000000038000D0012000000040000E8B479 -+:1000900000000038000D0014000000040000E8B665 -+:1000A00000000038000D0016000000040000E854B5 -+:1000B00000000038000D0018000000040000E855A2 -+:1000C00000000038000D001A000000040000E8568F -+:1000D00000000038000D001C000000040000E8577C -+:1000E00000000038000D001E000000040000E8249D -+:1000F00000000038000D0020000000040000E8258A -+:1001000000000038000D0022000000040000E8306C -+:1001100000000038000D0024000000040000F0C0C2 -+:1001200000000038000D0026000000040000F0C1AF -+:1001300000000038000D0028000000040000F0411D -+:1001400000000038000D002A000000040000F184C7 -+:1001500000000038000D002C000000040000F185B4 -+:1001600000000038000D002E000000040000F186A1 -+:1001700000000038000D0030000000040000F1878E -+:1001800000000038000D0032000000040000F18083 -+:1001900000000038000D0034000000040000F3935C -+:1001A00000000038000D0036000000040000F38A53 -+:1001B00000000038000D0038000000040000F38E3D -+:1001C000000000040000E821000000040140A0003D -+:1001D00000000018000000430000000400CCE8000C -+:1001E00000000004001B000100000004080048009B -+:1001F00000000004001B000100000004080048008B -+:1002000000000004001B000100000004080048007A -+:10021000000000080000003A000000000000A000FC -+:10022000000000042000451D000000040000E580DF -+:1002300000000004000CE581000000040800458077 -+:1002400000000004000CE5810000000800000047E9 -+:10025000000000000000A00000000004000C2000CE -+:10026000000000040000E50E000000040003200070 -+:10027000000000280002205100000024000000516E -+:10028000000000040800450F000000080000A04B1B -+:10029000000000040000E565000000040000E566C1 -+:1002A00000000008000000520000000403CCA5B4C8 -+:1002B00000000004054320000000000400022000AC -+:1002C000000000304CCCE05E0000000408274565CB -+:1002D000000000300000005E0000000408004564DB -+:1002E000000000040000E566000000080000005562 -+:1002F00000000010008020610000000400202000A9 -+:1003000000000004001B00FF00000010010000645A -+:1003100000000004001F200000000004001C00FF7B -+:100320000000000C0000000000000030000000721F -+:100330000000000800000055000000040000E57601 -+:10034000000000040000E577000000040000E50E56 -+:10035000000000040000E50F000000040140A000C0 -+:100360000000001800000069000000C200C0E5F9AC -+:100370000000000800000069000000040014E50E01 -+:10038000000000040040E50F0000000800C0006C01 -+:10039000000000040000E570000000040000E571AA -+:1003A0000000000C0000E572000000040000A00046 -+:1003B000000000040140A000000000040000E56807 -+:1003C00000000004000C200000000018000000766F -+:1003D00000000004000B00000000000418C0E562EB -+:1003E00000000008000000780000000800C000774E -+:1003F00000000004000700C7000000380000008073 -+:10040000000000040000E5BB000000000000E5BCA7 -+:10041000000000040000A000000000040000E8212B -+:10042000000000000000E800000000040000E821D7 -+:10043000000000000000E82E0000000402CCA00034 -+:10044000000000040014000000000004000CE1CCD7 -+:1004500000000004050DE1CD000000040040000094 -+:10046000000000180000008F0000000400C0A00081 -+:10047000000000080000008C000000200000009137 -+:10048000000000004200E00000000038000000987A -+:1004900000000004000CA000000000040014000094 -+:1004A00000000004000C2000000000040016000002 -+:1004B00000000004700CE00000000008001400942C -+:1004C000000000004000E0000000000402400000C6 -+:1004D00000000004400EE0000000000402400000A4 -+:1004E000000000004000E00000000004000C2000BC -+:1004F000000000040240E51B000000050080E50A42 -+:10050000000000050080E50B000000040022000050 -+:1005100000000004000700C700000038000000A42D -+:10052000000000050080E5BD000000050000E5BBFF -+:10053000000000050080E5BC000000040021000070 -+:1005400000000004028000000000001800C000ABA2 -+:10055000000000404180E00000000024000000ADE9 -+:100560000000000C010000000000000C0100E51D6F -+:1005700000000004000045BB00000008000080A748 -+:10058000000000040000F3CE000000040140A000C1 -+:100590000000000400CC20000000004008C053CF41 -+:1005A0000000000000008000000000040000F3D202 -+:1005B000000000040140A0000000000400CC200066 -+:1005C0000000004008C053D300000000000080007D -+:1005D000000000040000F39D000000040140A000A2 -+:1005E0000000000400CC20000000004008C0539E22 -+:1005F00000000000000080000000000403C008307C -+:10060000000000004200E000000000040000A00024 -+:1006100000000004200045E0000000000000E5E1CB -+:10062000000000000000000100000004000700C4FA -+:10063000000000000800E39400000000000000003B -+:10064000000000040000E8C4000000040000E8C549 -+:10065000000000040000E8C6000000040000E928D3 -+:10066000000000040000E929000000040000E92A5D -+:1006700000000008000000C8000000040000E92895 -+:10068000000000040000E929000000040000E92A3D -+:1006900000000008000000CF0000000402C020009D -+:1006A000000000040006000000000034000000D735 -+:1006B00000000008000000D40000000400008000DA -+:1006C00000000000C000E000000000040000E1CCD9 -+:1006D000000000040500E1CD00000004000CA000B3 -+:1006E00000000034000000DE00000008000000DA16 -+:1006F000000000000000A000000000040019E1CC90 -+:1007000000000004001B0001000000040500A00020 -+:1007100000000004080041CD00000004000CA0000F -+:1007200000000034000000FB000000080000004A48 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B00000000004000C200000000004001D0018D0 -+:1007C00000000004001A000100000034000000FBDB -+:1007D000000000080000004A000000080500A04AD0 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/R520_cp.bin.ihex b/firmware/radeon/R520_cp.bin.ihex -new file mode 100644 -index 0000000..372ff82 ---- /dev/null -+++ b/firmware/radeon/R520_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:10000000000000004200E000000000004000E000AE -+:100010000000000800000099000000080000009D9A -+:10002000000000004A554B4A000000004A4A44675D -+:100030000000000055526F75000000004A7E7D658B -+:1000400000000000E0DAE6F6000000004AC54A4A77 -+:1000500000000000C882828200000000BF4ACFC1B9 -+:100060000000000087B04AD500000000B5838383FC -+:10007000000000004A0F85BA00000004000CA00038 -+:1000800000000038000D0012000000040000E8B479 -+:1000900000000038000D0014000000040000E8B665 -+:1000A00000000038000D0016000000040000E854B5 -+:1000B00000000038000D0018000000040000E855A2 -+:1000C00000000038000D001A000000040000E8568F -+:1000D00000000038000D001C000000040000E8577C -+:1000E00000000038000D001E000000040000E8249D -+:1000F00000000038000D0020000000040000E8258A -+:1001000000000038000D0022000000040000E8306C -+:1001100000000038000D0024000000040000F0C0C2 -+:1001200000000038000D0026000000040000F0C1AF -+:1001300000000038000D0028000000040000E0006E -+:1001400000000038000D002A000000040000E0005C -+:1001500000000038000D002C000000040000E0004A -+:1001600000000038000D002E000000040000E00038 -+:1001700000000038000D0030000000040000E00026 -+:1001800000000038000D0032000000040000F18083 -+:1001900000000038000D0034000000040000F3935C -+:1001A00000000038000D0036000000040000F38A53 -+:1001B00000000038000D0038000000040000F38E3D -+:1001C000000000040000E821000000040140A0003D -+:1001D00000000018000000430000000400CCE8000C -+:1001E00000000004001B000100000004080048009B -+:1001F00000000004001B000100000004080048008B -+:1002000000000004001B000100000004080048007A -+:10021000000000080000003A000000000000A000FC -+:10022000000000042000451D000000040000E580DF -+:1002300000000004000CE581000000040800458077 -+:1002400000000004000CE5810000000800000047E9 -+:10025000000000000000A00000000004000C2000CE -+:10026000000000040000E50E000000040003200070 -+:10027000000000280002205100000024000000516E -+:10028000000000040800450F000000080000A04B1B -+:10029000000000040000E565000000040000E566C1 -+:1002A00000000008000000520000000403CCA5B4C8 -+:1002B00000000004054320000000000400022000AC -+:1002C000000000304CCCE05E0000000408274565CB -+:1002D000000000300000005E0000000408004564DB -+:1002E000000000040000E566000000080000005562 -+:1002F00000000010008020610000000400202000A9 -+:1003000000000004001B00FF00000010010000645A -+:1003100000000004001F200000000004001C00FF7B -+:100320000000000C0000000000000030000000721F -+:100330000000000800000055000000040000E57601 -+:10034000000000040000E577000000040000E50E56 -+:10035000000000040000E50F000000040140A000C0 -+:100360000000001800000069000000C200C0E5F9AC -+:100370000000000800000069000000040014E50E01 -+:10038000000000040040E50F0000000800C0006C01 -+:10039000000000040000E570000000040000E571AA -+:1003A0000000000C0000E572000000040000A00046 -+:1003B000000000040140A000000000040000E56807 -+:1003C00000000004000C200000000018000000766F -+:1003D00000000004000B00000000000418C0E562EB -+:1003E00000000008000000780000000800C000774E -+:1003F00000000004000700C7000000380000008073 -+:10040000000000040000E5BB000000000000E5BCA7 -+:10041000000000040000A000000000040000E8212B -+:10042000000000000000E800000000040000E821D7 -+:10043000000000000000E82E0000000402CCA00034 -+:10044000000000040014000000000004000CE1CCD7 -+:1004500000000004050DE1CD000000040040000094 -+:10046000000000180000008F0000000400C0A00081 -+:10047000000000080000008C000000200000009137 -+:10048000000000004200E00000000038000000987A -+:1004900000000004000CA000000000040014000094 -+:1004A00000000004000C2000000000040016000002 -+:1004B00000000004700CE00000000008001400942C -+:1004C000000000004000E0000000000402400000C6 -+:1004D00000000004400EE0000000000402400000A4 -+:1004E000000000004000E00000000004000C2000BC -+:1004F000000000040240E51B000000050080E50A42 -+:10050000000000050080E50B000000040022000050 -+:1005100000000004000700C700000038000000A42D -+:10052000000000050080E5BD000000050000E5BBFF -+:10053000000000050080E5BC000000040021000070 -+:1005400000000004028000000000001800C000ABA2 -+:10055000000000404180E00000000024000000ADE9 -+:100560000000000C010000000000000C0100E51D6F -+:1005700000000004000045BB00000008000080A748 -+:10058000000000040000F3CE000000040140A000C1 -+:100590000000000400CC20000000004008C053CF41 -+:1005A0000000000000008000000000040000F3D202 -+:1005B000000000040140A0000000000400CC200066 -+:1005C0000000004008C053D300000000000080007D -+:1005D000000000040000F39D000000040140A000A2 -+:1005E0000000000400CC20000000004008C0539E22 -+:1005F00000000000000080000000000403C008307C -+:10060000000000004200E000000000040000A00024 -+:1006100000000004200045E0000000000000E5E1CB -+:10062000000000000000000100000004000700C4FA -+:10063000000000000800E39400000000000000003B -+:10064000000000040000E8C4000000040000E8C549 -+:10065000000000040000E8C6000000040000E928D3 -+:10066000000000040000E929000000040000E92A5D -+:1006700000000008000000C8000000040000E92895 -+:10068000000000040000E929000000040000E92A3D -+:1006900000000008000000CF00000000DEADBEEF4B -+:1006A000000000000000011600000004000700D355 -+:1006B00000000004080050E700000004000700D418 -+:1006C000000000040800401C000000000000E01DC5 -+:1006D0000000000402C0200000000004000600002A -+:1006E00000000034000000DE00000008000000DB15 -+:1006F000000000040000800000000000C000E000D6 -+:10070000000000040000E1CC000000040500E1CD81 -+:1007100000000004000CA00000000034000000E510 -+:1007200000000008000000E1000000000000A00040 -+:10073000000000040019E1CC00000004001B0001CF -+:10074000000000040500A00000000004080041CDE6 -+:1007500000000004000CA00000000034000000FBBA -+:10076000000000080000004A000000000000000037 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B00000000004000C200000000004001D0018D0 -+:1007C00000000004001A000100000034000000FBDB -+:1007D000000000080000004A000000080500A04AD0 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/R600_me.bin.ihex b/firmware/radeon/R600_me.bin.ihex -new file mode 100644 -index 0000000..30d4c14 ---- /dev/null -+++ b/firmware/radeon/R600_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A0000060441100000614000000000060000021 -+:1000B000000005B20000000000600000000005C55F -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E0000000000000000020002036250000000075 -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000003100204A2D82 -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000002100203625C1 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001D00200E2D54 -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001D12 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000300020362407 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:1003800000000000000000100020362300000000E4 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E230000000000000011C7 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000003000204A2D0000000046 -+:1003F0000000000000204811000000000000003252 -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A0000000000000204804000000000000002DB2 -+:1005B0000020162D0000000000000000002F00A306 -+:1005C00000000000000000000CC0000000000080DF -+:1005D0000000002E0020162D00000000000000008A -+:1005E000002F00A400000000000000000CC000006C -+:1005F00000000081000000000040000000000087B3 -+:100600000000002D00203623000000000000002E16 -+:1006100000203624000000000000001D00201E2DD8 -+:10062000000000000000000200210227000000007E -+:100630000000000014E0000000000087000000003F -+:1006400000600000000005ED0000000000600000F8 -+:10065000000005E10000000200210E220000000061 -+:100660000000000014C000000000008A0000001814 -+:10067000C040362000000090000000002EE0000086 -+:100680000000008E000000002CE000000000008D43 -+:100690000000000200400E2D0000008F000000034B -+:1006A00000400E2D0000008F0000000C00200E2DD9 -+:1006B00000000000000000180020362300000000A9 -+:1006C0000000000300210E220000000000000000D6 -+:1006D00014C00000000000950000A00C0020441190 -+:1006E0000000000000000000C020480000000000E2 -+:1006F00000000000C04048000000009D0000A00C69 -+:1007000000204411000000000000000000204811FB -+:1007100000000000000000002EE000000000009B30 -+:10072000000000002CE000000000009A0000000221 -+:1007300000400E2D0000009C0000000300400E2D24 -+:100740000000009C0000000C00200E2D00000000A6 -+:10075000000000000020480300000000000000002E -+:10076000003A0C0200000000003F000000280E23A9 -+:10077000000000000000001000210E230000000017 -+:100780000000001300203623000000000000001EBF -+:100790000021022B000000000000000014C0000037 -+:1007A000000000A40000001CC02036200000000053 -+:1007B0000000001F0021022B0000000000000000CC -+:1007C00014C00000000000A70000001BC02036205D -+:1007D000000000000000000800210E2B00000000B7 -+:1007E0000000007F00280E23000000000000000031 -+:1007F000002F022300000000000000000CE00000B9 -+:10080000000000DB000000002700000000000000E6 -+:1008100000000000006000000000028C8100000069 -+:1008200000204411000000000000000600204811D4 -+:10083000000000000000000C00221E30000000003C -+:100840009980000000204411000000000000000416 -+:100850000020122D000000000000000800221224D9 -+:10086000000000000000001000201811000000002F -+:100870000000000000291CE400000000000000004F -+:1008800000604807000001289B0000000020441180 -+:1008900000000000000000000020480200000000EE -+:1008A0009C00000000204411000000000000000037 -+:1008B0000033146F000000000000000100333E23ED -+:1008C0000000000000000000D90048000000000007 -+:1008D0000000000000203C05000000008100000036 -+:1008E00000204411000000000000000E002048110C -+:1008F00000000000000000000020101000000000B8 -+:100900000000E00700204411000000000000000F7C -+:100910000021022B000000000000000014C00000B5 -+:10092000000000C500F8FF0800204811000000008A -+:100930009800000000404811000000D6000000F0C0 -+:1009400000280E2200000000000000A0002F02235B -+:1009500000000000000000000CC00000000000D4F7 -+:100960000000001300200E2D000000000000000118 -+:10097000002F022300000000000000000CE0000037 -+:10098000000000CF00000002002F02230000000042 -+:10099000000000000CE00000000000CE00003F005E -+:1009A00000400C11000000D000001F0000400C119E -+:1009B000000000D000000F0000200C11000000001B -+:1009C0000038000900294A23000000003F00000011 -+:1009D00000280E2B000000000000000200220E2361 -+:1009E000000000000000000700494A23000000D674 -+:1009F00000380F09002048110000000068000007BF -+:100A000000204811000000000000000800214A27D3 -+:100A1000000000000000000000204811000000005D -+:100A2000060A020000294A2400000000000000001D -+:100A300000204811000000000000000000204811C4 -+:100A4000000000000000A20200204411000000008D -+:100A500000FF000000284A220000000000000030D3 -+:100A600000200E2D000000000000002E0020122D9E -+:100A70000000000000000000002F008300000000C4 -+:100A8000000000000CE00000000000E30000000097 -+:100A900000600000000005E70000000000400000CA -+:100AA000000000E40000000000600000000005EA13 -+:100AB000000000070020222D0000000000000005BB -+:100AC00000220E22000000000010000000280E236B -+:100AD0000000000000000000002920680000000065 -+:100AE00000000000003A0C0200000000000000EFCF -+:100AF00000280E23000000000000000000292068EC -+:100B0000000000000000001D00200E2D000000006D -+:100B1000000000030021022300000000000000008C -+:100B200014E00000000000F10000000B002102288A -+:100B3000000000000000000014C00000000000F1F0 -+:100B40000000040000292228000000000000001A14 -+:100B500000203628000000000000001C00210E22AA -+:100B6000000000000000000014C00000000000F6BB -+:100B70000000A30C00204411000000000000000051 -+:100B800000204811000000000000001E00210E227D -+:100B9000000000000000000014C00000000001047C -+:100BA0000000A30F0020441100000000000000130B -+:100BB00000200E2D0000000000000001002F022385 -+:100BC00000000000000000000CC00000000000FD5C -+:100BD000FFFFFFFF00404811000001040000000279 -+:100BE000002F022300000000000000000CC00000E5 -+:100BF000000001000000FFFF004048110000010458 -+:100C000000000004002F022300000000000000008C -+:100C10000CC0000000000103000000FF004048116C -+:100C20000000010400000001002048110000000045 -+:100C30000002C40000204411000000000000001F5A -+:100C400000210E22000000000000000014C000007F -+:100C50000000010B0000001040210E2000000000E9 -+:100C600000000019002036230000000000000018DA -+:100C700040224A200000000000000010C0424A202C -+:100C80000000010D0000000000200C110000000019 -+:100C900000000019002036230000000000000000C2 -+:100CA0000020481100000000000000000020481152 -+:100CB000000000000000000A0020101100000000E9 -+:100CC00000000000002F02240000000000000000CF -+:100CD0000CE000000000011400000000002048119A -+:100CE0000000000000000001005312240000011069 -+:100CF000FFBFFFFF00283A2E000000000000001B8D -+:100D000000210222000000000000000014C00000CA -+:100D100000000127810000000020441100000000B5 -+:100D20000000000D00204811000000000000001825 -+:100D300000220E3000000000FC00000000280E23FE -+:100D400000000000810000000020441100000000AD -+:100D50000000000E0020481100000000000000000C -+:100D600000201010000000000000E00E00204411E0 -+:100D70000000000007F8FF080020481100000000F4 -+:100D80000000000000294A230000000000000024A9 -+:100D900000201E2D000000000000000800214A274E -+:100DA00000000000000000000020481100000000CA -+:100DB000060A020000294A2400000000000000008A -+:100DC0000020481100000000000000000020481131 -+:100DD0000000000000000000008000000000000093 -+:100DE000810000000020441100000000000000010C -+:100DF00000204811000000000000217C0020441168 -+:100E000000000000008000000020481100000000E9 -+:100E1000000000000020480600000000000000085C -+:100E200000214A2700000000000000001700000019 -+:100E3000000000000004217F00604411000006143F -+:100E40000000001F00210230000000000000000030 -+:100E500014C00000000006130000000400404C1104 -+:100E60000000012E00000000006000000000000BE8 -+:100E70000000000000600411000002FE00000000FD -+:100E800000200411000000000000000000600811B4 -+:100E90000000019F00000000006000000000015100 -+:100EA0000000FFFF40280E2000000000000000109E -+:100EB000C0211220000000000000FFFF4028062093 -+:100EC0000000000000000010C0210A200000000007 -+:100ED0000000000000341461000000000000000069 -+:100EE00000741882000002A40001A1FD00604411FA -+:100EF000000002C900003FFF002F022F0000000089 -+:100F0000000000000CC000000000013800000000DC -+:100F1000C04004000000000100000000006000006C -+:100F20000000000B0000000000600411000002FE41 -+:100F3000000000000020041100000000000000007C -+:100F4000006008110000019F00003FFF002F022FEA -+:100F500000000000000000000CE0000000000000A5 -+:100F600000000000006000000000015100000010BF -+:100F700040210E20000000000000FFFFC0281220CA -+:100F800000000000000000104021162000000000BA -+:100F90000000FFFFC0681A20000002A40001A1FDAC -+:100FA00000604411000002C900003FFF002F022F23 -+:100FB00000000000000000000CC00000000001491B -+:100FC00000000000C0400400000000010000225C9E -+:100FD00000204411000000000000000100300A2F32 -+:100FE000000000000000000100210A2200000000B3 -+:100FF0000000000300384A220000000000002256D2 -+:1010000000204411000000000000001A00204811D8 -+:10101000000000000000A1FC0020441100000000BE -+:1010200000000001008048110000000000000000E6 -+:10103000006000000000000B0000000000600000E5 -+:101040000000017C00000000006000000000018D35 -+:1010500000003FFF002F022F0000000000000000F2 -+:101060000CE00000000000000000000000202C0840 -+:10107000000000000000000000202411000000001B -+:10108000000000000020281100000000000022568F -+:10109000002044110000000000000016002048114C -+:1010A000000000000000225C00204411000000004D -+:1010B00000000003002048110000000093800000A1 -+:1010C00000204411000000000000000200221E2940 -+:1010D0000000000000000000007048EB00000189E3 -+:1010E0000000000000600000000002A400000001F9 -+:1010F000403306200000000000000000C03024093A -+:101100000000000000003FFF002F022F0000000041 -+:10111000000000000CE000000000000000000000E3 -+:10112000006000000000028C9500000000204411C7 -+:101130000000000000000000002F0221000000005D -+:10114000000000000CE0000000000173000000003F -+:10115000C0204800000000000000000100530621EC -+:101160000000016F92000000002044110000000008 -+:1011700000000000C0604800000001840001A1FDE3 -+:101180000020441100000000000000130020062D84 -+:1011900000000000000000000078042A000002E4C3 -+:1011A00000000000002028090000000000003FFFB0 -+:1011B000002F022F00000000000000000CC0000003 -+:1011C0000000016500000000C040040000000001B4 -+:1011D0000000021000600411000002FE00003FFF4A -+:1011E000002F022F00000000000000000CE00000B3 -+:1011F000000001810000001BC0203620000000001C -+:101200000000001CC0203620000000003F800000CD -+:1012100000200411000000004600000000600811DA -+:101220000000019F0000000000800000000000009E -+:101230000000A1FC002044110000000000003FFF5E -+:10124000002F022F00000000000000000CC0000072 -+:10125000000001880000000100804811000000002B -+:101260000000002100804811000000000000FFFF86 -+:1012700040280E200000000000000010C0211220B5 -+:10128000000000000000FFFF4028162000000000C2 -+:1012900000000010C0811A20000000008100000042 -+:1012A000002044110000000000000006002048114A -+:1012B000000000000000000800221E3000000000B6 -+:1012C0000000003200201A2D000000000000E000A5 -+:1012D0000020441100000000FFFBFF09002048111E -+:1012E00000000000000000110020222D000000007E -+:1012F00000001FFF00294A2800000000000000062F -+:101300000020222D0000000000000000002920E83D -+:10131000000000000000000000204808000000005D -+:10132000000000000020481100000000060A020032 -+:1013300000294A260000000000000000002048119B -+:101340000000000000000000002048110000000024 -+:10135000000001000020181100000000000000083B -+:1013600000621E28000001280000000800822228D8 -+:10137000000000000002C000002044110000000036 -+:101380000000001B00600E2D000001AA0000001CE0 -+:1013900000600E2D000001AA0000C00800204411CA -+:1013A000000000000000001D00200E2D00000000C5 -+:1013B0000000000014C00000000001A600000000B2 -+:1013C000002004110000000000000000002048017F -+:1013D000000000003900000000204811000000005B -+:1013E0000000000000204811000000000000000084 -+:1013F00000804802000000000000002000202E2D88 -+:101400000000000000000000003B0D630000000031 -+:101410000000000800224A23000000000000001025 -+:1014200000224A23000000000000001800224A2386 -+:1014300000000000000000000080480300000000E1 -+:1014400000000000006000000000000B0000100021 -+:1014500000600411000002FE0000000000200411E2 -+:101460000000000000000000006008110000019F63 -+:10147000000000070021062F0000000000000019F6 -+:1014800000200A2D000000000000000100202C11A7 -+:10149000000000000000FFFF4028222000000000A4 -+:1014A0000000000F002622280000000000000010AD -+:1014B00040212620000000000000000F0026262901 -+:1014C00000000000000000000020280200000000D2 -+:1014D0000000225600204411000000000000001B04 -+:1014E000002048110000000000000000002F022131 -+:1014F00000000000000000000CE00000000001CD32 -+:101500000000225C00204411000000000000008167 -+:1015100000204811000000000000A1FC0020441140 -+:101520000000000000000001002048110000000041 -+:101530000000008000201C110000000000000000DE -+:10154000002F022700000000000000000CE0000057 -+:10155000000001C90000000000600000000001D68A -+:101560000000000100531E27000001C5000000011B -+:1015700000202C11000000000000001F00280A229B -+:10158000000000000000001F00282A2A00000000C0 -+:101590000000000100530621000001BE0000225C93 -+:1015A00000204411000000000000000200304A2F1B -+:1015B000000000000000A1FC002044110000000019 -+:1015C00000000001002048110000000000000001A0 -+:1015D00000301E2F0000000000000000002F022736 -+:1015E00000000000000000000CE00000000000000F -+:1015F0000000000000600000000001D600000001B3 -+:1016000000531E27000001D20000FFFF40280E20DB -+:10161000000000000000000F00260E230000000064 -+:1016200000000010C0211220000000000000000F88 -+:101630000026122400000000000000000020141109 -+:10164000000000000000000000601811000002A46B -+:101650000001A1FD00204411000000000000000076 -+:10166000002F022B00000000000000000CE0000032 -+:10167000000001E500000010002216280000000014 -+:10168000FFFF000000281625000000000000FFFFFB -+:1016900000281A290000000000000000002948C5A9 -+:1016A00000000000000000000020480A00000000C8 -+:1016B0000000000000202C110000000000000010BD -+:1016C0000022162300000000FFFF0000002816255E -+:1016D000000000000000FFFF00281A2400000000A6 -+:1016E00000000000002948C50000000000000000C4 -+:1016F00000731503000001F200000000002018052F -+:10170000000000000000000000731524000001F23A -+:1017100000000000002D14C50000000000000000C3 -+:10172000003008A200000000000000000020480275 -+:10173000000000000000000000202802000000005F -+:101740000000000000202003000000000000000056 -+:1017500000802404000000000000000F002102258A -+:10176000000000000000000014C00000000006138C -+:1017700000000000002B1405000000000000000124 -+:10178000009016250000000000000000006000002E -+:101790000000000B0000000000600411000002FEC9 -+:1017A0000000000000200411000000000000000004 -+:1017B000006008110000019F000022560020441123 -+:1017C000000000000000001A00294A22000000006A -+:1017D00000000000C02000000000000000003FFFEB -+:1017E000002F022F00000000000000000CE00000AD -+:1017F0000000000000000000C02004000000000005 -+:101800000000225C002044110000000000000003E2 -+:1018100000384A21000000000000A1FC0020441113 -+:10182000000000000000000100204811000000003E -+:101830000000FFFF40281220000000000000001000 -+:10184000C0211A20000000000000FFFF40280E20E9 -+:101850000000000000000010C02116200000000061 -+:101860000000000000741465000002A40001A1FD46 -+:1018700000604411000002C900000001003306218D -+:101880000000000000000000002F02210000000006 -+:10189000000000000CC000000000020600003FFF36 -+:1018A000002F022F00000000000000000CC000000C -+:1018B000000001FF00000000C04004000000000123 -+:1018C0000000000000600000000005C500000000EE -+:1018D0000040040F00000200000000000060000053 -+:1018E000000005B20000000000600000000005C517 -+:1018F0000000021000600411000002FE0000000061 -+:10190000006000000000018D000000000060000089 -+:10191000000001890000000000600000000002A437 -+:1019200000000000006000000000028C93800000B6 -+:1019300000204411000000000000000000204808C2 -+:10194000000000009500000000204411000000008D -+:1019500000000000002F022F000000000000000027 -+:101960000CE000000000021F00000000C040480022 -+:101970000000021C92000000002044110000000042 -+:1019800000000000C02048000000000000002256B7 -+:101990000020441100000000000000160020481143 -+:1019A000000000000000225C002044110000000044 -+:1019B0000000000300204811000000000000A1FC0E -+:1019C0000020441100000000000000010020481128 -+:1019D000000000000001A1FD0020441100000000F3 -+:1019E0000000000000600411000002E4000000009C -+:1019F000C040040000000001000000000060000082 -+:101A0000000005B20000A00C0020441100000000FE -+:101A100000000000C020480000000000000000009E -+:101A2000C04048000000000000000000006000000E -+:101A30000000000B0000001840210A2000000000F8 -+:101A400000000003002F0222000000000000000040 -+:101A50000AE00000000002350000001A0020222DDC -+:101A600000000000000801010029222800000000F9 -+:101A70000000001A00203628000000000000A30C1F -+:101A8000002044110000000000000000C0204800B9 -+:101A90000000000000000000C0204800000000001E -+:101AA00000000000C04048000000023A00000000B2 -+:101AB000006000000000000B000000100060041136 -+:101AC000000002FE3F800000002004110000000022 -+:101AD00000000000006008110000019F0000225C6F -+:101AE0000020441100000000000000030020481105 -+:101AF000000000000000000000600000000002651F -+:101B00000000001D00201E2D00000000000000014C -+:101B100000211E27000000000000000014E000006B -+:101B2000000002530000001800201E2D00000000DD -+:101B30000000FFFF00281E2700000000000000003A -+:101B400000341C27000000000000000012C000004C -+:101B5000000002480000000000201C1100000000EE -+:101B600000000000002F00E5000000000000000061 -+:101B700008C000000000024B000000000020140715 -+:101B8000000000000000001800201E2D00000000D2 -+:101B90000000001000211E270000000000000000CF -+:101BA00000341C47000000000000000012C00000CC -+:101BB000000002500000000000201C110000000086 -+:101BC00000000000002F00E6000000000000000000 -+:101BD00008C00000000002530000000000201807A9 -+:101BE000000000000000000000600000000002AAE9 -+:101BF00000002256002044110000000000000000F8 -+:101C000000342023000000000000000012C000008B -+:101C10000000025B000000000034204400000000CF -+:101C20000000000012C000000000025A0000001670 -+:101C3000004048110000025F0000001800404811F9 -+:101C40000000025F0000000000342044000000009B -+:101C50000000000012C000000000025E000000173B -+:101C6000004048110000025F0000001900204811E8 -+:101C7000000000000000A1FC002044110000000052 -+:101C80000000000100204811000000000001A1FD3B -+:101C900000604411000002D200003FFF002F022F1D -+:101CA00000000000000000000CC000000000023F27 -+:101CB00000000000C040040000000001000000100F -+:101CC00040210620000000000000FFFFC0280A207D -+:101CD000000000000000001040210E200000000065 -+:101CE0000000FFFFC02812200000000000000010CC -+:101CF00040211620000000000000FFFFC0881A20CD -+:101D000000000000810000000020441100000000DD -+:101D10000000000100204811000000000004200421 -+:101D20000060441100000614000000000060000084 -+:101D3000000005B200000000C06000000000028C3E -+:101D40000000000500200A2D00000000000000082F -+:101D500000220A22000000000000003400201A2D9A -+:101D6000000000000000002400201E2D00000000E4 -+:101D70000000700000281E27000000000000000086 -+:101D800000311CE6000000000000003300201A2D86 -+:101D9000000000000000000C00221A2600000000D5 -+:101DA00000000000002F00E600000000000000001E -+:101DB00006E000000000027B0000000000201C1173 -+:101DC000000000000000000000200C1100000000D6 -+:101DD0000000003400203623000000000000001046 -+:101DE00000201811000000000000000000691CE243 -+:101DF0000000012893800000002044110000000032 -+:101E000000000000002048070000000095000000CE -+:101E1000002044110000000000000000002F022FED -+:101E200000000000000000000CE00000000002863E -+:101E30000000000100333E2F000000000000000001 -+:101E4000D90048000000000092000000002044116A -+:101E50000000000000000000C0204800000000005A -+:101E60000000002400403627000000000000000CA5 -+:101E7000C0220A20000000000000003200203622AC -+:101E80000000000000000031C040362000000000CB -+:101E90000000A2A40020441100000000000000097E -+:101EA0000020481100000000A100000000204411A3 -+:101EB0000000000000000001008048110000000048 -+:101EC0000000002900201E2D00000000000000007E -+:101ED000002C1CE300000000000000290020362731 -+:101EE000000000000000002A00201E2D000000005D -+:101EF00000000000002C1CE4000000000000002A8C -+:101F000000203627000000000000002B00201E2DBE -+:101F10000000000000000000003120A300000000CD -+:101F200000000000002D1D07000000000000002B35 -+:101F300000203627000000000000002C00201E2D8D -+:101F40000000000000000000003120C4000000007C -+:101F500000000000002D1D07000000000000002C04 -+:101F600000803627000000000000002900203623F2 -+:101F7000000000000000002A0020362400000000BD -+:101F80000000000000311CA3000000000000002B36 -+:101F900000203627000000000000000000311CC4B3 -+:101FA000000000000000002C008036270000000028 -+:101FB000000000220020362700000000000000235F -+:101FC00000203628000000000000001D00201E2D0B -+:101FD00000000000000000020021022700000000B5 -+:101FE0000000000014C00000000002C50000000056 -+:101FF00000400000000002C200000022002036273E -+:10200000000000000000002300203628000000002F -+:102010000000001D00201E2D000000000000000236 -+:1020200000210227000000000000000014E0000072 -+:10203000000002C20000000300210227000000008F -+:102040000000000014E00000000002C50000002BAA -+:1020500000201E2D0000000000000000002E00E106 -+:10206000000000000000000002C00000000002C5E7 -+:102070000000002900201E2D0000000000000000CC -+:10208000003120A10000000000000000002E00E848 -+:10209000000000000000000006C00000000002C5B3 -+:1020A0000000002C00201E2D000000000000000099 -+:1020B000002E00E2000000000000000002C000004E -+:1020C000000002C50000002A00201E2D00000000B4 -+:1020D00000000000003120C20000000000000000ED -+:1020E000002E00E8000000000000000006C0000014 -+:1020F000000002C50000000000600000000005EDC7 -+:1021000000000000006000000000029E00000000CF -+:1021100000400000000002C7000000000060000056 -+:102120000000029E0000000000600000000005E4C6 -+:102130000000000000400000000002C70000000096 -+:10214000006000000000029000000000004000005D -+:10215000000002C70000002200201E2D0000000029 -+:10216000000000230080222D00000000000000106D -+:1021700000221E2300000000000000000029488704 -+:10218000000000000000000000311CA3000000005F -+:102190000000001000221E270000000000000000C8 -+:1021A00000294887000000000000001000221E23C4 -+:1021B0000000000000000000003120C4000000000A -+:1021C0000000FFFF0028222800000000000000009F -+:1021D00000894907000000000000001000221E23B3 -+:1021E00000000000000000000029488700000000F7 -+:1021F0000000001000221E2100000000000000006E -+:1022000000294847000000000000000000311CA326 -+:10221000000000000000001000221E270000000047 -+:1022200000000000002948870000000000000000B6 -+:1022300000311CA1000000000000001000221E2739 -+:1022400000000000000000000029484700000000D6 -+:102250000000001000221E2300000000000000000B -+:10226000003120C4000000000000FFFF00282228E9 -+:1022700000000000000000000029490700000000E5 -+:102280000000001000221E210000000000000000DD -+:10229000003120C2000000000000FFFF00282228BB -+:1022A0000000000000000000008949070000000055 -+:1022B0000000001000221E230000000000000000AB -+:1022C00000294887000000000000000100220A21C8 -+:1022D0000000000000000000003308A20000000021 -+:1022E0000000001000221E2200000000000000106C -+:1022F0000021222200000000000000000029490700 -+:10230000000000000000000000311CA300000000DD -+:102310000000001000221E27000000000000000046 -+:1023200000294887000000000000000100220A2167 -+:102330000000000000000000003008A200000000C3 -+:102340000000001000221E2200000000000000100B -+:10235000002122220000000000000000002949079F -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:102390000000000000000000003808C50000000038 -+:1023A00000000000003008410000000000000001B3 -+:1023B00000220A220000000000000000003308A2F2 -+:1023C000000000000000001000221E22000000009B -+:1023D0000000001000212222000000000000000088 -+:1023E00000894907000000000000001D0020222D88 -+:1023F000000000000000000014C000000000030105 -+:10240000FFFFFFEF00280621000000000000001A77 -+:102410000020222D000000000000F8E00020441100 -+:102420000000000000000000002949010000000039 -+:1024300000000000008949010000000000000000C9 -+:10244000002048110000000000000000002048119A -+:1024500000000000060A0200008048110000000091 -+:1024600000000000C02000000000000097000000F5 -+:10247000C02044110000000000000000C0204811EE -+:10248000000000008A00000000204411000000004D -+:102490000000000000204811000000000000225C45 -+:1024A000002044110000000000000000C02048008F -+:1024B000000000000000A1FC00204411000000000A -+:1024C00000000000C02048000000000000000000E4 -+:1024D000C0200400000000000000000000A0000A6E -+:1024E00000000000970000000020441100000000E0 -+:1024F0000000000000204811000000008A000000D9 -+:1025000000204411000000000000000000204811DD -+:10251000000000000000225C0020441100000000C8 -+:1025200000000000C0204800000000000000A1FCE6 -+:10253000002044110000000000000000C0204800FE -+:102540000000000000000000C020040000000000A7 -+:102550000000000000A0000A00000000970000003A -+:10256000002044110000000000000000002048117D -+:10257000000000008A00000000204411000000005C -+:102580000000000000204811000000000000225C54 -+:10259000002044110000000000000000C02048009E -+:1025A000000000000000A1FC002044110000000019 -+:1025B00000000000C0204800000000000001A1FD54 -+:1025C000002044110000000000000000D900480075 -+:1025D0000000000000000000C02004000000000017 -+:1025E0000000000000A0000A0000000000002257C8 -+:1025F000002044110000000000000003C0484A20F1 -+:10260000000000000000225D0020441100000000D6 -+:1026100000000000C0404800000000000000000072 -+:1026200000600000000005C500000000C020080098 -+:10263000000000000000225C0020441100000000A7 -+:102640000000000300384A22000000000000A1FC46 -+:10265000002044110000000000000000C0204800DD -+:10266000000000000001A1FD002044110000000056 -+:1026700000000000002F0222000000000000000007 -+:102680000CE00000000000000000000040204800B6 -+:10269000000000000000000140304A20000000005F -+:1026A00000000002C0304A200000000000000001CD -+:1026B00000530A22000003340000003FC0280A2013 -+:1026C0000000000081000000002044110000000014 -+:1026D000000000010020481100000000000021F867 -+:1026E00000204411000000000000001700204811E5 -+:1026F00000000000000421F90060441100000614ED -+:102700000000001100210230000000000000000065 -+:1027100014E000000000033D00000014002F02221E -+:1027200000000000000000000CC000000000035189 -+:102730000000201000204411000000000000800074 -+:1027400000204811000000000001A2A40020441154 -+:102750000000000000000000002048110000000000 -+:1027600000000016006048110000035E0000210018 -+:10277000002044110000000000000000C0204800BC -+:102780000000000000000000C02048000000000021 -+:1027900000000000C0204800000000000000000011 -+:1027A000C0204800000000000001A2A40020441145 -+:1027B00000000000000000000020481100000000A0 -+:1027C000000000000040480200000000000000047B -+:1027D000002F022200000000000000000CC00000DA -+:1027E00000000355000020100020441100000000EC -+:1027F000000080000040481100000349000000284C -+:10280000002F022200000000000000000CE0000089 -+:1028100000000349000021040020441100000000D2 -+:1028200000000000C0204800000000000000000080 -+:10283000C02048000000000000000000C020480048 -+:102840000000000000000000C02048000000000060 -+:102850000000A2A4002044110000000000000000BD -+:10286000004048020000000000000035002036262D -+:1028700000000000000000490020181100000000C6 -+:1028800000000000002048110000000000000001CE -+:1028900000331A260000000000000000002F02266E -+:1028A00000000000000000000CC0000000000360F9 -+:1028B0000000003500801A2D000000000000003FDD -+:1028C000C0280A200000000000000015002F02228E -+:1028D00000000000000000000CE000000000037693 -+:1028E0000000001E002F0222000000000000000077 -+:1028F0000CE000000000038000000020002F0222F6 -+:1029000000000000000000000CE000000000038C4C -+:102910000000000F002F0222000000000000000055 -+:102920000CE000000000039800000010002F0222BD -+:1029300000000000000000000CE000000000039810 -+:1029400000000006002F022200000000000000002E -+:102950000CE000000000039A00000016002F022285 -+:1029600000000000000000000CE000000000039FD9 -+:102970000000A2A40020441100000000000000009C -+:1029800000404802000000000800000000290A2260 -+:10299000000000000000000340210E2000000000A5 -+:1029A0000000000CC0211220000000000008000000 -+:1029B000002812240000000000000014C02216208D -+:1029C0000000000000000000002914A40000000026 -+:1029D0000000A2A40020441100000000000000003C -+:1029E000002948A2000000000000A1FE00204411C0 -+:1029F000000000000000000000404803000000004C -+:102A000081000000002044110000000000000001CF -+:102A10000020481100000000000021F800204411AF -+:102A20000000000000000015002048110000000018 -+:102A3000000421F900604411000006140000001594 -+:102A400000210230000000000000000014E000003F -+:102A5000000003820000210E00204411000000004D -+:102A600000000000C020480000000000000000003E -+:102A7000C0204800000000000000A2A40020441173 -+:102A800000000000000000000040480200000000BC -+:102A9000810000000020441100000000000000013F -+:102AA0000020481100000000000021F8002044111F -+:102AB0000000000000000016002048110000000087 -+:102AC000000421F900604411000006140000000316 -+:102AD00000210230000000000000000014E00000AF -+:102AE0000000038E000021080020441100000000B7 -+:102AF00000000000C02048000000000000000000AE -+:102B0000C0204800000000000000A2A400204411E2 -+:102B1000000000000000000000404802000000002B -+:102B20000000201000204411000000000000800080 -+:102B30000040481100000000000020100020441157 -+:102B4000000000000000800000204811000000008C -+:102B50000001A2A4002044110000000000000000B9 -+:102B6000002048110000000000000006004048114D -+:102B700000000000000020100020441100000000B0 -+:102B80000000800000204811000000000001A2A405 -+:102B90000020441100000000000000000020481147 -+:102BA0000000000000000016006048110000035EF5 -+:102BB0000000001600404811000000000000000066 -+:102BC000C02008000000000000000000C0200C0031 -+:102BD000000000000000001D002102230000000092 -+:102BE0000000000014E00000000003B981000000B4 -+:102BF00000204411000000000000000100204811E6 -+:102C000000000000000021F8002044110000000036 -+:102C1000000000170020481100000000000421F906 -+:102C20000060441100000614000000110021023071 -+:102C3000000000000000000014E00000000003ABF2 -+:102C400000002100002044110000000000000000EE -+:102C5000002048020000000000000000002048039F -+:102C600000000000BABECAFE0020481100000000AB -+:102C7000CAFEBABE0020481100000000000020106B -+:102C800000204411000000000000800000204811D6 -+:102C9000000000000000A2A4002044110000000079 -+:102CA00000000004004048110000000000002170F6 -+:102CB0000020441100000000000000000020480235 -+:102CC0000000000000000000002048030000000099 -+:102CD0008100000000204411000000000000000AF4 -+:102CE000002048110000000000000000002000103B -+:102CF000000000000000000014C00000000003BE3F -+:102D00008C0000000020441100000000CAFEBABE82 -+:102D10000040481100000000810000000020441124 -+:102D20000000000000000001002048110000000029 -+:102D300000003FFF40280A20000000008000000043 -+:102D400040280E200000000040000000C028122093 -+:102D50000000000000040000006946220000061484 -+:102D6000000000000020141000000000000000001F -+:102D7000002F022300000000000000000CC0000033 -+:102D8000000003CC00000000C0401800000003CF8A -+:102D900000003FFFC0281A200000000000040000CF -+:102DA00000694626000006140000000000201810EC -+:102DB0000000000000000000002F022400000000BE -+:102DC000000000000CC00000000003D20000000062 -+:102DD000C0401C00000003D500003FFFC0281E209B -+:102DE00000000000000400000069462700000614EF -+:102DF0000000000000201C10000000000000000087 -+:102E0000002044020000000000000000002820C54F -+:102E10000000000000000000004948E80000000039 -+:102E2000A580000000200811000000000000200024 -+:102E300000200C110000000083000000006044111D -+:102E4000000003FD0000000000204402000000001C -+:102E500000000000C020480000000000000000004A -+:102E600040204800000000000000001FC021022098 -+:102E7000000000000000000014C00000000003E299 -+:102E8000000020100020441100000000000080001D -+:102E900000204811000000000000FFFFC048122081 -+:102EA000000003EAA78000000020081100000000D5 -+:102EB0000000A00000200C110000000083000000B2 -+:102EC00000604411000003FD0000000000204402E7 -+:102ED0000000000000000000C020480000000000CA -+:102EE00000000000C0204800000000000000FFFFBC -+:102EF000C0281220000000008300000000204411C0 -+:102F000000000000000000000030488300000000C6 -+:102F100084000000002044110000000000000000B8 -+:102F2000C020480000000000000000001D0000005C -+:102F3000000000008300000000604411000003FD59 -+:102F400000000000C040040000000001A980000053 -+:102F500000200811000000000000C00000400C111B -+:102F6000000003E5AB800000002008110000000015 -+:102F70000000F8E000400C11000003E5AD80000007 -+:102F800000200811000000000000F88000400C1133 -+:102F9000000003E5B38000000020081100000000DD -+:102FA0000000F3FC00400C11000003E5AF800000BE -+:102FB00000200811000000000000E00000400C119B -+:102FC000000003E5B18000000020081100000000AF -+:102FD0000000F00000400C11000003E58300000039 -+:102FE000002044110000000000002148002048118A -+:102FF00000000000840000000020441100000000D8 -+:1030000000000000C0204800000000000000000098 -+:103010001D00000000000000000000000080000013 -+:103020000000000000182000C03046200000000012 -+:1030300000000000D900480000000000000000006F -+:10304000C0200400000000000000000000A0000AF2 -+:10305000000000000018A000C03046200000000062 -+:1030600000000000D900480000000000000000003F -+:10307000C0200400000000000000000000A0000AC2 -+:10308000000000000018C000C03046200000000012 -+:1030900000000000D900480000000000000000000F -+:1030A000C0200400000000000000000000A0000A92 -+:1030B000000000000018F8E0C030462000000000CA -+:1030C00000000000D90048000000000000000000DF -+:1030D000C0200400000000000000000000A0000A62 -+:1030E000000000000018F880C030462000000000FA -+:1030F00000000000D90048000000000000000000AF -+:10310000C0200400000000000000000000A0000A31 -+:10311000000000000018E000C03046200000000061 -+:1031200000000000D900480000000000000000007E -+:10313000C0200400000000000000000000A0000A01 -+:10314000000000000018F000C03046200000000021 -+:1031500000000000D900480000000000000000004E -+:10316000C0200400000000000000000000A0000AD1 -+:10317000000000000018F3FCC030462000000000F2 -+:1031800000000000D900480000000000000000001E -+:10319000C0200400000000000000000000A0000AA1 -+:1031A0000000000086000000002044110000000024 -+:1031B0000000000000404801000000008500000001 -+:1031C0000020441100000000000000000040480101 -+:1031D000000000000000217C0020441100000000DD -+:1031E00000000000C02048000000000000000000B7 -+:1031F000C02048000000000000000000C02048007F -+:1032000000000000810000000020441100000000C8 -+:103210000000000100204811000000000000000034 -+:10322000C02008000000000000000000170000009F -+:10323000000000000004217F00604411000006141B -+:103240000000001F0021023000000000000000000C -+:1032500014C00000000000000000000000404C020C -+:103260000000042E00000000C0200C000000000040 -+:1032700000000000C020100000000000000000005E -+:10328000C02014000000000000000000C020180052 -+:103290000000000000000000C0201C000000000032 -+:1032A00000007F0000280A21000000000000450007 -+:1032B000002F022200000000000000000CE00000CF -+:1032C0000000043C00000000C020200000000000BE -+:1032D00000000000170000000000000000000010C7 -+:1032E00000280A230000000000000010002F022226 -+:1032F00000000000000000000CE00000000004449A -+:1033000081000000002044110000000000000001C6 -+:10331000002048110000000000040000006946245D -+:103320000000061400000000004000000000044DF2 -+:103330008100000000204411000000000000000097 -+:1033400000204811000000000000216D0020441101 -+:103350000000000000000000002048040000000001 -+:1033600000000000002048050000000000000000F0 -+:103370001AC00000000004499E0000000020441113 -+:1033800000000000CAFEBABE002048110000000084 -+:10339000000000001AE000000000044C00000000E3 -+:1033A000002824F0000000000000000700280A2385 -+:1033B0000000000000000001002F022200000000B9 -+:1033C000000000000AE000000000045400000000BB -+:1033D000002F00C9000000000000000004E0000011 -+:1033E0000000046D00000000004000000000047AAE -+:1033F00000000002002F0222000000000000000078 -+:103400000AE000000000045900000000002F00C97D -+:10341000000000000000000002E000000000046D59 -+:1034200000000000004000000000047A00000003DB -+:10343000002F022200000000000000000AE000004F -+:103440000000045E00000000002F00C90000000022 -+:10345000000000000CE000000000046D000000000F -+:10346000004000000000047A00000004002F022247 -+:1034700000000000000000000AE0000000000463FB -+:1034800000000000002F00C9000000000000000044 -+:103490000AE000000000046D000000000040000091 -+:1034A0000000047A00000005002F02220000000046 -+:1034B000000000000AE000000000046800000000B6 -+:1034C000002F00C9000000000000000006E000001E -+:1034D0000000046D00000000004000000000047ABD -+:1034E00000000006002F0222000000000000000083 -+:1034F0000AE000000000046D00000000002F00C979 -+:10350000000000000000000008E000000000046D62 -+:1035100000000000004000000000047A00007F006E -+:1035200000280A210000000000004500002F0222B0 -+:1035300000000000000000000AE0000000000000A1 -+:103540000000000800210A23000000000000000025 -+:1035500014C000000000047700002169002044111D -+:103560000000000000000000C02048000000000033 -+:1035700000000000C0204800000000000000000023 -+:10358000C020480000000000CAFEBABE004048113A -+:103590000000000000000000C02044000000000007 -+:1035A00000000000C020000000000000000000003B -+:1035B000C04048000000000000007F0000280A21F1 -+:1035C0000000000000004500002F02220000000063 -+:1035D000000000000AE0000000000480000000007D -+:1035E000C02000000000000000000000C02000001B -+:1035F0000000000000000000C040000000000000CB -+:103600000000000000404C080000043C00000000E6 -+:10361000C0200800000000000000001040210E2023 -+:1036200000000000000000114021122000000000F6 -+:103630000000001240211620000000000000216957 -+:10364000002044110000000000000000002048029B -+:103650000000000000000000002102250000000022 -+:103660000000000014E000000000048A00040000D4 -+:10367000C0494A200000048BFFFBFFFFC0284A20FE -+:1036800000000000000000000021022300000000F4 -+:103690000000000014E0000000000497000000009B -+:1036A000C02048000000000000000000C0204800CA -+:1036B00000000000000000000021022400000000C3 -+:1036C0000000000014C000000000000081000000A5 -+:1036D00000204411000000000000000C00204811F0 -+:1036E00000000000000000000020001000000000AA -+:1036F0000000000014C0000000000493A0000000BF -+:103700000020441100000000CAFEBABE004048116B -+:1037100000000000810000000020441100000000B3 -+:103720000000000400204811000000000000216B90 -+:10373000002044110000000000000000C0204810DC -+:103740000000000081000000002044110000000083 -+:103750000000000500204811000000000000216C5E -+:10376000002044110000000000000000C0204810AC -+:103770000000000000000000002F022400000000F4 -+:10378000000000000CE0000000000000000000004D -+:10379000004000000000049100000000C0210A2049 -+:1037A000000000000000000014C00000000004AE93 -+:1037B0008100000000204411000000000000000013 -+:1037C00000204811000000000000216D002044117D -+:1037D0000000000000000000C020480000000000C1 -+:1037E00000000000C02048000000000000000000B1 -+:1037F0001AC00000000004A99E000000002044112F -+:1038000000000000CAFEBABE0020481100000000FF -+:10381000000000001AE00000000004AC00000000FE -+:1038200000400000000004B28100000000204411AC -+:10383000000000000000000100204811000000000E -+:1038400000040000C0294620000000000000000025 -+:10385000C0600000000006140000000100210222E8 -+:10386000000000000000000014C00000000004B9C7 -+:103870000000216900204411000000000000000049 -+:10388000C02048000000000000000000C0204800E8 -+:1038900000000000000000000020481000000000B0 -+:1038A000CAFEBABE0040481100000000000000003F -+:1038B000C02044000000000000000000C04048108C -+:1038C0000000000081000000002044110000000002 -+:1038D000000000010020481100000000000021F855 -+:1038E00000204411000000000000000D00204811DD -+:1038F00000000000000421F90060441100000614DB -+:103900000000000000210230000000000000000064 -+:1039100014C00000000004BB0000218000204411FE -+:103920000000000000000000C0204800000000006F -+:1039300000000000C02000000000000000000000A7 -+:10394000C02048000000000000000000C02000006F -+:103950000000000000000000C0404800000000001F -+:103960000000000300333E2F0000000000000001B3 -+:1039700000210221000000000000000014E000000F -+:10398000000004EB0000003500200A2D00000000BC -+:103990000004000018E00C11000004DA000000012F -+:1039A00000333E2F00000000000021690020441178 -+:1039B000000000000000000000204802000000009D -+:1039C0000000000000204803000000000000000884 -+:1039D00000300A220000000000000000C020480063 -+:1039E0000000000000000000C020480000000000AF -+:1039F00000002169002044110000000000000000C8 -+:103A000000204802000000000000000000204803E1 -+:103A1000000000000000000800300A220000000042 -+:103A200000000000C020480000000000000000006E -+:103A3000D8C04800000004CE0000216900204411D5 -+:103A4000000000000000000000204802000000000C -+:103A500000000000002048030000000000000008F3 -+:103A600000300A220000000000000000C0204800D2 -+:103A70000000000000000000C0204800000000001E -+:103A8000000000360020122D0000000000000000A1 -+:103A900000290C830000000000002169002044116F -+:103AA00000000000000000000020480200000000AC -+:103AB0000000000000204803000000000000000893 -+:103AC00000300A220000000000000000C020480072 -+:103AD0000000000000000000C020480000000000BE -+:103AE000000000110021022400000000000000007E -+:103AF00014C00000000000000000000000400000B2 -+:103B00000000049100000035C020362000000000B5 -+:103B100000000036C0403620000000000000304A9F -+:103B20000020441100000000E0000000C0484A20CE -+:103B3000000000000000000F002102210000000032 -+:103B40000000000014C00000000004F200000000AB -+:103B5000006000000000000B00000000D900000021 -+:103B60000000000000000000C04004000000000150 -+:103B7000810000000020441100000000000000024D -+:103B80000020481100000000000000FF00280E3057 -+:103B90000000000000000000002F022300000000D1 -+:103BA000000000000CC00000000004F6000000004F -+:103BB000C0200800000000000000000014C0000049 -+:103BC0000000050B0000000000200C1100000000A8 -+:103BD0000000002400203623000000000000003414 -+:103BE00000203623000000000000003200203623B1 -+:103BF000000000000000003100203623000000001B -+:103C00000000001D00203623000000000000002DF1 -+:103C100000203623000000000000002E0020362384 -+:103C2000000000000000001B002036230000000000 -+:103C30000000001C0020362300000000FFFFE00011 -+:103C400000200C1100000000000000290020362395 -+:103C5000000000000000002A0020362300000000C1 -+:103C600000001FFF00200C11000000000000002BCE -+:103C700000203623000000000000002C0020362326 -+:103C800000000000F1FFFFFF00283A2E00000000B6 -+:103C90000000001AC0220E200000000000000000FA -+:103CA0000029386E0000000081000000002044114F -+:103CB0000000000000000006002048110000000085 -+:103CC0000000003340203620000000008700000084 -+:103CD000002044110000000000000000C020480047 -+:103CE000000000000000A1F40020441100000000CA -+:103CF0000000000000204810000000009D000000AF -+:103D000000204411000000000000001F40214A2054 -+:103D10000000000096000000002044110000000098 -+:103D200000000000C020480000000000000000006B -+:103D3000C0200C000000000000000000C0201000A7 -+:103D4000000000000000001F0021162400000000F9 -+:103D50000000000014C0000000000000000000256A -+:103D600000203623000000000000000300281E236E -+:103D700000000000000000080022222300000000D4 -+:103D8000FFFFF000002822280000000000000000D3 -+:103D9000002920E80000000000000027002036284D -+:103DA000000000000000001800211E230000000099 -+:103DB000000000280020362700000000000000025C -+:103DC000002216240000000000000000003014A8AB -+:103DD0000000000000000026002036250000000042 -+:103DE0000000000300211A24000000001000000061 -+:103DF00000281A2600000000EFFFFFFF00283A2EDF -+:103E00000000000000000000004938CE000006025B -+:103E10000000000140280A20000000000000000609 -+:103E200040280E200000000000000300C0281220DF -+:103E30000000000000000008002112240000000023 -+:103E400000000000C020162000000000000000005C -+:103E5000C0201A2000000000000000000021022203 -+:103E6000000000000000000014C000000000054138 -+:103E7000810000000020441100000000000000014B -+:103E800000204811000000000000225800300A24E1 -+:103E90000000000000040000006946220000061433 -+:103EA0000000216900204411000000000000000013 -+:103EB00000204805000000000002000000294A26FA -+:103EC000000000000000000000204810000000007A -+:103ED000CAFEBABE00204811000000000000000227 -+:103EE000002F022300000000000000000CC00000B2 -+:103EF0000000054900000000C0201C100000000068 -+:103F000000000000C04000000000055B000000024F -+:103F1000002F022300000000000000000CC0000081 -+:103F2000000005498100000000204411000000004D -+:103F3000000000010020481100000000000022588D -+:103F400000300A240000000000040000006946223E -+:103F50000000061400000000C0201C10000000003B -+:103F600000000000C04000000000055B00000000F1 -+:103F7000002F022300000000000000000CC0000021 -+:103F80000000054D00000000C0201C0000000000E3 -+:103F900000000000C04000000000055B00000004BD -+:103FA000002F022300000000000000000CC00000F1 -+:103FB00000000559810000000020441100000000AD -+:103FC0000000000000204811000000000000216DEA -+:103FD000002044110000000000000000C020480044 -+:103FE0000000000000000000C020480000000000A9 -+:103FF000000000001AC00000000005549E000000F0 -+:104000000020441100000000CAFEBABE0020481182 -+:1040100000000000000000001AE00000000005574A -+:104020000000000000401C100000055B00000000C4 -+:10403000C02000000000000000000000C0400000A0 -+:1040400000000000000000000EE000000000055D20 -+:104050000000000000600000000005A40000000057 -+:10406000002F022400000000000000000CC000002F -+:104070000000056D0000A2B7002044110000000000 -+:104080000000000000204807000000008100000040 -+:104090000020441100000000000000010020481131 -+:1040A000000000000004A2B60060441100000614E5 -+:1040B0000000001A0021223000000000000000066D -+:1040C00000222630000000000000A2C4002044119D -+:1040D0000000000000000000003048E9000000007F -+:1040E0000000000000E000000000056B0000A2D10D -+:1040F00000204411000000000000000000404808BB -+:10410000000000000000A2D10020441100000000C7 -+:104110000000000100504A280000000000000001DB -+:10412000002F022400000000000000000CC000006E -+:104130000000057D0000A2BB00204411000000002B -+:10414000000000000020480700000000810000007F -+:104150000020441100000000000000010020481170 -+:10416000000000000004A2BA006044110000061420 -+:104170000000001A002122300000000000000006AC -+:1041800000222630000000000000A2C500204411DB -+:104190000000000000000000003048E900000000BE -+:1041A0000000000000E000000000057B0000A2D23B -+:1041B00000204411000000000000000000404808FA -+:1041C000000000000000A2D2002044110000000006 -+:1041D0000000000100504A2800000000000000021A -+:1041E000002F022400000000000000000CC00000AE -+:1041F0000000058D0000A2BF002044110000000057 -+:1042000000000000002048070000000081000000BE -+:1042100000204411000000000000000100204811AF -+:10422000000000000004A2BE00604411000006145B -+:104230000000001A002122300000000000000006EB -+:1042400000222630000000000000A2C60020441119 -+:104250000000000000000000003048E900000000FD -+:104260000000000000E000000000058B0000A2D369 -+:104270000020441100000000000000000040480839 -+:10428000000000000000A2D3002044110000000044 -+:104290000000000100504A28000000000000A2C3F6 -+:1042A000002044110000000000000000002048072A -+:1042B0000000000081000000002044110000000008 -+:1042C0000000000100204811000000000004A2C20C -+:1042D00000604411000006140000001A0021223082 -+:1042E0000000000000000006002226300000000050 -+:1042F0000000A2C7002044110000000000000000E0 -+:10430000003048E9000000000000000000E000006C -+:10431000000005990000A2D4002044110000000014 -+:104320000000000000404808000000000000A2D487 -+:1043300000204411000000000000000100504A2845 -+:104340000000000085000000002044110000000073 -+:104350000000000000204801000000000000304A7A -+:10436000002044110000000001000000002048115E -+:104370000000000000000000004000000000059F59 -+:10438000A4000000C0204411000000000000000054 -+:10439000C04048000000000000000000C0600000B5 -+:1043A000000005A400000000C0400400000000015F -+:1043B0000001A2A400204411000000000000000041 -+:1043C00000204811000000000000000000204811FB -+:1043D0000000000000000000002048110000000064 -+:1043E000000000000020481100000000000000054F -+:1043F00000204811000000000000A1F4002044113A -+:104400000000000000000000002048110000000033 -+:10441000880000000020441100000000000000019E -+:104420000020481100000000FF000000002044119F -+:104430000000000000000000002048110000000003 -+:1044400000000001002048110000000000000002F0 -+:104450000080481100000000000000000EE0000095 -+:10446000000005B700001000002008110000000047 -+:104470000000003400203622000000000000000090 -+:1044800000600000000005BB0000000000600000AC -+:10449000000005A498000000002044110000000066 -+:1044A0000000000000804811000000000000000033 -+:1044B000C0600000000005BB00000000C040040018 -+:1044C000000000010000A2A4002044110000000030 -+:1044D00000000022002048110000000089000000B8 -+:1044E00000204411000000000000000100204811DD -+:1044F00000000000FF000000002044110000000048 -+:104500000000000000204811000000000000000131 -+:104510000020481100000000000000020080481147 -+:10452000000000000000217AC020441100000000BB -+:10453000000000000040481100000000970000004B -+:10454000002044110000000000000000002048117D -+:10455000000000008A00000000204411000000005C -+:10456000000000000020481100000000FF000000D3 -+:10457000002044110000000000000000002048114D -+:1045800000000000000000010020481100000000B1 -+:104590000000000200804811000000000000000040 -+:1045A00000600000000005E1000020100020441120 -+:1045B0000000000000008000002048110000000002 -+:1045C0000001A2A4C020441100000000000000006F -+:1045D0000020481100000000000000160060481193 -+:1045E0000000035E000000160020481100000000DB -+:1045F0000000201000204411000000000001000015 -+:10460000002048110000000081000000002044113B -+:104610000000000000000001002048110000000020 -+:104620000000217C002044110000000009800000EF -+:104630000020481100000000FFFFFFFF002048118C -+:1046400000000000000000000020481100000000F1 -+:104650000000000017000000000000000004217F9F -+:1046600000604411000006140000001F0021023009 -+:10467000000000000000000014C000000000000066 -+:104680000000000400404C11000005DC0000001D8B -+:1046900000201E2D000000000000000400291E273D -+:1046A000000000000000001D008036270000000010 -+:1046B0000000001D00201E2D00000000FFFFFFFB7A -+:1046C00000281E27000000000000001D0080362783 -+:1046D000000000000000001D00201E2D0000000052 -+:1046E0000000000800291E27000000000000001D37 -+:1046F00000803627000000000000001D00201E2D55 -+:1047000000000000FFFFFFF700281E270000000048 -+:104710000000001D0080362700000000000020106F -+:10472000002044110000000000008000002048111B -+:10473000000000000001A2A40020441100000000BD -+:1047400000000000002048110000000000000016DA -+:10475000006048110000035E0000001600204811B0 -+:1047600000000000000020100020441100000000A4 -+:104770000001000000204811000000000000217C22 -+:1047800000204411000000000180000000204811BA -+:104790000000000000FFFFFF0020481100000000A3 -+:1047A0000000000000204811000000000000000090 -+:1047B00017000000000000008100000000204411EC -+:1047C000000000000000000100204811000000006F -+:1047D0000004217F00604411000006140000000066 -+:1047E00000200010000000000000000014C00000C5 -+:1047F000000006130000001000404C11000005F9F5 -+:1048000000000000C02004000000000000000000C4 -+:1048100038C00000000000000000002500200A2D24 -+:10482000000000000000002600200E2D0000000007 -+:10483000000000270020122D0000000000000028CA -+:104840000020162D00000000000021690020441106 -+:1048500000000000000000000020480400000000EC -+:1048600000000000002048050000000000000000DB -+:104870000020480100000000CAFEBABE0020481116 -+:1048800000000000000000040030122400000000BE -+:1048900000000000002F0064000000000000000085 -+:1048A0000CC00000000006120000000300281A22BD -+:1048B000000000000000000800221222000000009A -+:1048C000FFFFF0000028122400000000000000009C -+:1048D000002910C40000000000000027004036241A -+:1048E0000000000000000000008000000000000048 -+:1048F000000000001AC00000000006149F00000025 -+:104900000020441100000000CAFEBABE0020481179 -+:1049100000000000000000001AE000000000061780 -+:104920000000000000800000000000000000000007 -+:10493000006000000000000B000010000060041187 -+:10494000000002FE00000000002004110000000032 -+:1049500000000000006008110000019F0000225CC0 -+:104960000020441100000000000000030020481156 -+:10497000000000000000225600204411000000004A -+:104980000000001B00204811000000000000A1FCF6 -+:104990000020441100000000000000010020481128 -+:1049A000000000000001A1FDC02044110000000033 -+:1049B0000000002900201E2D000000000000001053 -+:1049C00000221E27000000000000002C0020222DE5 -+:1049D000000000000000FFFF002822280000000067 -+:1049E000000000000029490700000000000000004E -+:1049F00000204811000000000000002A0020222DA5 -+:104A0000000000000000FFFF002822280000000036 -+:104A1000000000000029490700000000000000001D -+:104A200000204811000000000000002B00201E2D77 -+:104A3000000000000000001000221E2700000000FF -+:104A400000000000002949070000000000000000ED -+:104A500000404811000000000000000000000000BD -+:104A60000000000000000000000000000000000046 -+:104A70000000000000000000000000000000000036 -+:104A80000000000000000000000000000000000026 -+:104A90000000000000000000000000000000000016 -+:104AA0000000000000000000000000000000000006 -+:104AB00000000000000000000000000000000000F6 -+:104AC00000000000000000000000000000000000E6 -+:104AD00000000000000000000000000000000000D6 -+:104AE00000000000000000000000000000000000C6 -+:104AF00000000000000000000000000000000000B6 -+:104B000000000000000000000000000000000000A5 -+:104B10000000000000000000000000000000000095 -+:104B20000000000000000000000000000000000085 -+:104B30000000000000000000000000000000000075 -+:104B40000000000000000000000000000000000065 -+:104B50000000000000000000000000000000000055 -+:104B60000000000000000000000000000000000045 -+:104B70000000000000000000000000000000000035 -+:104B80000000000000000000000000000000000025 -+:104B90000000000000000000000000000000000015 -+:104BA0000000000000000000000000000000000005 -+:104BB00000000000000000000000000000000000F5 -+:104BC00000000000000000000000000000000000E5 -+:104BD00000000000000000000000000000000000D5 -+:104BE00000000000000000000000000000000000C5 -+:104BF00000000000000000000000000000000000B5 -+:104C000000000000000000000000000000000000A4 -+:104C10000000000000000000000000000000000094 -+:104C20000000000000000000000000000000000084 -+:104C30000000000000000000000000000000000074 -+:104C40000000000000000000000000000000000064 -+:104C50000000000000000000000000000000000054 -+:104C60000000000000000000000000000000000044 -+:104C70000000000000000000000000000000000034 -+:104C80000000000000000000000000000000000024 -+:104C90000000000000000000000000000000000014 -+:104CA0000000000000000000000000000000000004 -+:104CB00000000000000000000000000000000000F4 -+:104CC00000000000000000000000000000000000E4 -+:104CD00000000000000000000000000000000000D4 -+:104CE00000000000000000000000000000000000C4 -+:104CF00000000000000000000000000000000000B4 -+:104D000000000000000000000000000000000000A3 -+:104D10000000000000000000000000000000000093 -+:104D20000000000000000000000000000000000083 -+:104D30000000000000000000000000000000000073 -+:104D40000000000000000000000000000000000063 -+:104D50000000000000000000000000000000000053 -+:104D60000000000000000000000000000000000043 -+:104D70000000000000000000000000000000000033 -+:104D80000000000000000000000000000000000023 -+:104D90000000000000000000000000000000000013 -+:104DA0000000000000000000000000000000000003 -+:104DB00000000000000000000000000000000000F3 -+:104DC00000000000000000000000000000000000E3 -+:104DD00000000000000000000000000000000000D3 -+:104DE00000000000000000000000000000000000C3 -+:104DF00000000000000000000000000000000000B3 -+:104E000000000000000000000000000000000000A2 -+:104E10000000000000000000000000000000000092 -+:104E20000000000000000000000000000000000082 -+:104E30000000000000000000000000000000000072 -+:104E40000000000000000000000000000000000062 -+:104E50000000000000000000000000000000000052 -+:104E60000000000000000000000000000000000042 -+:104E70000000000000000000000000000000000032 -+:104E80000000000000000000000000000000000022 -+:104E90000000000000000000000000000000000012 -+:104EA0000000000000000000000000000000000002 -+:104EB00000000000000000000000000000000000F2 -+:104EC00000000000000000000000000000000000E2 -+:104ED00000000000000000000000000000000000D2 -+:104EE00000000000000000000000000000000000C2 -+:104EF00000000000000000000000000000000000B2 -+:104F000000000000000000000000000000000000A1 -+:104F10000000000000000000000000000000000091 -+:104F20000000000000000000000000000000000081 -+:104F30000000000000000000000000000000000071 -+:104F40000000000000000000000000000000000061 -+:104F50000000000000000000000000000000000051 -+:104F60000000000000000000000000000000000041 -+:104F70000000000000000000000000000000000031 -+:104F80000000000000000000000000000000000021 -+:104F90000000000000000000000000000000000011 -+:104FA0000000000000000000000000000000000001 -+:104FB00000000000000000000000000000000000F1 -+:104FC00000000000000000000000000000000000E1 -+:104FD00000000000000000000000000000000000D1 -+:104FE00000000000000000000000000000000000C1 -+:104FF00000000000000000000000000000000000B1 -+:1050000000000000000000000000000000000000A0 -+:105010000000000000000000000000000000000090 -+:105020000000000000000000000000000000000080 -+:105030000000000000000000000000000000000070 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B000013304EF059B02390000000001B00159E1 -+:1052C0000425059B00000000021201F6023901428C -+:1052D000000000000210022E0289022A00000000D5 -+:1052E00003C2059B059B059B0000000005CD05CE74 -+:1052F0000308059B00000000059B05A00309032986 -+:10530000000000000313026B032B031D00000000CC -+:10531000059B059B059B059B00000000059B052C3C -+:10532000059B059B0000000003A5059B04A2032D1F -+:1053300000000000048104330423059B00000000EA -+:1053400004BB04ED042704C800000000043304F487 -+:10535000033A036500000000059B059B059B059B28 -+:1053600000000000059B059B059B059B00000000BD -+:10537000059B059B05B905A200000000059B059B48 -+:105380000007059B00000000059B059B059B059BF6 -+:1053900000000000059B059B059B059B000000008D -+:1053A00003E303D803F303F10000000003F903F55E -+:1053B00003F703FB0000000004070403040F040BC1 -+:1053C0000000000004170413041F041B0000000069 -+:1053D000059B059B059B059B00000000059B059B0D -+:1053E000059B059B00000000059B059B059B059BFD -+:1053F0000000000000020600061900060000000080 -+:00000001FF -diff --git a/firmware/radeon/R600_pfp.bin.ihex b/firmware/radeon/R600_pfp.bin.ihex -new file mode 100644 -index 0000000..5236108 ---- /dev/null -+++ b/firmware/radeon/R600_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000D4007100D4007200CA040000A00000F7 -+:10001000007E828B0080000300CA040000D4401ED2 -+:1000200000EE001E00CA040000A00000007E828BCB -+:1000300000C4183800CA240000CA2800009581A80E -+:1000400000C41C3A00C3C00000CA080000CA0C006B -+:10005000007C744B00C200050099C00000C41C3A2B -+:10006000007C744C00C0FFF000042C0400309002AF -+:10007000007D250000351402007D350B002554035A -+:10008000007CD58000259C030095C00400D5001B92 -+:10009000007EDDC1007D9D8000D6801B00D5801BC9 -+:1000A00000D4401E00D5401E00D6401E00D6801E43 -+:1000B00000D4801E00D4C01E009783D400D5C01E7B -+:1000C00000CA08000080001B00CA0C0000E4011EEA -+:1000D00000D4001E0080000D00C4183800E4013E6A -+:1000E00000D4001E0080000D00C4183800D4401E4B -+:1000F00000EE001E00CA040000A00000007E828BFB -+:1001000000E4011E00D4001E00D4401E00EE001EBC -+:1001100000CA040000A00000007E828B00E4013EC3 -+:1001200000D4001E00D4401E00EE001E00CA0400D1 -+:1001300000A00000007E828B00CA180000D4401E80 -+:1001400000D5801E0080005400D4007300D4401EEF -+:1001500000CA080000CA0C0000CA100000D48019B0 -+:1001600000D4C01800D5001700D4801E00D4C01ED3 -+:1001700000D5001E00E2001E00CA040000A000001E -+:10018000007E828B00CA080000D4806000D4401E2C -+:100190000080000200D4801E00CA080000D48061E4 -+:1001A00000D4401E0080000200D4801E00CA080057 -+:1001B00000CA0C0000D4401E00D4801600D4C01623 -+:1001C00000D4801E008001B900D4C01E00C6083EC5 -+:1001D00000CA0C0000CA10000094800400CA140079 -+:1001E00000E420F300D4201300D5606500D4E01CA7 -+:1001F00000D5201C00D5601C0080000200062001F4 -+:1002000000C6083E00CA0C0000CA1000009483F724 -+:1002100000CA140000E420F30080007A00D4201308 -+:1002200000C6083E00CA0C0000CA1000009883EF08 -+:1002300000CA140000D400640080008E000000009A -+:1002400000C4143200C6183E00C4082F00954005B3 -+:1002500000C40C3000D4401E0080000200EE001EDE -+:10026000009583F500C4103100D4403300D52065DB -+:1002700000D4A01C00D4E01C00D5201C00D40073C6 -+:1002800000E4015E00D4001E008001B900062001D8 -+:10029000000A200100D6007400C4083600C61040D1 -+:1002A0000098800700CC38350095010F00D4001F5E -+:1002B00000D460620080000200D4206200CC1433BD -+:1002C000008401BC00D4007000D5401E00800002F4 -+:1002D00000EE001E00CA0C0000CA100000D4C01AB4 -+:1002E000008401BC00D5001A00CC04430035101F67 -+:1002F000002C9401007D098B00984005007D15CBF2 -+:1003000000D4001A008001B900D4006D003444010B -+:1003100000CC0C440098403A00CC2C460095800458 -+:1003200000CC0445008001B900D4001A00D4C01AE2 -+:1003300000282801008400F300CC10030098801BE3 -+:100340000004380C008400F300CC100300988017E0 -+:1003500000043808008400F300CC100300988013D8 -+:1003600000043804008400F300CC100300988014CB -+:1003700000CC1047009A800900CC1448009840DA5D -+:1003800000D4006D00CC184400D5001A00D5401AE6 -+:10039000008000CC00D5801A0096C0D300D4006D38 -+:1003A000008001B900D4006E009AC00300D4006D33 -+:1003B00000D4006E0080000200EC007F009AC0CAEA -+:1003C00000D4006D008001B900D4006E00CC14038D -+:1003D00000CC180300CC1C03007D9103007DD58365 -+:1003E000007D190C0035CC1F0035701F007CF0CB50 -+:1003F000007CD08B00880000007E8E8B0095C004AE -+:1004000000D4006E008001B900D4001A00D4C01AD4 -+:1004100000CC080300CC0C0300CC100300CC140368 -+:1004200000CC180300CC1C0300CC240300CC280310 -+:100430000035C41F0036B01F007C704B0034F01F25 -+:10044000007C704B0035701F007C704B007D8881F4 -+:10045000007DCCC1007E5101007E9541007C9082E0 -+:10046000007CD4C2007C848B009AC003007C8C8BFF -+:10047000002C88010098809C00D4006D0098409A60 -+:1004800000D4006E00CC084700CC0C4800CC1044CF -+:1004900000D4801A00D4C01A0080010400D5001ACC -+:1004A00000CC083200D40032009482D800CA0C007C -+:1004B00000D4401E0080000200D4001E00E4011E93 -+:1004C00000D4001E00CA080000CA0C0000CA1000B8 -+:1004D00000D4401E00CA140000D4801E00D4C01EE8 -+:1004E00000D5001E00D5401E00D54034008000021B -+:1004F00000EE001E0028040400E2001A00E2001AC8 -+:1005000000D4401A00CA380000CC080300CC0C0309 -+:1005100000CC0C0300CC0C03009882BC000000004F -+:10052000008401BC00D7806F0080000200EE001F35 -+:1005300000CA040000C2FF0000CC083400C13FFF25 -+:10054000007C74CB007CC90B007D010F009902AFC9 -+:10055000007C738B008401BC00D7806F0080000298 -+:1005600000EE001F00CA080000281900007D898BDA -+:10057000009580140028140400CA0C0000CA100062 -+:1005800000CA1C0000CA240000E2001F00D4C01AE8 -+:1005900000D5001A00D5401A00CC180300CC2C035B -+:1005A00000CC2C0300CC2C03007DA58B007D9C4748 -+:1005B00000984296000000000080016400D4C01A38 -+:1005C00000D4401E00D4801E0080000200EE001EF9 -+:1005D00000E4011E00D4001E00D4401E00EE001EE8 -+:1005E00000CA040000A00000007E828B00E4013EEF -+:1005F00000D4001E00D4401E00EE001E00CA0400FD -+:1006000000A00000007E828B00CA080000248C0637 -+:10061000000CCC060098C00600CC104900990004DC -+:1006200000D4007100E4011E00D4001E00D4401E5E -+:1006300000D4801E0080000200EE001E00CA0800E8 -+:1006400000CA0C000034D018002510010095001FCE -+:1006500000C17FFF00CA100000CA140000CA1800C1 -+:1006600000D4801D00D4C01D007DB18B00C14202AA -+:1006700000C2C00100D5801D0034DC0E007D5D4C41 -+:10068000007F734C00D7401E00D5001E00D5401ED1 -+:1006900000C1420000C2C00000099C010031DC1012 -+:1006A000007F5F4C007F734C007D838000D5806F9E -+:1006B00000D5806600D7401E00EC005E00C8240212 -+:1006C000008001B900D6007400D4401E00D4801E02 -+:1006D00000D4C01E0080000200EE001E0080000258 -+:1006E00000EE001F00D4001F0080000200D4001F95 -+:1006F00000D4001F0088000000D4001F000000008C -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:10080000000101740002017B0003009000040080DD -+:100810000005000500060040000700330008012F16 -+:1008200000090047000A0037001001B7001700A4B4 -+:100830000022013D0023014C002000B500240128C6 -+:100840000027004E0028006B002A0061002B005397 -+:10085000002F00660032008800340182003C0159FC -+:10086000003F00730041018F0044013100550176C3 -+:100870000056017D0060000C006100350062003907 -+:1008800000630039006400390065003900660039F2 -+:10089000006700390068003B00690042006A0049B7 -+:1008A000006B0049006C0049006D0049006E004972 -+:1008B000006F0049007301B7000000070000000747 -+:1008C000000000070000000700000007000000070C -+:1008D00000000007000000070000000700000007FC -+:1008E00000000007000000070000000700000007EC -+:1008F00000000007000000070000000700000007DC -+:00000001FF -diff --git a/firmware/radeon/RS600_cp.bin.ihex b/firmware/radeon/RS600_cp.bin.ihex -new file mode 100644 -index 0000000..4a89501 ---- /dev/null -+++ b/firmware/radeon/RS600_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:10000000000000004200E000000000004000E000AE -+:1000100000000008000000A000000008000000A48C -+:10002000000000004A554B4A000000004A4A44675D -+:100030000000000055526F75000000004A7E7D658B -+:10004000000000004AE74AF6000000004AD34A4A8E -+:1000500000000000D689898900000000CD4ADDCF6C -+:10006000000000008EBE4AE200000000C38A8A8AB7 -+:10007000000000004A0F8CC800000004000CA00023 -+:1000800000000038000D0012000000040000E8B479 -+:1000900000000038000D0014000000040000E8B665 -+:1000A00000000038000D0016000000040000E854B5 -+:1000B00000000038000D0018000000040000E855A2 -+:1000C00000000038000D001A000000040000E8568F -+:1000D00000000038000D001C000000040000E8577C -+:1000E00000000038000D001E000000040000E8249D -+:1000F00000000038000D0020000000040000E8258A -+:1001000000000038000D0022000000040000E8306C -+:1001100000000038000D0024000000040000F0C0C2 -+:1001200000000038000D0026000000040000F0C1AF -+:1001300000000038000D0028000000040000F0411D -+:1001400000000038000D002A000000040000F184C7 -+:1001500000000038000D002C000000040000F185B4 -+:1001600000000038000D002E000000040000F186A1 -+:1001700000000038000D0030000000040000F1878E -+:1001800000000038000D0032000000040000F18083 -+:1001900000000038000D0034000000040000F3935C -+:1001A00000000038000D0036000000040000F38A53 -+:1001B00000000038000D0038000000040000F38E3D -+:1001C000000000040000E821000000040140A0003D -+:1001D00000000018000000430000000400CCE8000C -+:1001E00000000004001B000100000004080048009B -+:1001F00000000004001B000100000004080048008B -+:1002000000000004001B000100000004080048007A -+:10021000000000080000003A000000000000A000FC -+:10022000000000042000451D000000040000E580DF -+:1002300000000004000CE581000000040800458077 -+:1002400000000004000CE5810000000800000047E9 -+:10025000000000000000A00000000004000C2000CE -+:10026000000000040000E50E000000040003200070 -+:10027000000000280002205100000024000000516E -+:10028000000000040800450F000000080000A04B1B -+:10029000000000040000E565000000040000E566C1 -+:1002A00000000008000000520000000403CCA5B4C8 -+:1002B00000000004054320000000000400022000AC -+:1002C000000000304CCCE05E0000000408274565CB -+:1002D000000000300000005E0000000408004564DB -+:1002E000000000040000E566000000080000005562 -+:1002F00000000010008020610000000400202000A9 -+:1003000000000004001B00FF00000010010000645A -+:1003100000000004001F200000000004001C00FF7B -+:100320000000000C0000000000000030000000721F -+:100330000000000800000055000000040000E57601 -+:10034000000000040000E577000000040000E50E56 -+:10035000000000040000E50F000000040140A000C0 -+:100360000000001800000069000000C200C0E5F9AC -+:100370000000000800000069000000040014E50E01 -+:10038000000000040040E50F0000000800C0006C01 -+:10039000000000040000E570000000040000E571AA -+:1003A0000000000C0000E572000000040000A00046 -+:1003B000000000040140A000000000040000E56807 -+:1003C00000000004000C200000000018000000766F -+:1003D00000000004000B00000000000418C0E562EB -+:1003E00000000008000000780000000800C000774E -+:1003F00000000004000700D5000000380000008461 -+:1004000000000030000CA08600000004080045BB7E -+:1004100000000030000C2087000000000800E5BC50 -+:10042000000000040000E5BB000000000000E5BC87 -+:100430000000000C00120000000000040012000088 -+:100440000000000C001B0002000000040000A000DF -+:10045000000000040000E821000000000000E800A7 -+:10046000000000040000E821000000000000E82E69 -+:100470000000000402CCA0000000000400140000F2 -+:1004800000000004000CE1CC00000004050DE1CDEB -+:10049000000000040040000000000018000000966A -+:1004A0000000000400C0A00000000008000000934D -+:1004B0000000002000000098000000004200E00062 -+:1004C000000000380000009F00000004000CA000A5 -+:1004D000000000040014000000000004000C2000D4 -+:1004E000000000040016000000000004700CE00092 -+:1004F000000000080014009B000000004000E00025 -+:10050000000000040240000000000004400EE00073 -+:100510000000000402400000000000004000E00075 -+:1005200000000004000C2000000000040240E51B55 -+:10053000000000050080E50A000000050080E50BD2 -+:10054000000000040022000000000004000700D5A5 -+:1005500000000038000000B200000030000C2087CE -+:10056000000000050880E5BD00000030000C20867A -+:10057000000000050800E5BB00000030000C2087EB -+:10058000000000050880E5BC00000008000000B580 -+:10059000000000050080E5BD000000050000E5BB8F -+:1005A000000000050080E5BC000000040021000000 -+:1005B00000000004028000000000001800C000B924 -+:1005C000000000404180E00000000024000000BB6B -+:1005D0000000000C010000000000000C0100E51DFF -+:1005E00000000004000045BB00000008000080B5CA -+:1005F000000000040000F3CE000000040140A00051 -+:100600000000000400CC20000000004008C053CFD0 -+:100610000000000000008000000000040000F3D291 -+:10062000000000040140A0000000000400CC2000F5 -+:100630000000004008C053D300000000000080000C -+:10064000000000040000F39D000000040140A00031 -+:100650000000000400CC20000000004008C0539EB1 -+:1006600000000000000080000000000403C008300B -+:10067000000000004200E000000000040000A000B4 -+:1006800000000004200045E0000000000000E5E15B -+:10069000000000000000000100000004000700D27C -+:1006A000000000000800E3940000000000000000CB -+:1006B000000000040000E8C4000000040000E8C5D9 -+:1006C000000000040000E8C6000000040000E92863 -+:1006D000000000040000E929000000040000E92AED -+:1006E00000000008000000D6000000040000E92817 -+:1006F000000000040000E929000000040000E92ACD -+:1007000000000008000000DD0000000000E001160D -+:1007100000000004000700E1000000040800401C85 -+:1007200000000004200050E7000000040000E01D6D -+:1007300000000008000000E40000000402C02000E7 -+:10074000000000040006000000000034000000EB80 -+:1007500000000008000000E8000000040000800025 -+:1007600000000000C000E0000000000000000000E9 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B00000000004000C200000000004001D0018D0 -+:1007C00000000004001A000100000034000000FBDB -+:1007D000000000080000004A000000080500A04AD0 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/RS690_cp.bin.ihex b/firmware/radeon/RS690_cp.bin.ihex -new file mode 100644 -index 0000000..6896274 ---- /dev/null -+++ b/firmware/radeon/RS690_cp.bin.ihex -@@ -0,0 +1,130 @@ -+:1000000000000008000000DD00000008000000DF24 -+:1000100000000008000000A000000008000000A48C -+:10002000000000004A554B4A000000004A4A44675D -+:100030000000000055526F75000000004A7E7D658B -+:10004000000000004AD74AF6000000004AC94A4AA8 -+:1000500000000000CC89898900000000C34AD3C594 -+:10006000000000008E4A4A4A000000004A8A8A8A3C -+:10007000000000004A0F8C4A00000004000CA000A1 -+:1000800000000038000D0012000000040000E8B479 -+:1000900000000038000D0014000000040000E8B665 -+:1000A00000000038000D0016000000040000E854B5 -+:1000B00000000038000D0018000000040000E855A2 -+:1000C00000000038000D001A000000040000E8568F -+:1000D00000000038000D001C000000040000E8577C -+:1000E00000000038000D001E000000040000E8249D -+:1000F00000000038000D0020000000040000E8258A -+:1001000000000038000D0022000000040000E8306C -+:1001100000000038000D0024000000040000F0C0C2 -+:1001200000000038000D0026000000040000F0C1AF -+:1001300000000038000D0028000000040000F0411D -+:1001400000000038000D002A000000040000F184C7 -+:1001500000000038000D002C000000040000F185B4 -+:1001600000000038000D002E000000040000F186A1 -+:1001700000000038000D0030000000040000F1878E -+:1001800000000038000D0032000000040000F18083 -+:1001900000000038000D0034000000040000F3935C -+:1001A00000000038000D0036000000040000F38A53 -+:1001B00000000038000D0038000000040000F38E3D -+:1001C000000000040000E821000000040140A0003D -+:1001D00000000018000000430000000400CCE8000C -+:1001E00000000004001B000100000004080048009B -+:1001F00000000004001B000100000004080048008B -+:1002000000000004001B000100000004080048007A -+:10021000000000080000003A000000000000A000FC -+:10022000000000042000451D000000040000E580DF -+:1002300000000004000CE581000000040800458077 -+:1002400000000004000CE5810000000800000047E9 -+:10025000000000000000A00000000004000C2000CE -+:10026000000000040000E50E000000040003200070 -+:10027000000000280002205100000024000000516E -+:10028000000000040800450F000000080000A04B1B -+:10029000000000040000E565000000040000E566C1 -+:1002A00000000008000000520000000403CCA5B4C8 -+:1002B00000000004054320000000000400022000AC -+:1002C000000000304CCCE05E0000000408274565CB -+:1002D000000000300000005E0000000408004564DB -+:1002E000000000040000E566000000080000005562 -+:1002F00000000010008020610000000400202000A9 -+:1003000000000004001B00FF00000010010000645A -+:1003100000000004001F200000000004001C00FF7B -+:100320000000000C0000000000000030000000721F -+:100330000000000800000055000000040000E57601 -+:10034000000000040000E577000000040000E50E56 -+:10035000000000040000E50F000000040140A000C0 -+:100360000000001800000069000000C200C0E5F9AC -+:100370000000000800000069000000040014E50E01 -+:10038000000000040040E50F0000000800C0006C01 -+:10039000000000040000E570000000040000E571AA -+:1003A0000000000C0000E572000000040000A00046 -+:1003B000000000040140A000000000040000E56807 -+:1003C00000000004000C200000000018000000766F -+:1003D00000000004000B00000000000418C0E562EB -+:1003E00000000008000000780000000800C000774E -+:1003F00000000004000700CB00000038000000846B -+:1004000000000030000CA08600000004080045BB7E -+:1004100000000030000C2087000000000800E5BC50 -+:10042000000000040000E5BB000000000000E5BC87 -+:100430000000000C00120000000000040012000088 -+:100440000000000C001B0002000000040000A000DF -+:10045000000000040000E821000000000000E800A7 -+:10046000000000040000E821000000000000E82E69 -+:100470000000000402CCA0000000000400140000F2 -+:1004800000000004000CE1CC00000004050DE1CDEB -+:10049000000000040040000000000018000000966A -+:1004A0000000000400C0A00000000008000000934D -+:1004B0000000002000000098000000004200E00062 -+:1004C000000000380000009F00000004000CA000A5 -+:1004D000000000040014000000000004000C2000D4 -+:1004E000000000040016000000000004700CE00092 -+:1004F000000000080014009B000000004000E00025 -+:10050000000000040240000000000004400EE00073 -+:100510000000000402400000000000004000E00075 -+:100520000000002C0010000000000000000040004F -+:1005300000000004080045C8000000040024000575 -+:100540000000000408004D0B00000004000C200017 -+:10055000000000040240E51B000000050080E50AE1 -+:10056000000000050080E50B0000000400220000F0 -+:1005700000000004000700CB00000038000000B7B6 -+:1005800000000030000C2087000000050880E5BD59 -+:1005900000000030000C2086000000050800E5BBCC -+:1005A00000000030000C2087000000050880E5BC3A -+:1005B00000000008000000BA000000050080E5BD52 -+:1005C000000000050000E5BB000000050080E5BC60 -+:1005D0000000000400210000000000040280000070 -+:1005E0000000001800C000BE000000404180E00094 -+:1005F00000000024000000C00000000C010000000A -+:100600000000000C0100E51D00000004000045BBD7 -+:1006100000000008000080BA0000000403C0083099 -+:10062000000000004200E000000000040000A00004 -+:1006300000000004200045E0000000000000E5E1AB -+:10064000000000000000000100000004000700C8D6 -+:10065000000000000800E39400000000000000001B -+:10066000000000040000E8C4000000040000E8C529 -+:10067000000000040000E8C6000000040000E928B3 -+:10068000000000040000E929000000040000E92A3D -+:1006900000000008000000CC000000040000E92871 -+:1006A000000000040000E929000000040000E92A1D -+:1006B00000000008000000D30000000402C0200079 -+:1006C000000000040006000000000034000000DB11 -+:1006D00000000008000000D80000000400008000B6 -+:1006E00000000000C000E00000000030000000E159 -+:1006F000000000004200E00000000030000000E1C7 -+:10070000000000004000E000000000040025001B85 -+:100710000000000400230000000000040025000584 -+:1007200000000034000000E60000000C00000000A3 -+:10073000000000040024400000000004080045C838 -+:1007400000000004002400050000000C08004D0B10 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B00000000004000C200000000004001D0018D0 -+:1007C00000000004001A000100000034000000FBDB -+:1007D000000000080000004A000000080500A04AD0 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:00000001FF -+/* production radeon ucode r1xx-r6xx */ -diff --git a/firmware/radeon/RS780_me.bin.ihex b/firmware/radeon/RS780_me.bin.ihex -new file mode 100644 -index 0000000..6479c10 ---- /dev/null -+++ b/firmware/radeon/RS780_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A0000060441100000622000000000060000013 -+:1000B000000005D10000000000600000000005DE27 -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:100660000000000000600000000005FF0000000026 -+:1006700000600000000005F30000000200210E22CF -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE0000000000000600000000005F900000000A8 -+:100AF00000400000000000EB00000000006000006B -+:100B0000000005FC000000070020222D000000006E -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E9000000006220000001F0021023000000000B8 -+:100EA0000000000014C00000000006210000000443 -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000062200000011002102300000000066 -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000062100000000002B1405000000001D -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A000000000010000000000600000000005DEF3 -+:1019B000000000000040040F0000021300000000BF -+:1019C00000600000000005D1000000000060000081 -+:1019D000000005DE00000210006004110000031585 -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B100000600000000005D10000A00C002044116E -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E3000000420040060441100000622000000009D -+:101E400000600000000005D100000000C06000003C -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000005FF0000000000600000000002B5A3 -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:10224000000005F60000000000400000000002DE73 -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A0000000097000000C020441165 -+:102600000000000000000000C02048110000000091 -+:102610008A000000C02044110000000000000000FB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D00000000000C0200400000000000000000016 -+:1026E00000A0000A00000000970000000020441134 -+:1026F0000000000000000000002048110000000061 -+:102700008A000000002044110000000000000000CA -+:1027100000204811000000000000225C002044114D -+:102720000000000000000000C02048000000000081 -+:102730000000A1FC00204411000000000000000087 -+:10274000C0204800000000000001A1FD002044114D -+:102750000000000000000000D90048000000000058 -+:1027600000000000C0200400000000000000000085 -+:1027700000A0000A000000000000225700204411C1 -+:102780000000000000000003C0484A2000000000D4 -+:102790000000225D00204411000000000000000045 -+:1027A000C040480000000000000000000060000081 -+:1027B000000005DE00000000C0200800000000004E -+:1027C0000000225C00204411000000000000000313 -+:1027D00000384A22000000000000A1FC0020441143 -+:1027E0000000000000000000C020480000000000C1 -+:1027F0000001A1FD002044110000000000000000C5 -+:10280000002F022200000000000000000CE0000089 -+:102810000000000000000000402048000000000010 -+:102820000000000140304A200000000000000002CB -+:10283000C0304A20000000000000000100530A22BE -+:10284000000003550000003FC0280A2000000000DF -+:102850008100000000204411000000000000000181 -+:102860000020481100000000000021F80020441161 -+:1028700000000000000000180020481100000000C7 -+:10288000000421F90060441100000622000000113C -+:1028900000210230000000000000000014E00000F1 -+:1028A0000000035E00000014002F02220000000060 -+:1028B000000000000CC000000000036C0001A2A496 -+:1028C00000204411000000000000000000604802E9 -+:1028D00000000374000021000020441100000000EB -+:1028E00000000000C02048000000000000000000C0 -+:1028F000C02048000000000000000000C020480088 -+:102900000000000000000000C0404800000000007F -+:1029100000000004002F0222000000000000000060 -+:102920000CC00000000003700001A2A400204411AC -+:1029300000000000000000000040480200000367A3 -+:1029400000000028002F022200000000000000000C -+:102950000CC00000000005BA0001A2A40020441130 -+:102960000000000000000000004048020000036773 -+:102970000000002C00203626000000000000004966 -+:1029800000201811000000000000003F0020481146 -+:10299000000000000000000100331A2600000000C3 -+:1029A00000000000002F02260000000000000000D0 -+:1029B0000CC00000000003760000002C00801A2DDF -+:1029C000000000000000003FC0280A2000000000B6 -+:1029D00000000015002F022200000000000000008F -+:1029E0000CE000000000038C00000006002F022213 -+:1029F00000000000000000000CE00000000003B731 -+:102A000000000016002F022200000000000000005D -+:102A10000CE00000000003B900000020002F02229B -+:102A200000000000000000000CE00000000003A215 -+:102A30000000000F002F0222000000000000000034 -+:102A40000CE00000000003AE00000010002F022286 -+:102A500000000000000000000CE00000000003AED9 -+:102A60000000001E002F02220000000000000000F5 -+:102A70000CE00000000003960000A2A40020441116 -+:102A800000000000000000000040480200000000BC -+:102A90000800000000290A220000000000000003D6 -+:102AA00040210E20000000000000000CC021122078 -+:102AB00000000000000800000028122400000000B0 -+:102AC00000000014C02216200000000000000000DA -+:102AD000002914A4000000000000A2A4002044115A -+:102AE0000000000000000000002948A200000000D3 -+:102AF0000000A1FE002044110000000000000000C2 -+:102B00000040480300000000810000000020441144 -+:102B1000000000000000000100204811000000003B -+:102B2000000021F800204411000000000000001601 -+:102B30000020481100000000000421F90060441149 -+:102B400000000622000000150021023000000000F5 -+:102B50000000000014E00000000003980000210EB7 -+:102B6000002044110000000000000000C0204800C8 -+:102B70000000000000000000C0204800000000002D -+:102B80000000A2A40020441100000000000000008A -+:102B900000404802000000008100000000204411B5 -+:102BA00000000000000000010020481100000000AB -+:102BB000000021F800204411000000000000001770 -+:102BC0000020481100000000000421F900604411B9 -+:102BD0000000062200000003002102300000000077 -+:102BE0000000000014E00000000003A40000210821 -+:102BF000002044110000000000000000C020480038 -+:102C00000000000000000000C0204800000000009C -+:102C10000000A2A4002044110000000000000000F9 -+:102C200000404802000000000000A2A4002044115F -+:102C3000000000000000000000204802000000002A -+:102C4000800000000020441100000000000000008F -+:102C50000020481100000000810000000020441105 -+:102C600000000000000000100020481100000000DB -+:102C70000000000000200010000000000000000024 -+:102C800014C00000000003B4000000000040000079 -+:102C9000000000000001A2A4002044110000000078 -+:102CA0000000000600404811000000000001A2A43E -+:102CB00000204411000000000000001600604811D0 -+:102CC000000003740000000000400000000000004D -+:102CD00000000000C020080000000000000000000C -+:102CE000C0200C00000000000000001D0021022395 -+:102CF000000000000000000014E00000000003CE0F -+:102D000081000000002044110000000000000001CC -+:102D10000020481100000000000021F800204411AC -+:102D20000000000000000018002048110000000012 -+:102D3000000421F900604411000006220000001187 -+:102D400000210230000000000000000014E000003C -+:102D5000000003C200002100002044110000000018 -+:102D600000000000002048020000000000000000F9 -+:102D70000020480300000000BABECAFE002048112F -+:102D800000000000CAFEBABE00204811000000008A -+:102D90000000A2A400204411000000000000000474 -+:102DA0000040481100000000000021700020441184 -+:102DB00000000000000000000020480200000000A9 -+:102DC0000000000000204803000000008100000017 -+:102DD00000204411000000000000000A00204811FB -+:102DE00000000000000000000020001000000000B3 -+:102DF0000000000014C00000000003D38C0000009D -+:102E00000020441100000000CAFEBABE0040481174 -+:102E100000000000810000000020441100000000BC -+:102E200000000001002048110000000000003FFFEA -+:102E300040280A20000000008000000040280E20EA -+:102E40000000000040000000C02812200000000028 -+:102E50000004000000694622000006220000000075 -+:102E6000002014100000000000000000002F0223CA -+:102E700000000000000000000CC00000000003E1A2 -+:102E800000000000C0401800000003E400003FFF05 -+:102E9000C0281A2000000000000400000069462637 -+:102EA00000000622000000000020181000000000B2 -+:102EB00000000000002F02240000000000000000BD -+:102EC0000CC00000000003E700000000C0401C0030 -+:102ED000000003EA00003FFFC0281E2000000000A1 -+:102EE00000040000006946270000062200000000E0 -+:102EF00000201C1000000000000000000020440220 -+:102F00000000000000000000002820C500000000B4 -+:102F100000000000004948E800000000A580000013 -+:102F200000200811000000000000200000200C110B -+:102F30000000000083000000006044110000041243 -+:102F4000000000000020440200000000000000001B -+:102F5000C0204800000000000000000040204800A1 -+:102F6000000000000000001FC0210220000000003F -+:102F70000000000014C00000000003F70000201053 -+:102F800000204411000000000000800000204811D3 -+:102F9000000000000000FFFFC0481220000003FFF7 -+:102FA000A780000000200811000000000000A00021 -+:102FB00000200C110000000083000000006044119C -+:102FC0000000041200000000002044020000000085 -+:102FD00000000000C02048000000000000000000C9 -+:102FE000C0204800000000000000FFFFC0281220A1 -+:102FF00000000000830000000020441100000000D9 -+:103000000000000000304883000000008400000041 -+:10301000002044110000000000000000C020480013 -+:1030200000000000000000001D0000000000000083 -+:103030008300000000604411000004120000000042 -+:10304000C040040000000001A98000000020081119 -+:10305000000000000000C00000400C11000003FA56 -+:10306000AB80000000200811000000000000F8E024 -+:1030700000400C11000003FAAD8000000020081190 -+:10308000000000000000F88000400C11000003FA6E -+:10309000B380000000200811000000000000F3FCD5 -+:1030A00000400C11000003FAAF800000002008115E -+:1030B000000000000000E00000400C11000003FAD6 -+:1030C000B180000000200811000000000000F000A6 -+:1030D00000400C11000003FA83000000002044119E -+:1030E00000000000000021480020481100000000FE -+:1030F00084000000002044110000000000000000D7 -+:10310000C020480000000000000000001D0000007A -+:10311000000000000000000000800000000000002F -+:1031200001182000C0304620000000000000000010 -+:10313000D90048000000000000000000C02004008A -+:10314000000000000000000000A0000A00000000D5 -+:103150000218A000C030462000000000000000005F -+:10316000D90048000000000000000000C02004005A -+:10317000000000000000000000A0000A00000000A5 -+:103180000318C000C030462000000000000000000E -+:10319000D90048000000000000000000C02004002A -+:1031A000000000000000000000A0000A0000000075 -+:1031B0000418F8E0C03046200000000000000000C5 -+:1031C000D90048000000000000000000C0200400FA -+:1031D000000000000000000000A0000A0000000045 -+:1031E0000518F880C03046200000000000000000F4 -+:1031F000D90048000000000000000000C0200400CA -+:10320000000000000000000000A0000A0000000014 -+:103210000618E000C030462000000000000000005A -+:10322000D90048000000000000000000C020040099 -+:10323000000000000000000000A0000A00000000E4 -+:103240000718F000C0304620000000000000000019 -+:10325000D90048000000000000000000C020040069 -+:10326000000000000000000000A0000A00000000B4 -+:103270000818F3FCC03046200000000000000000E9 -+:10328000D90048000000000000000000C020040039 -+:10329000000000000000000000A0000A0000000084 -+:1032A00000000033C0300A200000000000000000D1 -+:1032B000C0403440000000000000003000200A2D13 -+:1032C0000000000000000000C0290C4000000000C9 -+:1032D0000000003000203623000000000000000045 -+:1032E000C0200400000000000000000000A0000A50 -+:1032F00000000000860000000020441100000000D3 -+:1033000000000000004048010000000085000000AF -+:10331000C0204411000000000000000000404801EF -+:10332000000000000000217C00204411000000008B -+:1033300000000018402102200000000000000000F2 -+:1033400014C000000000044700800000C0494A206B -+:103350000000044800000000C020480000000000F9 -+:1033600000000000C0204800000000000000000035 -+:10337000C02048000000000081000000002044112F -+:1033800000000000000000010020481100000000C3 -+:1033900000000000C0200800000000000000000441 -+:1033A000002F0222000000000000000006E00000E4 -+:1033B000000004500000000400200811000000007C -+:1033C0000000000017000000000000000004217F42 -+:1033D00000604411000006220000001F002102309E -+:1033E000000000000000000014C000000000000009 -+:1033F0000000000000404C020000045000000000EB -+:10340000C0200C000000000000000000C0201000E0 -+:103410000000000000000000C020140000000000B8 -+:1034200000000000C02018000000000000000000A4 -+:10343000C0201C000000000000007F0000280A21BE -+:103440000000000000004500002F022200000000E4 -+:10345000000000000CE0000000000461000000001B -+:10346000C02020000000000000000004002F0228FF -+:10347000000000000000000006E000000000046101 -+:1034800000000004002020110000000000000000E7 -+:1034900017000000000000000000001000280A23B0 -+:1034A0000000000000000010002F022200000000B9 -+:1034B000000000000CE00000000004698100000032 -+:1034C000002044110000000000000001002048110D -+:1034D00000000000000400000069462400000622ED -+:1034E00000000000004000000000046E81000000A9 -+:1034F00000204411000000000000000000204811DE -+:10350000000000000000216D0020441100000000B8 -+:10351000000000000020480400000000000000003F -+:10352000006048050000062700000000002824F085 -+:10353000000000000000000700280A23000000002F -+:1035400000000001002F0222000000000000000027 -+:103550000AE000000000047500000000002F00C910 -+:10356000000000000000000004E000000000048EE5 -+:1035700000000000004000000000049B000000026A -+:10358000002F022200000000000000000AE00000FE -+:103590000000047A00000000002F00C900000000B5 -+:1035A0000000000002E000000000048E00000000A7 -+:1035B000004000000000049B00000003002F0222D6 -+:1035C00000000000000000000AE000000000047F8E -+:1035D00000000000002F00C90000000000000000F3 -+:1035E0000CE000000000048E00000000004000001D -+:1035F0000000049B00000004002F022200000000D5 -+:10360000000000000AE00000000004840000000048 -+:10361000002F00C900000000000000000AE00000C8 -+:103620000000048E00000000004000000000049B29 -+:1036300000000005002F0222000000000000000032 -+:103640000AE000000000048900000000002F00C90B -+:10365000000000000000000006E000000000048EF2 -+:1036600000000000004000000000049B0000000675 -+:10367000002F022200000000000000000AE000000D -+:103680000000048E00000000002F00C900000000B0 -+:103690000000000008E000000000048E00000000B0 -+:1036A000004000000000049B00007F0000280A2169 -+:1036B0000000000000004500002F02220000000072 -+:1036C000000000000AE00000000000000000000808 -+:1036D00000210A23000000000000000014C00000C8 -+:1036E000000004980000216900204411000000003F -+:1036F00000000000C02048000000000000000000A2 -+:10370000C02048000000000000000000C020480069 -+:1037100000000000CAFEBABE0040481100000000D0 -+:1037200000000000C0204400000000000000000075 -+:10373000C02000000000000000000000C040480061 -+:103740000000000000007F0000280A2100000000A7 -+:1037500000004500002F02220000000000000000D1 -+:103760000AE00000000004A100000000C0200000EA -+:103770000000000000000000C02000000000000069 -+:1037800000000000C0400000000000000000000039 -+:1037900000404C080000046100000000C020080048 -+:1037A000000000000000001040210E20000000007A -+:1037B0000000001140211220000000000000001253 -+:1037C0004021162000000000000021690020441163 -+:1037D000000000000000000000204802000000007F -+:1037E0000000000000210225000000000000000091 -+:1037F00014E00000000004AB00040000C0494A20AF -+:10380000000004ACFFFBFFFFC0284A2000000000BE -+:103810000000000000210223000000000000000062 -+:1038200014E00000000004B800000000C0204800C0 -+:103830000000000000000000C02048000000000060 -+:103840000000000000210224000000000000000031 -+:1038500014C000000000000081000000002044119E -+:10386000000000000000000C0020481100000000D3 -+:103870000000000000200010000000000000000018 -+:1038800014C00000000004B4A00000000020441197 -+:1038900000000000CAFEBABE00404811000000004F -+:1038A000810000000020441100000000000000041E -+:1038B00000204811000000000000216B002044118E -+:1038C0000000000000000000C020481000000000C0 -+:1038D00081000000002044110000000000000005ED -+:1038E00000204811000000000000216C002044115D -+:1038F0000000000000000000C02048100000000090 -+:1039000000000000002F0224000000000000000062 -+:103910000CE000000000000000000000004000007B -+:10392000000004B200000000C0210A2000000000D6 -+:103930000000000014C00000000004CB8100000063 -+:103940000020441100000000000000000020481189 -+:10395000000000000000216D002044110000000064 -+:1039600000000000C020480000000000000000002F -+:10397000C060480000000627000000000040000072 -+:10398000000004CF8100000000204411000000006E -+:1039900000000001002048110000000000040000A9 -+:1039A000C02946200000000000000000C0600000A8 -+:1039B0000000062200000001002102220000000099 -+:1039C0000000000014C00000000004D600002169BF -+:1039D000002044110000000000000000C02048004A -+:1039E0000000000000000000C020480000000000AF -+:1039F000000000000020481000000000CAFEBABE0F -+:103A0000004048110000000000000000C0204400F9 -+:103A10000000000000000000C0404810000000004E -+:103A2000810000000020441100000000000000019F -+:103A30000020481100000000000021F8002044117F -+:103A4000000000000000000E0020481100000000EF -+:103A5000000421F90060441100000622000000006B -+:103A600000210230000000000000000014C000002F -+:103A7000000004D800002180002044110000000054 -+:103A800000000000C020480000000000000000000E -+:103A9000C02000000000000000000000C02048001E -+:103AA0000000000000000000C02000000000000036 -+:103AB00000000000C04048000000000000000003BB -+:103AC00000333E2F00000000000000010021022111 -+:103AD000000000000000000014E0000000000508E5 -+:103AE0000000002C00200A2D00000000000400004F -+:103AF00018E00C11000004F70000000100333E2F15 -+:103B000000000000000021690020441100000000B6 -+:103B1000000000000020480200000000000000003B -+:103B200000204803000000000000000800300A22C6 -+:103B30000000000000000000C0204800000000005D -+:103B400000000000C02048000000000000002169C3 -+:103B50000020441100000000000000000020480286 -+:103B600000000000000000000020480300000000EA -+:103B70000000000800300A220000000000000000E1 -+:103B8000C02048000000000000000000D8C048002D -+:103B9000000004EB00002169002044110000000037 -+:103BA00000000000002048020000000000000000AB -+:103BB00000204803000000000000000800300A2236 -+:103BC0000000000000000000C020480000000000CD -+:103BD00000000000C0204800000000000000002D90 -+:103BE0000020122D000000000000000000290C83BE -+:103BF00000000000000021690020441100000000C6 -+:103C0000000000000020480200000000000000004A -+:103C100000204803000000000000000800300A22D5 -+:103C20000000000000000000C0204800000000006C -+:103C300000000000C020480000000000000000114B -+:103C400000210224000000000000000014C0000059 -+:103C5000000000000000000000400000000004B26E -+:103C60000000002CC0203620000000000000002DC5 -+:103C7000C0403620000000000000000F002102219B -+:103C8000000000000000000014C000000000050D4E -+:103C900000000000006000000000000B00000000B9 -+:103CA000D90000000000000000000000C040040037 -+:103CB00000000001B50000000020441100000000D9 -+:103CC000000020000020481100000000B6000000A5 -+:103CD00000204411000000000000A0000020481156 -+:103CE00000000000B70000000020441100000000A8 -+:103CF0000000C0000020481100000000B8000000D3 -+:103D000000204411000000000000F8E000204811ED -+:103D100000000000B9000000002044110000000075 -+:103D20000000F8800020481100000000BA000000E8 -+:103D300000204411000000000000E00000204811B5 -+:103D400000000000BB000000002044110000000043 -+:103D50000000F0000020481100000000BC0000003E -+:103D600000204411000000000000F3FC0020481176 -+:103D7000000000008100000000204411000000004D -+:103D8000000000020020481100000000000000FFB9 -+:103D900000280E300000000000000000002F022369 -+:103DA00000000000000000000CC000000000052121 -+:103DB00000000000C020080000000000000000001B -+:103DC00014C00000000005360000000000200C11A7 -+:103DD000000000000000001C00203623000000004E -+:103DE0000000002B00203623000000000000002906 -+:103DF00000203623000000000000002800203623A9 -+:103E00000000000000000017002036230000000022 -+:103E100000000025002036230000000000000026DE -+:103E2000002036230000000000000015002036238B -+:103E300000000000000000160020362300000000F3 -+:103E4000FFFFE00000200C11000000000000002136 -+:103E5000002036230000000000000022002036234E -+:103E60000000000000001FFF00200C1100000000F7 -+:103E70000000002300203623000000000000002482 -+:103E80000020362300000000F1FFFFFF00283A2E3B -+:103E9000000000000000001AC0220E2000000000F8 -+:103EA000000000000029386E0000000081000000C2 -+:103EB000002044110000000000000006002048110E -+:103EC000000000000000002A402036200000000012 -+:103ED00087000000002044110000000000000000E6 -+:103EE000C0204800000000000000A1F400204411A0 -+:103EF000000000000000000000204810000000004A -+:103F00009D00000000204411000000000000001F80 -+:103F100040214A20000000009600000000204411CB -+:103F20000000000000000000C02048000000000069 -+:103F300000000000C0200C00000000000000000095 -+:103F4000C0201000000000000000001F0021162407 -+:103F5000000000000000000014C00000000000008D -+:103F60000000001D002036230000000000000003B8 -+:103F700000281E2300000000000000080022222369 -+:103F800000000000FFFFF0000028222800000000D1 -+:103F900000000000002920E8000000000000001FD1 -+:103FA00000203628000000000000001800211E2319 -+:103FB0000000000000000020002036270000000064 -+:103FC0000000000200221624000000000000000093 -+:103FD000003014A8000000000000001E002036255C -+:103FE000000000000000000300211A24000000006F -+:103FF0001000000000281A2600000000EFFFFFFF5D -+:1040000000283A2E0000000000000000004938CED1 -+:10401000000006100000000140280A2000000000F7 -+:104020000000000640280E200000000000000300F1 -+:10403000C028122000000000000000080021122407 -+:104040000000000000000000C0201620000000005A -+:1040500000000000C0201A20000000000000000046 -+:1040600000210222000000000000000014C0000037 -+:104070000000056C810000000020441100000000D9 -+:10408000000000010020481100000000000022583C -+:1040900000300A24000000000004000000694622ED -+:1040A00000000622000021690020441100000000E9 -+:1040B0000000000000204805000000000002000091 -+:1040C00000294A26000000000000000000204810DF -+:1040D00000000000CAFEBABE002048110000000027 -+:1040E00000000002002F022300000000000000007A -+:1040F0000CC000000000057400000000C0201C106F -+:104100000000000000000000C04000000000058228 -+:1041100000000002002F0223000000000000000049 -+:104120000CC0000000000574810000000020441154 -+:104130000000000000000001002048110000000005 -+:104140000000225800300A24000000000004000093 -+:10415000006946220000062200000000C0201C105A -+:104160000000000000000000C040000000000582C8 -+:1041700000000000002F02230000000000000000EB -+:104180000CC000000000057800000000C0201C00EA -+:104190000000000000000000C04000000000058298 -+:1041A00000000004002F02230000000000000000B7 -+:1041B0000CC00000000005808100000000204411B8 -+:1041C0000000000000000000002048110000000076 -+:1041D0000000216D002044110000000000000000DC -+:1041E000C02048000000000000000000C06048003F -+:1041F000000006270000000000401C10000005829F -+:1042000000000000C02000000000000000000000CE -+:10421000C040000000000000000000000EE00000B0 -+:10422000000005840000000000600000000005C3DD -+:1042300000000000002F0224000000000000000029 -+:104240000CC00000000005920000A2B7002044113D -+:1042500000000000000000000020480700000000EF -+:10426000000000330020262D000000000000001A8E -+:10427000002122290000000000000006002226295B -+:10428000000000000000A2C4002044110000000053 -+:1042900000000000003048E90000000000000000BD -+:1042A00000E00000000005900000A2D100204411B1 -+:1042B000000000000000000000404808000000006E -+:1042C0000000A2D100204411000000000000000105 -+:1042D00000504A280000000000000001002F0224C6 -+:1042E00000000000000000000CC00000000005A05D -+:1042F0000000A2BB002044110000000000000000EC -+:104300000020480700000000000000340020262D97 -+:10431000000000000000001A002122290000000017 -+:104320000000000600222629000000000000A2C5AF -+:10433000002044110000000000000000003048E9A7 -+:10434000000000000000000000E000000000059EEA -+:104350000000A2D200204411000000000000000074 -+:1043600000404808000000000000A2D200204411D4 -+:10437000000000000000000100504A28000000007A -+:1043800000000002002F02240000000000000000D6 -+:104390000CC00000000005AE0000A2BF00204411C8 -+:1043A000000000000000000000204807000000009E -+:1043B000000000350020262D000000000000001A3B -+:1043C000002122290000000000000006002226290A -+:1043D000000000000000A2C6002044110000000000 -+:1043E00000000000003048E900000000000000006C -+:1043F00000E00000000005AC0000A2D30020441142 -+:10440000000000000000000000404808000000001C -+:104410000000A2D3002044110000000000000001B1 -+:1044200000504A28000000000000A2C300204411F0 -+:10443000000000000000000000204807000000000D -+:10444000000000360020262D000000000000001AA9 -+:104450000021222900000000000000060022262979 -+:10446000000000000000A2C700204411000000006E -+:1044700000000000003048E90000000000000000DB -+:1044800000E00000000005B80000A2D400204411A4 -+:10449000000000000000000000404808000000008C -+:1044A0000000A2D400204411000000000000000120 -+:1044B00000504A2800000000850000000020441140 -+:1044C0000000000000000000002048010000000083 -+:1044D0000000304A002044110000000001000000EC -+:1044E0000020481100000000000000000040000013 -+:1044F000000005BEA4000000C02044110000000020 -+:1045000000000000C0404800000000000000000063 -+:10451000C0600000000005C300000000C0400400AF -+:10452000000000010001A2A40020441100000000CE -+:104530000000003F00204811000000000000003F84 -+:1045400000204811000000000000003F002048113A -+:10455000000000000000003F0020481100000000A3 -+:104560000000000500204811000000000000A1F438 -+:10457000002044110000000000000000002048114D -+:10458000000000008800000000204411000000002E -+:10459000000000010020481100000000FF000000A2 -+:1045A000002044110000000000000000002048111D -+:1045B0000000000000000001002048110000000081 -+:1045C0000000000200804811000000000000000010 -+:1045D0000EE00000000005D60000100000200811C9 -+:1045E000000000000000002B002036220000000028 -+:1045F0000000000000600000000005DA000000007C -+:1046000000600000000005C3980000000020441175 -+:1046100000000000000000000080481100000000C1 -+:1046200000000000C0600000000005DA000000008B -+:10463000C0400400000000010000A2A400204411BA -+:1046400000000000000000220020481100000000CF -+:10465000890000000020441100000000000000015B -+:1046600000404811000005CD9700000000204411D3 -+:1046700000000000000000000020481100000000C1 -+:104680008A0000000020441100000000000000002B -+:1046900000404811000005CD00000000006000004F -+:1046A000000005F30001A2A4C02044110000000096 -+:1046B0000000001600604811000003740000201084 -+:1046C00000204411000000000001000000204811FB -+:1046D00000000000810000000020441100000000E4 -+:1046E0000000000100204811000000000000217CB3 -+:1046F0000020441100000000098000000020481143 -+:1047000000000000FFFFFFFF002048110000000034 -+:104710000000000000204811000000000000000020 -+:1047200017000000000000000004217F0060441119 -+:10473000000006220000001F0021023000000000DF -+:104740000000000014C00000000000000000000491 -+:1047500000404C11000005ED00000000004000008A -+:10476000000000000000001700201E2D00000000C7 -+:104770000000000400291E270000000000000017B0 -+:1047800000803627000000000000001700201E2DCA -+:1047900000000000FFFFFFFB00281E2700000000B4 -+:1047A00000000017008036270000000000000017FE -+:1047B00000201E2D000000000000000800291E2718 -+:1047C00000000000000000170080362700000000F5 -+:1047D0000000001700201E2D00000000FFFFFFF763 -+:1047E00000281E2700000000000000170080362768 -+:1047F000000000000001A2A40020441100000000FD -+:104800000000001600604811000003740000201032 -+:1048100000204411000000000001000000204811A9 -+:10482000000000000000217C002044110000000076 -+:10483000018000000020481100000000FFFFFFFF82 -+:104840000020481100000000000000000020481176 -+:104850000000000000000000170000000000000041 -+:104860008100000000204411000000000000000151 -+:1048700000204811000000000004217F0060441166 -+:10488000000006220000001F00210230000000008E -+:104890000000000014C0000000000621000000100D -+:1048A00000404C110000060700000000C02004007A -+:1048B000000000000000000038C000000000000000 -+:1048C0000000001D00200A2D000000000000001E56 -+:1048D00000200E2D000000000000001F0020122DFF -+:1048E00000000000000000200020162D0000000045 -+:1048F00000002169002044110000000000000000B9 -+:1049000000204804000000000000000000204805CE -+:10491000000000000000000000204801000000002E -+:10492000CAFEBABE002048110000000000000004CA -+:10493000003012240000000000000000002F00647E -+:1049400000000000000000000CC000000000062075 -+:104950000000000300281A220000000000000008E8 -+:104960000022122200000000FFFFF00000281224A5 -+:104970000000000000000000002910C4000000003A -+:104980000000001F0040362400000000000000006E -+:104990000080000000000000000000001AC00000BD -+:1049A000000006229F0000000020441100000000CB -+:1049B000CAFEBABE0020481100000000000000003E -+:1049C0001AE0000000000625000000000080000042 -+:1049D00000000000000000001AC0000000000627D0 -+:1049E0009E0000000020441100000000CAFEBABE74 -+:1049F0000020481100000000000000001AE0000044 -+:104A00000000062A000000000080000000000000F6 -+:104A100000000000006000000000000B000010001B -+:104A200000600411000003150000000000200411C4 -+:104A3000000000000000000000600811000001B24A -+:104A40000000225C00204411000000000000000370 -+:104A500000204811000000000000225600204411F0 -+:104A6000000000000000001B0020481100000000B2 -+:104A70000000A1FC00204411000000000000000123 -+:104A800000204811000000000001A1FDC0204411D9 -+:104A9000000000000000002100201E2D000000008A -+:104AA0000000001000221E2700000000000000246B -+:104AB0000020222D000000000000FFFF0028222817 -+:104AC000000000000000000000294907000000006D -+:104AD000000000000020481100000000000000223B -+:104AE0000020222D000000000000FFFF00282228E7 -+:104AF000000000000000000000294907000000003D -+:104B00000000000000204811000000000000002309 -+:104B100000201E2D000000000000001000221E27B3 -+:104B2000000000000000000000294907000000000C -+:104B300000000000004048110000000000000000DC -+:104B40000000000000000000000000000000000065 -+:104B50000000000000000000000000000000000055 -+:104B60000000000000000000000000000000000045 -+:104B70000000000000000000000000000000000035 -+:104B80000000000000000000000000000000000025 -+:104B90000000000000000000000000000000000015 -+:104BA0000000000000000000000000000000000005 -+:104BB00000000000000000000000000000000000F5 -+:104BC00000000000000000000000000000000000E5 -+:104BD00000000000000000000000000000000000D5 -+:104BE00000000000000000000000000000000000C5 -+:104BF00000000000000000000000000000000000B5 -+:104C000000000000000000000000000000000000A4 -+:104C10000000000000000000000000000000000094 -+:104C20000000000000000000000000000000000084 -+:104C30000000000000000000000000000000000074 -+:104C40000000000000000000000000000000000064 -+:104C50000000000000000000000000000000000054 -+:104C60000000000000000000000000000000000044 -+:104C70000000000000000000000000000000000034 -+:104C80000000000000000000000000000000000024 -+:104C90000000000000000000000000000000000014 -+:104CA0000000000000000000000000000000000004 -+:104CB00000000000000000000000000000000000F4 -+:104CC00000000000000000000000000000000000E4 -+:104CD00000000000000000000000000000000000D4 -+:104CE00000000000000000000000000000000000C4 -+:104CF00000000000000000000000000000000000B4 -+:104D000000000000000000000000000000000000A3 -+:104D10000000000000000000000000000000000093 -+:104D20000000000000000000000000000000000083 -+:104D30000000000000000000000000000000000073 -+:104D40000000000000000000000000000000000063 -+:104D50000000000000000000000000000000000053 -+:104D60000000000000000000000000000000000043 -+:104D70000000000000000000000000000000000033 -+:104D80000000000000000000000000000000000023 -+:104D90000000000000000000000000000000000013 -+:104DA0000000000000000000000000000000000003 -+:104DB00000000000000000000000000000000000F3 -+:104DC00000000000000000000000000000000000E3 -+:104DD00000000000000000000000000000000000D3 -+:104DE00000000000000000000000000000000000C3 -+:104DF00000000000000000000000000000000000B3 -+:104E000000000000000000000000000000000000A2 -+:104E10000000000000000000000000000000000092 -+:104E20000000000000000000000000000000000082 -+:104E30000000000000000000000000000000000072 -+:104E40000000000000000000000000000000000062 -+:104E50000000000000000000000000000000000052 -+:104E60000000000000000000000000000000000042 -+:104E70000000000000000000000000000000000032 -+:104E80000000000000000000000000000000000022 -+:104E90000000000000000000000000000000000012 -+:104EA0000000000000000000000000000000000002 -+:104EB00000000000000000000000000000000000F2 -+:104EC00000000000000000000000000000000000E2 -+:104ED00000000000000000000000000000000000D2 -+:104EE00000000000000000000000000000000000C2 -+:104EF00000000000000000000000000000000000B2 -+:104F000000000000000000000000000000000000A1 -+:104F10000000000000000000000000000000000091 -+:104F20000000000000000000000000000000000081 -+:104F30000000000000000000000000000000000071 -+:104F40000000000000000000000000000000000061 -+:104F50000000000000000000000000000000000051 -+:104F60000000000000000000000000000000000041 -+:104F70000000000000000000000000000000000031 -+:104F80000000000000000000000000000000000021 -+:104F90000000000000000000000000000000000011 -+:104FA0000000000000000000000000000000000001 -+:104FB00000000000000000000000000000000000F1 -+:104FC00000000000000000000000000000000000E1 -+:104FD00000000000000000000000000000000000D1 -+:104FE00000000000000000000000000000000000C1 -+:104FF00000000000000000000000000000000000B1 -+:1050000000000000000000000000000000000000A0 -+:105010000000000000000000000000000000000090 -+:105020000000000000000000000000000000000080 -+:105030000000000000000000000000000000000070 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B0000142050A05BA02500000000001C301685E -+:1052C000044105BA00000000022502090250015104 -+:1052D000000000000223024502A00241000000007D -+:1052E00003D705BA05BA05BA0000000005E205E3D8 -+:1052F000031F05BA00000000032005BF0320034A76 -+:105300000000000003340282034C033E0000000052 -+:1053100005BA05BA05BA05BA0000000005BA055776 -+:1053200005BA032A0000000003BC05BA04C3034EFB -+:105330000000000004A20455043F05BA000000006C -+:1053400004D805BA044304E5000000000455050F25 -+:10535000035B037B0000000005BA05BA05BA05BA75 -+:105360000000000005BA05BA05BA05BA0000000041 -+:1053700005BA05BA05D805C10000000005BA05BA8E -+:10538000000705BA0000000005BA05BA05BA05BA5B -+:105390000000000005BA05BA05BA05BA0000000011 -+:1053A00003F803ED0408040600000000040E040ADC -+:1053B000040C041000000000041C04180424042041 -+:1053C00000000000042C0428043404300000000015 -+:1053D00005BA05BA043A04380000000005BA05BA57 -+:1053E00005BA05BA0000000005BA05BA05BA05BA43 -+:1053F000000000000002060E062C0006000000005F -+:00000001FF -diff --git a/firmware/radeon/RS780_pfp.bin.ihex b/firmware/radeon/RS780_pfp.bin.ihex -new file mode 100644 -index 0000000..4088041 ---- /dev/null -+++ b/firmware/radeon/RS780_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001DB007C038B00D4401E00EE001E3C -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581CB00C41C3AE5 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFE000042C0800309002007D250055 -+:1000700000351402007D350B00255407007CD58027 -+:1000800000259C070095C00400D5001B007EDDC143 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA080000CA0C00008001DB30 -+:1001400000D4802400CA0800007C00C000C8142528 -+:1001500000C81824007C9488007C988000C20003AA -+:1001600000D40075007C744C0080006400D4401EF4 -+:1001700000CA180000D4401E00D5801E0080006216 -+:1001800000D4007500D4401E00CA080000CA0C004C -+:1001900000CA100000D4801900D4C01800D5001780 -+:1001A00000D4801E00D4C01E00D5001E00E2001E38 -+:1001B00000CA040000A00000007E828B00D40075FD -+:1001C00000D4401E00CA080000CA0C0000CA10007B -+:1001D00000D4801900D4C01800D5001700D4801EA8 -+:1001E00000D4C01E00D5001E00EE001E00CA040090 -+:1001F00000A00000007E828B00CA080000248C0151 -+:1002000000D480600094C0030004100100041002B8 -+:1002100000D5002500D4401E0080000000D4801EC0 -+:1002200000CA080000D4806100D4401E0080000095 -+:1002300000D4801E00CA080000CA0C0000D4401E72 -+:1002400000D4801600D4C01600D4801E008001DBCC -+:1002500000D4C01E00C6084300CA0C0000CA10002B -+:100260000094800400CA140000E420F300D420139A -+:1002700000D5606500D4E01C00D5201C00D5601CB2 -+:10028000008000000006200100C6084300CA0C00E0 -+:1002900000CA1000009483F700CA140000E420F3A1 -+:1002A0000080009C00D4201300C6084300CA0C0044 -+:1002B00000CA1000009883EF00CA140000D4006444 -+:1002C000008000B00000000000C4143200C61843D3 -+:1002D00000C4082F0095400500C40C3000D4401E17 -+:1002E0000080000000EE001E009583F500C4103170 -+:1002F00000D4403300D5206500D4A01C00D4E01CFD -+:1003000000D5201C00E4015E00D4001E0080000027 -+:100310000006200100CA1800000A200100D600765D -+:1003200000C408360098800700C6104500950110EB -+:1003300000D4001F00D460620080000000D420625E -+:1003400000CC383500CC1433008401DE00D40072B8 -+:1003500000D5401E0080000000EE001E00E2001AE2 -+:10036000008401DE00E2001A00CC104B00CC0447F0 -+:10037000002C9401007D098B00984005007D15CB71 -+:1003800000D4001A008001DB00D4006D0034440169 -+:1003900000CC0C480098403A00CC2C4A00958004D0 -+:1003A00000CC0449008001DB00D4001A00D4C01A3C -+:1003B000002828010084011300CC10030098801B42 -+:1003C0000004380C0084011300CC1003009880173F -+:1003D000000438080084011300CC10030098801337 -+:1003E000000438040084011300CC1003009880142A -+:1003F00000CC104C009A800900CC144D009840DCD1 -+:1004000000D4006D00CC184800D5001A00D5401A61 -+:10041000008000EC00D5801A0096C0D500D4006D95 -+:10042000008001DB00D4006E009AC00300D4006D90 -+:1004300000D4006E0080000000EC007F009AC0CC69 -+:1004400000D4006D008001DB00D4006E00CC1403EA -+:1004500000CC180300CC1C03007D9103007DD583E4 -+:10046000007D190C0035CC1F0035701F007CF0CBCF -+:10047000007CD08B00880000007E8E8B0095C0042D -+:1004800000D4006E008001DB00D4001A00D4C01A32 -+:1004900000CC080300CC0C0300CC100300CC1403E8 -+:1004A00000CC180300CC1C0300CC240300CC280390 -+:1004B0000035C41F0036B01F007C704B0034F01FA5 -+:1004C000007C704B0035701F007C704B007D888174 -+:1004D000007DCCC1007E5101007E9541007C908260 -+:1004E000007CD4C2007C848B009AC003007C8C8B7F -+:1004F000002C88010098809E00D4006D0098409CDC -+:1005000000D4006E00CC084C00CC0C4D00CC104840 -+:1005100000D4801A00D4C01A0080012400D5001A2B -+:1005200000CC083200D40032009482B600CA0C001D -+:1005300000D4401E0080000000D4001E00E4011E14 -+:1005400000D4001E00CA080000CA0C0000CA100037 -+:1005500000D4401E00CA140000D4801E00D4C01E67 -+:1005600000D5001E00D5401E00D54034008000009C -+:1005700000EE001E0028040400E2001A00E2001A47 -+:1005800000D4401A00CA380000CC080300CC0C0389 -+:1005900000CC0C0300CC0C030098829A00000000F1 -+:1005A000008401DE00D7A06F0080000000EE001F75 -+:1005B00000CA040000C2FF0000CC083400C13FFFA5 -+:1005C000007C74CB007CC90B007D010F0099028D6B -+:1005D000007C738B008401DE00D7A06F00800000D8 -+:1005E00000EE001F00CA080000281900007D898B5A -+:1005F000009580140028140400CA0C0000CA1000E2 -+:1006000000CA1C0000CA240000E2001F00D4C01A67 -+:1006100000D5001A00D5401A00CC180300CC2C03DA -+:1006200000CC2C0300CC2C03007DA58B007D9C47C7 -+:1006300000984274000000000080018400D4C01AB9 -+:1006400000D4401E00D4801E0080000000EE001E7A -+:1006500000E4011E00D4001E00D4401E00EE001E67 -+:1006600000CA040000A00000007E828B00E4013E6E -+:1006700000D4001E00D4401E00EE001E00CA04007C -+:1006800000A00000007E828B00CA080000248C06B7 -+:10069000000CCC060098C00600CC104E0099000457 -+:1006A00000D4007300E4011E00D4001E00D4401EDC -+:1006B00000D4801E0080000000EE001E00CA08006A -+:1006C00000CA0C000034D01800251001009500214C -+:1006D00000C17FFF00CA100000CA140000CA180041 -+:1006E00000D4801D00D4C01D007DB18B00C142022A -+:1006F00000C2C00100D5801D0034DC0E007D5D4CC1 -+:10070000007F734C00D7401E00D5001E00D5401E50 -+:1007100000C1420000C2C00000099C010031DC1091 -+:10072000007F5F4C007F734C00042802007D8380B3 -+:1007300000D5A86F00D5806600D7401E00EC005E93 -+:1007400000C8240200C82402008001DB00D6007625 -+:1007500000D4401E00D4801E00D4C01E00800000C3 -+:1007600000EE001E0080000000EE001F00D4001FFD -+:100770000080000000D4001F00D4001F008800008B -+:1007800000D4001F00000000000000000000000076 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:10080000000101940002019B000300B2000400A259 -+:10081000000500030006003F000700320008014FFA -+:1008200000090046000A0036001001D9001700C573 -+:100830000022015D0023016C002000D70024014844 -+:100840000026004D0027005C0028008D0029005183 -+:10085000002A007E002B0061002F0088003200AAD1 -+:10086000003401A20036006F003C0179003F009582 -+:10087000004101AF00440151005501960056019D11 -+:100880000060000B00610034006200380063003833 -+:1008900000640038006500380066003800670038E2 -+:1008A0000068003A00690041006A0048006B004897 -+:1008B000006C0048006D0048006E0048006F004862 -+:1008C000007301D9000000060000000600000006C9 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV610_me.bin.ihex b/firmware/radeon/RV610_me.bin.ihex -new file mode 100644 -index 0000000..ba19ed8 ---- /dev/null -+++ b/firmware/radeon/RV610_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A000006044110000068D0000000000600000A8 -+:1000B000000006310000000000600000000006455E -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:1006600000000000006000000000066800000000BC -+:10067000006000000000065C0000000200210E2265 -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE000000000000060000000000662000000003E -+:100AF00000400000000000EB00000000006000006B -+:100B000000000665000000070020222D0000000004 -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E90000000068D0000001F00210230000000004D -+:100EA0000000000014C000000000068C00000004D8 -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000068D000000110021023000000000FB -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000068C00000000002B140500000000B2 -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A000000000010000000000600000000006458B -+:1019B000000000000040040F0000021300000000BF -+:1019C0000060000000000631000000000060000020 -+:1019D000000006450000021000600411000003151D -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B100000600000000006310000A00C002044110D -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E300000042004006044110000068D0000000032 -+:101E4000006000000000063100000000C0600000DB -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000006680000000000600000000002B539 -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:102240000000065F0000000000400000000002DE09 -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A00000000970000000020441125 -+:102600000000000000000000002048110000000051 -+:102610008A000000002044110000000000000000BB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D0000001A1FD002044110000000000000000E6 -+:1026E000D90048000000000000000000C0200400E5 -+:1026F000000000000000000000A0000A0000000030 -+:1027000000002257002044110000000000000003D8 -+:10271000C0484A20000000000000225D0020441153 -+:102720000000000000000000C04048000000000061 -+:1027300000000000006000000000064500000000EE -+:10274000C0200800000000000000225C00204411AE -+:10275000000000000000000300384A2200000000D2 -+:102760000000A1FC00204411000000000000000057 -+:10277000C0204800000000000001A1FD002044111D -+:102780000000000000000000002F022200000000F6 -+:10279000000000000CE0000000000000000000004D -+:1027A00040204800000000000000000140304A20A6 -+:1027B0000000000000000002C0304A2000000000BD -+:1027C0000000000100530A220000034B0000003FFC -+:1027D000C0280A20000000008100000000204411F1 -+:1027E000000000000000000100204811000000006F -+:1027F000000021F800204411000000000000001833 -+:102800000020481100000000000421F9006044117C -+:102810000000068D000000110021023000000000C1 -+:102820000000000014E00000000003540000001449 -+:10283000002F022200000000000000000CC0000079 -+:10284000000003640000201000204411000000007C -+:102850000000800000204811000000000001A2A438 -+:102860000020441100000000000000000060480249 -+:102870000000036E00002100002044110000000051 -+:1028800000000000C0204800000000000000000020 -+:10289000C02048000000000000000000C0204800E8 -+:1028A0000000000000000000C040480000000000E0 -+:1028B00000000004002F02220000000000000000C1 -+:1028C0000CC000000000036A00002010002044112A -+:1028D00000000000000080000020481100000000FF -+:1028E0000001A2A40020441100000000000000002C -+:1028F000004048020000035F00000028002F022271 -+:1029000000000000000000000CC00000000005C036 -+:102910000001A2A4002044110000000000000000FB -+:10292000004048020000035F0000002C0020362613 -+:102930000000000000000049002018110000000005 -+:102940000000003F002048110000000000000001CE -+:1029500000331A260000000000000000002F0226AD -+:1029600000000000000000000CC000000000037028 -+:102970000000002C00801A2D000000000000003F25 -+:10298000C0280A200000000000000015002F0222CD -+:1029900000000000000000000CE0000000000386C2 -+:1029A00000000006002F02220000000000000000CE -+:1029B0000CE00000000003B100000016002F02220E -+:1029C00000000000000000000CE00000000003B563 -+:1029D00000000020002F0222000000000000000084 -+:1029E0000CE000000000039C0000000F002F0222FA -+:1029F00000000000000000000CE00000000003A840 -+:102A000000000010002F0222000000000000000063 -+:102A10000CE00000000003A80000001E002F0222AE -+:102A200000000000000000000CE000000000039027 -+:102A30000000A2A4002044110000000000000000DB -+:102A400000404802000000000800000000290A229F -+:102A5000000000000000000340210E2000000000E4 -+:102A60000000000CC021122000000000000800003F -+:102A7000002812240000000000000014C0221620CC -+:102A80000000000000000000002914A40000000065 -+:102A90000000A2A40020441100000000000000007B -+:102AA000002948A2000000000000A1FE00204411FF -+:102AB000000000000000000000404803000000008B -+:102AC000810000000020441100000000000000010F -+:102AD0000020481100000000000021F800204411EF -+:102AE0000000000000000016002048110000000057 -+:102AF000000421F9006044110000068D000000155B -+:102B000000210230000000000000000014E000007E -+:102B1000000003920000210E00204411000000007C -+:102B200000000000C020480000000000000000007D -+:102B3000C0204800000000000000A2A400204411B2 -+:102B400000000000000000000040480200000000FB -+:102B5000810000000020441100000000000000017E -+:102B60000020481100000000000021F8002044115E -+:102B700000000000000000170020481100000000C5 -+:102B8000000421F9006044110000068D00000003DC -+:102B900000210230000000000000000014E00000EE -+:102BA0000000039E000021080020441100000000E6 -+:102BB00000000000C02048000000000000000000ED -+:102BC000C0204800000000000000A2A40020441122 -+:102BD000000000000000000000404802000000006B -+:102BE0000000A2A40020441100000000000000002A -+:102BF0000020480200000000800000000020441176 -+:102C0000000000000000000000204811000000004B -+:102C100081000000002044110000000000000010AE -+:102C200000204811000000000000000000200010FB -+:102C3000000000000000000014C00000000003AE0F -+:102C40000000000000400000000000000000201014 -+:102C50000020441100000000000080000020481106 -+:102C6000000000000001A2A40020441100000000A8 -+:102C70000000000600404811000000000000201085 -+:102C800000204411000000000000800000204811D6 -+:102C9000000000000001A2A4002044110000000078 -+:102CA00000000016006048110000036E00000000E4 -+:102CB000004000000000000000000000C0200800EC -+:102CC0000000000000000000C0200C000000000018 -+:102CD0000000001D00210223000000000000000091 -+:102CE00014E00000000003CE810000000020441129 -+:102CF000000000000000000100204811000000005A -+:102D0000000021F80020441100000000000000181D -+:102D10000020481100000000000421F90060441167 -+:102D20000000068D000000110021023000000000AC -+:102D30000000000014E00000000003C000002100BB -+:102D400000204411000000000000000000204802A4 -+:102D50000000000000000000002048030000000008 -+:102D6000BABECAFE0020481100000000CAFEBABE6A -+:102D70000020481100000000000020100020441135 -+:102D8000000000000000800000204811000000004A -+:102D90000000A2A400204411000000000000000474 -+:102DA0000040481100000000000021700020441184 -+:102DB00000000000000000000020480200000000A9 -+:102DC0000000000000204803000000008100000017 -+:102DD00000204411000000000000000A00204811FB -+:102DE00000000000000000000020001000000000B3 -+:102DF0000000000014C00000000003D38C0000009D -+:102E00000020441100000000CAFEBABE0040481174 -+:102E100000000000810000000020441100000000BC -+:102E200000000001002048110000000000003FFFEA -+:102E300040280A20000000008000000040280E20EA -+:102E40000000000040000000C02812200000000028 -+:102E500000040000006946220000068D000000000A -+:102E6000002014100000000000000000002F0223CA -+:102E700000000000000000000CC00000000003E1A2 -+:102E800000000000C0401800000003E400003FFF05 -+:102E9000C0281A2000000000000400000069462637 -+:102EA0000000068D00000000002018100000000047 -+:102EB00000000000002F02240000000000000000BD -+:102EC0000CC00000000003E700000000C0401C0030 -+:102ED000000003EA00003FFFC0281E2000000000A1 -+:102EE00000040000006946270000068D0000000075 -+:102EF00000201C1000000000000000000020440220 -+:102F00000000000000000000002820C500000000B4 -+:102F100000000000004948E800000000A580000013 -+:102F200000200811000000000000200000200C110B -+:102F30000000000083000000006044110000041243 -+:102F4000000000000020440200000000000000001B -+:102F5000C0204800000000000000000040204800A1 -+:102F6000000000000000001FC0210220000000003F -+:102F70000000000014C00000000003F70000201053 -+:102F800000204411000000000000800000204811D3 -+:102F9000000000000000FFFFC0481220000003FFF7 -+:102FA000A780000000200811000000000000A00021 -+:102FB00000200C110000000083000000006044119C -+:102FC0000000041200000000002044020000000085 -+:102FD00000000000C02048000000000000000000C9 -+:102FE000C0204800000000000000FFFFC0281220A1 -+:102FF00000000000830000000020441100000000D9 -+:103000000000000000304883000000008400000041 -+:10301000002044110000000000000000C020480013 -+:1030200000000000000000001D0000000000000083 -+:103030008300000000604411000004120000000042 -+:10304000C040040000000001A98000000020081119 -+:10305000000000000000C00000400C11000003FA56 -+:10306000AB80000000200811000000000000F8E024 -+:1030700000400C11000003FAAD8000000020081190 -+:10308000000000000000F88000400C11000003FA6E -+:10309000B380000000200811000000000000F3FCD5 -+:1030A00000400C11000003FAAF800000002008115E -+:1030B000000000000000E00000400C11000003FAD6 -+:1030C000B180000000200811000000000000F000A6 -+:1030D00000400C11000003FA83000000002044119E -+:1030E00000000000000021480020481100000000FE -+:1030F00084000000002044110000000000000000D7 -+:10310000C020480000000000000000001D0000007A -+:10311000000000000000000000800000000000002F -+:1031200001182000C0304620000000000000000010 -+:10313000D90048000000000000000000C02004008A -+:10314000000000000000000000A0000A00000000D5 -+:103150000218A000C030462000000000000000005F -+:10316000D90048000000000000000000C02004005A -+:10317000000000000000000000A0000A00000000A5 -+:103180000318C000C030462000000000000000000E -+:10319000D90048000000000000000000C02004002A -+:1031A000000000000000000000A0000A0000000075 -+:1031B0000418F8E0C03046200000000000000000C5 -+:1031C000D90048000000000000000000C0200400FA -+:1031D000000000000000000000A0000A0000000045 -+:1031E0000518F880C03046200000000000000000F4 -+:1031F000D90048000000000000000000C0200400CA -+:10320000000000000000000000A0000A0000000014 -+:103210000618E000C030462000000000000000005A -+:10322000D90048000000000000000000C020040099 -+:10323000000000000000000000A0000A00000000E4 -+:103240000718F000C0304620000000000000000019 -+:10325000D90048000000000000000000C020040069 -+:10326000000000000000000000A0000A00000000B4 -+:103270000818F3FCC03046200000000000000000E9 -+:10328000D90048000000000000000000C020040039 -+:10329000000000000000000000A0000A0000000084 -+:1032A0000000003000200A2D000000000000000097 -+:1032B000C0290C4000000000000000300020362330 -+:1032C0000000000000000000C0200400000000001A -+:1032D0000000000000A0000A0000000086000000BE -+:1032E00000204411000000000000000000404801E0 -+:1032F0000000000085000000C02044110000000014 -+:103300000000000000404801000000000000217C97 -+:10331000002044110000000000000018402102209D -+:10332000000000000000000014C000000000044580 -+:1033300000800000C0494A20000004460000000050 -+:10334000C02048000000000000000000C02048002D -+:103350000000000000000000C02048000000000045 -+:103360008100000000204411000000000000000166 -+:10337000002048110000000000000000C0200800EC -+:103380000000000000000000170000000000000026 -+:103390000004217F006044110000068D0000001F22 -+:1033A00000210230000000000000000014C00000F6 -+:1033B000000000000000000000404C020000044B30 -+:1033C00000000000C0200C00000000000000000011 -+:1033D000C02010000000000000000000C020140009 -+:1033E0000000000000000000C020180000000000E5 -+:1033F00000000000C0201C000000000000007F0052 -+:1034000000280A210000000000004500002F0222D1 -+:1034100000000000000000000CE000000000045963 -+:1034200000000000C020200000000000000000009C -+:1034300017000000000000000000001000280A2310 -+:103440000000000000000010002F02220000000019 -+:10345000000000000CE0000000000461810000009A -+:10346000002044110000000000000001002048116D -+:103470000000000000040000006946240000068DE2 -+:103480000000000000400000000004668100000011 -+:10349000002044110000000000000000002048113E -+:1034A000000000000000216D002044110000000019 -+:1034B00000000000002048040000000000000000A0 -+:1034C000006048050000069200000000002824F07B -+:1034D000000000000000000700280A230000000090 -+:1034E00000000001002F0222000000000000000088 -+:1034F0000AE000000000046D00000000002F00C979 -+:10350000000000000000000004E00000000004864D -+:1035100000000000004000000000049300000002D2 -+:10352000002F022200000000000000000AE000005E -+:103530000000047200000000002F00C9000000001D -+:103540000000000002E0000000000486000000000F -+:10355000004000000000049300000003002F02223E -+:1035600000000000000000000AE0000000000477F6 -+:1035700000000000002F00C9000000000000000053 -+:103580000CE0000000000486000000000040000085 -+:103590000000049300000004002F0222000000003D -+:1035A000000000000AE000000000047C00000000B1 -+:1035B000002F00C900000000000000000AE0000029 -+:1035C000000004860000000000400000000004939A -+:1035D00000000005002F0222000000000000000093 -+:1035E0000AE000000000048100000000002F00C974 -+:1035F000000000000000000006E00000000004865B -+:1036000000000000004000000000049300000006DD -+:10361000002F022200000000000000000AE000006D -+:103620000000048600000000002F00C90000000018 -+:103630000000000008E00000000004860000000018 -+:10364000004000000000049300007F0000280A21D1 -+:103650000000000000004500002F022200000000D2 -+:10366000000000000AE00000000000000000000868 -+:1036700000210A23000000000000000014C0000028 -+:1036800000000490000021690020441100000000A7 -+:1036900000000000C0204800000000000000000002 -+:1036A000C02048000000000000000000C0204800CA -+:1036B00000000000CAFEBABE004048110000000031 -+:1036C00000000000C02044000000000000000000D6 -+:1036D000C02000000000000000000000C0404800C2 -+:1036E0000000000000007F0000280A210000000008 -+:1036F00000004500002F0222000000000000000032 -+:103700000AE000000000049900000000C020000052 -+:103710000000000000000000C020000000000000C9 -+:1037200000000000C0400000000000000000000099 -+:1037300000404C080000045900000000C0200800B0 -+:10374000000000000000001040210E2000000000DA -+:1037500000000011402112200000000000000012B3 -+:1037600040211620000000000000216900204411C3 -+:1037700000000000000000000020480200000000DF -+:1037800000000000002102250000000000000000F1 -+:1037900014E00000000004A300040000C0494A2017 -+:1037A000000004A4FFFBFFFFC0284A200000000027 -+:1037B00000000000002102230000000000000000C3 -+:1037C00014E00000000004B000000000C020480029 -+:1037D0000000000000000000C020480000000000C1 -+:1037E0000000000000210224000000000000000092 -+:1037F00014C00000000000008100000000204411FF -+:10380000000000000000000C002048110000000033 -+:103810000000000000200010000000000000000078 -+:1038200014C00000000004ACA000000000204411FF -+:1038300000000000CAFEBABE0040481100000000AF -+:10384000810000000020441100000000000000047E -+:1038500000204811000000000000216B00204411EE -+:103860000000000000000000C02048100000000020 -+:10387000810000000020441100000000000000054D -+:1038800000204811000000000000216C00204411BD -+:103890000000000000000000C020481000000000F0 -+:1038A00000000000002F02240000000000000000C3 -+:1038B0000CE00000000000000000000000400000DC -+:1038C000000004AA00000000C0210A20000000003F -+:1038D0000000000014C00000000004C381000000CC -+:1038E00000204411000000000000000000204811EA -+:1038F000000000000000216D0020441100000000C5 -+:1039000000000000C020480000000000000000008F -+:10391000C060480000000692000000000040000067 -+:10392000000004C7810000000020441100000000D6 -+:103930000000000100204811000000000004000009 -+:10394000C02946200000000000000000C060000008 -+:103950000000068D0000000100210222000000008E -+:103960000000000014C00000000004CE0000216927 -+:10397000002044110000000000000000C0204800AA -+:103980000000000000000000C0204800000000000F -+:10399000000000000020481000000000CAFEBABE6F -+:1039A000004048110000000000000000C02044005A -+:1039B0000000000000000000C040481000000000AF -+:1039C0008100000000204411000000000000000100 -+:1039D0000020481100000000000021F800204411E0 -+:1039E000000000000000000E002048110000000050 -+:1039F000000421F9006044110000068D0000000061 -+:103A000000210230000000000000000014C000008F -+:103A1000000004D0000021800020441100000000BC -+:103A200000000000C020480000000000000000006E -+:103A3000C02000000000000000000000C02048007E -+:103A40000000000000000000C02000000000000096 -+:103A500000000000C040480000000000000000031B -+:103A600000333E2F00000000000000010021022171 -+:103A7000000000000000000014E00000000005004D -+:103A80000000002C00200A2D0000000000040000AF -+:103A900018E00C11000004EF0000000100333E2F7D -+:103AA0000000000000002169002044110000000017 -+:103AB000000000000020480200000000000000009C -+:103AC00000204803000000000000000800300A2227 -+:103AD0000000000000000000C020480000000000BE -+:103AE00000000000C0204800000000000000216924 -+:103AF00000204411000000000000000000204802E7 -+:103B0000000000000000000000204803000000004A -+:103B10000000000800300A22000000000000000041 -+:103B2000C02048000000000000000000D8C048008D -+:103B3000000004E30000216900204411000000009F -+:103B4000000000000020480200000000000000000B -+:103B500000204803000000000000000800300A2296 -+:103B60000000000000000000C0204800000000002D -+:103B700000000000C0204800000000000000002DF0 -+:103B80000020122D000000000000000000290C831E -+:103B90000000000000002169002044110000000026 -+:103BA00000000000002048020000000000000000AB -+:103BB00000204803000000000000000800300A2236 -+:103BC0000000000000000000C020480000000000CD -+:103BD00000000000C02048000000000000000011AC -+:103BE00000210224000000000000000014C00000BA -+:103BF000000000000000000000400000000004AAD7 -+:103C00000000002CC0203620000000000000002D25 -+:103C1000C0403620000000000000000F00210221FB -+:103C2000000000000000000014C0000000000505B6 -+:103C300000000000006000000000000B0000000019 -+:103C4000D90000000000000000000000C040040097 -+:103C500000000001B5000000002044110000000039 -+:103C6000000020000020481100000000B600000005 -+:103C700000204411000000000000A00000204811B6 -+:103C800000000000B7000000002044110000000008 -+:103C90000000C0000020481100000000B800000033 -+:103CA00000204411000000000000F8E0002048114E -+:103CB00000000000B90000000020441100000000D6 -+:103CC0000000F8800020481100000000BA00000049 -+:103CD00000204411000000000000E0000020481116 -+:103CE00000000000BB0000000020441100000000A4 -+:103CF0000000F0000020481100000000BC0000009F -+:103D000000204411000000000000F3FC00204811D6 -+:103D100000000000810000000020441100000000AD -+:103D2000000000020020481100000000000000FF19 -+:103D300000280E300000000000000000002F0223C9 -+:103D400000000000000000000CC000000000051989 -+:103D500000000000C020080000000000000000007B -+:103D600014C000000000052E0000000000200C110F -+:103D7000000000000000001C0020362300000000AE -+:103D80000000002B00203623000000000000002966 -+:103D90000020362300000000000000280020362309 -+:103DA0000000000000000017002036230000000083 -+:103DB000000000250020362300000000000000263F -+:103DC00000203623000000000000001500203623EC -+:103DD0000000000000000016002036230000000054 -+:103DE000FFFFE00000200C11000000000000002197 -+:103DF00000203623000000000000002200203623AF -+:103E00000000000000001FFF00200C110000000057 -+:103E100000000023002036230000000000000024E2 -+:103E20000020362300000000F1FFFFFF00283A2E9B -+:103E3000000000000000001AC0220E200000000058 -+:103E4000000000000029386E000000008100000022 -+:103E5000002044110000000000000006002048116E -+:103E6000000000000000002A402036200000000072 -+:103E70008700000000204411000000000000000046 -+:103E8000C0204800000000000000A1F40020441100 -+:103E900000000000000000000020481000000000AA -+:103EA0000000000000200C110000000000000030A5 -+:103EB00000203623000000009D0000000020441177 -+:103EC000000000000000001F40214A200000000008 -+:103ED00096000000002044110000000000000000D7 -+:103EE000C02048000000000000000000C0200C00BE -+:103EF0000000000000000000C020100000000000D2 -+:103F00000000001F00211624000000000000000037 -+:103F100014C00000000000000000001D0020362337 -+:103F2000000000000000000300281E230000000025 -+:103F3000000000080022222300000000FFFFF00024 -+:103F4000002822280000000000000000002920E8CE -+:103F5000000000000000001F0020362800000000C4 -+:103F60000000001800211E230000000000000020B7 -+:103F70000020362700000000000000020022162466 -+:103F80000000000000000000003014A80000000045 -+:103F90000000001E00203625000000000000000385 -+:103FA00000211A24000000001000000000281A263A -+:103FB00000000000EFFFFFFF00283A2E0000000085 -+:103FC00000000000004938CE0000067B0000000120 -+:103FD00040280A20000000000000000640280E20B3 -+:103FE0000000000000000300C028122000000000B4 -+:103FF0000000000800211224000000000000000062 -+:10400000C02016200000000000000000C0201A2080 -+:10401000000000000000000000210222000000005B -+:104020000000000014C000000000056681000000D0 -+:104030000020441100000000000000010020481191 -+:10404000000000000000225800300A240000000098 -+:1040500000040000006946220000068D000021696E -+:10406000002044110000000000000000002048056E -+:10407000000000000002000000294A2600000000A5 -+:10408000000000000020481000000000CAFEBABE78 -+:10409000002048110000000000000002002F022351 -+:1040A00000000000000000000CC000000000056ED1 -+:1040B00000000000C0201C100000000000000000F4 -+:1040C000C04000000000057C00000002002F022319 -+:1040D00000000000000000000CC000000000056EA1 -+:1040E00081000000002044110000000000000001D9 -+:1040F00000204811000000000000225800300A246F -+:104100000000000000040000006946220000068D47 -+:1041100000000000C0201C10000000000000000093 -+:10412000C04000000000057C00000000002F0223BA -+:1041300000000000000000000CC00000000005723C -+:1041400000000000C0201C00000000000000000073 -+:10415000C04000000000057C00000004002F022386 -+:1041600000000000000000000CC000000000057A04 -+:104170008100000000204411000000000000000049 -+:1041800000204811000000000000216D00204411B3 -+:104190000000000000000000C020480000000000F7 -+:1041A00000000000C060480000000692000000000F -+:1041B00000401C100000057C00000000C020000032 -+:1041C0000000000000000000C040000000000000EF -+:1041D000000000000EE000000000057E000000006E -+:1041E00000600000000005C900000000002F02244C -+:1041F00000000000000000000CC000000000058F5F -+:104200000000A2B7002044110000000000000000E0 -+:104210000020480700000000810000000020441139 -+:104220000000000000000001002048110000000014 -+:104230000004A2B6006044110000068D0000001AC0 -+:10424000002122300000000000000006002226307D -+:104250000000000000042004006044110000068DEE -+:104260000000A2C400204411000000000000000073 -+:10427000003048E9000000000000000000E00000FD -+:104280000000058D0000A2D10020441100000000B4 -+:104290000000000000404808000000000000A2D11B -+:1042A00000204411000000000000000100504A28D6 -+:1042B0000000000000000001002F022400000000A8 -+:1042C000000000000CC00000000005A00000A2BB20 -+:1042D00000204411000000000000000000204807FA -+:1042E00000000000810000000020441100000000D8 -+:1042F0000000000100204811000000000004A2BAE4 -+:10430000006044110000068D0000001A00212230D8 -+:10431000000000000000000600222630000000001F -+:1043200000042004006044110000068D0000A2C5B6 -+:10433000002044110000000000000000003048E9A7 -+:10434000000000000000000000E000000000059EEA -+:104350000000A2D200204411000000000000000074 -+:1043600000404808000000000000A2D200204411D4 -+:10437000000000000000000100504A28000000007A -+:1043800000000002002F02240000000000000000D6 -+:104390000CC00000000005B10000A2BF00204411C5 -+:1043A000000000000000000000204807000000009E -+:1043B0008100000000204411000000000000000106 -+:1043C00000204811000000000004A2BE006044115B -+:1043D0000000068D0000001A0021223000000000BD -+:1043E0000000000600222630000000000004200427 -+:1043F000006044110000068D0000A2C60020441198 -+:104400000000000000000000003048E9000000004B -+:104410000000000000E00000000005AF0000A2D393 -+:104420000020441100000000000000000040480887 -+:10443000000000000000A2D3002044110000000092 -+:104440000000000100504A28000000000000A2C344 -+:104450000020441100000000000000000020480778 -+:104460000000000081000000002044110000000056 -+:104470000000000100204811000000000004A2C25A -+:10448000006044110000068D0000001A0021223057 -+:10449000000000000000000600222630000000009E -+:1044A00000042004006044110000068D0000A2C733 -+:1044B000002044110000000000000000003048E926 -+:1044C000000000000000000000E00000000005BE49 -+:1044D0000000A2D4002044110000000000000000F1 -+:1044E00000404808000000000000A2D40020441151 -+:1044F000000000000000000100504A2800000000F9 -+:1045000085000000002044110000000000000000B1 -+:1045100000204801000000000000304A0020441143 -+:104520000000000001000000002048110000000011 -+:104530000000000000400000000005C4A4000000CE -+:10454000C02044110000000000000000C0404800EE -+:104550000000000000000000C0600000000005C96D -+:1045600000000000C0400400000000010000002C1A -+:1045700000203621000000008100000000204411CE -+:1045800000000000000000060020481100000000AC -+:1045900000000000002F02300000000000000000BA -+:1045A0000CC00000000005D0000000000020041135 -+:1045B000000000000000003000403621000005E34C -+:1045C000000000300020062D0000000000007E00EA -+:1045D000002806210000000000000000002F02213A -+:1045E00000000000000000000CE00000000005E3F7 -+:1045F00081000000002044110000000000000001C4 -+:1046000000204811000000000004A0920060441146 -+:104610000000068D00000031002036300000000050 -+:104620000004A093006044110000068D00000032D9 -+:1046300000203630000000000004A2B600604411E3 -+:104640000000068D0000003300203630000000001E -+:104650000004A2BA006044110000068D000000347E -+:1046600000203630000000000004A2BE00604411AB -+:104670000000068D000000350020363000000000EC -+:104680000004A2C2006044110000068D0000003644 -+:1046900000203630000000000004200400604411B7 -+:1046A0000000068D0001A2A40020441100000000BB -+:1046B0000000003F00204811000000000000003F03 -+:1046C00000204811000000000000003F00204811B9 -+:1046D000000000000000003F002048110000000022 -+:1046E0000000000500204811000000000000A1F4B7 -+:1046F00000204411000000000000000000204811CC -+:1047000000000000880000000020441100000000AC -+:10471000000000010020481100000000810000009E -+:104720000020441100000000000000060020481195 -+:104730000000000000000001002F02300000000017 -+:10474000000000000CE000000000062C000000301B -+:104750000020062D0000000000000000002F0221B4 -+:1047600000000000000000000CE000000000062C2B -+:104770008100000000204411000000000000000142 -+:10478000002048110000000000007E0000280621E3 -+:104790000000000000000000002F022100000000C7 -+:1047A000000000000CE00000000006050000A092E0 -+:1047B00000204411000000000000003100204A2DBC -+:1047C000000000000000A093002044110000000041 -+:1047D0000000003200204A2D000000000000A2B6B8 -+:1047E00000204411000000000000003300204A2D8A -+:1047F000000000000000A2BA0020441100000000E8 -+:104800000000003400204A2D000000000000A2BE7D -+:1048100000204411000000000000003500204A2D57 -+:10482000000000000000A2C20020441100000000AF -+:104830000000003600204A2D00000000000000307B -+:104840000020062D00000000000001FF00280621C6 -+:104850000000000000000000002F02210000000006 -+:10486000000000000CE000000000062B000000002B -+:1048700000210221000000000000000014C0000020 -+:104880000000060E0004A003006044110000068D25 -+:104890000000A00300204411000000000000000000 -+:1048A0000020481000000000000000010021062147 -+:1048B000000000000000000014C00000000006130B -+:1048C0000004A010006044110000068D0000A0103C -+:1048D00000204411000000000000000000204810EB -+:1048E000000000000000000100210621000000007F -+:1048F00000000000002F0221000000000000000066 -+:104900000CE000000000062B0004A0110060441120 -+:104910000000068D0000A0110020441100000000DE -+:104920000000000000204810000000000004A01259 -+:10493000006044110000068D0000A0120020441108 -+:1049400000000000000000000020481000000000EF -+:104950000004A013006044110000068D0000A013A5 -+:10496000002044110000000000000000002048105A -+:10497000000000000004A014006044110000068D37 -+:104980000000A014002044110000000000000000FE -+:1049900000204810000000000004A0150060441131 -+:1049A0000000068D0000A01500204411000000004A -+:1049B0000000000000204810000000000004A016C5 -+:1049C000006044110000068D0000A0160020441174 -+:1049D000000000000000000000204810000000005F -+:1049E0000004A017006044110000068D0000A0170D -+:1049F00000204411000000000000000000204810CA -+:104A00000000000000042004006044110000068D36 -+:104A10000000002C0080062D00000000FF000000B8 -+:104A20000020441100000000000000000020481198 -+:104A300000000000000000010020481100000000FC -+:104A4000000000020080481100000000000000008B -+:104A50000EE000000000063D000000300020062DA2 -+:104A600000000000000000020028062100000000F5 -+:104A700000000000002F02210000000000000000E4 -+:104A80000CE000000000063B810000000020441103 -+:104A9000000000000000000100204811000000009C -+:104AA00000042004006044110000068D0000100086 -+:104AB00000200811000000000000002B002036221A -+:104AC000000000000000000000600000000006413F -+:104AD0000000000000600000000005C99800000010 -+:104AE0000020441100000000000000000080481178 -+:104AF0000000000000000000C0600000000006414F -+:104B000000000000C0400400000000010000A2A45A -+:104B10000020441100000000000000220020481185 -+:104B20000000000089000000002044110000000087 -+:104B300000000001004048110000062D9700000011 -+:104B40000020441100000000000000000020481177 -+:104B5000000000008A000000002044110000000056 -+:104B600000000000004048110000062D0000000079 -+:104B7000006000000000065C0000201000204411CE -+:104B8000000000000000800000204811000000002C -+:104B90000001A2A4C0204411000000000000001683 -+:104BA000006048110000036E000020100020441136 -+:104BB000000000000001000000204811000000007B -+:104BC00081000000002044110000000000000001EE -+:104BD00000204811000000000000217C002044114A -+:104BE00000000000098000000020481100000000C3 -+:104BF000FFFFFFFF00204811000000000000000040 -+:104C00000020481100000000000000001700000014 -+:104C1000000000000004217F006044110000068DA8 -+:104C20000000001F00210230000000000000000012 -+:104C300014C00000000000000000000400404C11FF -+:104C400000000656000000000040000000000000C8 -+:104C50000000001700201E2D0000000000000004CE -+:104C600000291E27000000000000001700803627E2 -+:104C7000000000000000001700201E2D00000000B2 -+:104C8000FFFFFFFB00281E270000000000000017A8 -+:104C900000803627000000000000001700201E2DB5 -+:104CA000000000000000000800291E27000000008E -+:104CB00000000017008036270000000000000017E9 -+:104CC00000201E2D00000000FFFFFFF700281E2718 -+:104CD00000000000000000170080362700000000E0 -+:104CE000000020100020441100000000000080009F -+:104CF00000204811000000000001A2A4002044117F -+:104D00000000000000000016006048110000036E63 -+:104D100000002010002044110000000000010000ED -+:104D200000204811000000000000217C00204411F8 -+:104D30000000000001800000002048110000000079 -+:104D4000FFFFFFFF002048110000000000000000EE -+:104D500000204811000000000000000017000000C3 -+:104D6000000000008100000000204411000000004D -+:104D70000000000100204811000000000004217F15 -+:104D8000006044110000068D0000001F0021023069 -+:104D9000000000000000000014C000000000068CAD -+:104DA0000000001000404C110000067200000000DE -+:104DB000C0200400000000000000000038C0000017 -+:104DC000000000000000001D00200A2D000000006F -+:104DD0000000001E00200E2D000000000000001F3B -+:104DE0000020122D00000000000000200020162DE1 -+:104DF00000000000000021690020441100000000B4 -+:104E00000000000000204804000000000000000036 -+:104E100000204805000000000000000000204801BC -+:104E200000000000CAFEBABE0020481100000000C9 -+:104E30000000000400301224000000000000000008 -+:104E4000002F006400000000000000000CC0000003 -+:104E50000000068B0000000300281A22000000005A -+:104E6000000000080022122200000000FFFFF000F6 -+:104E7000002812240000000000000000002910C4D7 -+:104E8000000000000000001F004036240000000069 -+:104E90000000000000800000000000000000000092 -+:104EA0001AC000000000068D9F0000000020441181 -+:104EB00000000000CAFEBABE002048110000000039 -+:104EC000000000001AE00000000006900000000052 -+:104ED0000080000000000000000000001AC0000078 -+:104EE000000006929E000000002044110000000017 -+:104EF000CAFEBABE002048110000000000000000F9 -+:104F00001AE000000000069500000000008000008C -+:104F10000000000000000000006000000000000B26 -+:104F200000001000006004110000031500000000E4 -+:104F300000200411000000000000000000600811C3 -+:104F4000000001B20000225C0020441100000000BB -+:104F5000000000030020481100000000000022565D -+:104F600000204411000000000000001B0020481138 -+:104F7000000000000000A1FC00204411000000001F -+:104F80000000000100204811000000000001A1FD08 -+:104F9000C0204411000000000000002100201E2D50 -+:104FA000000000000000001000221E27000000008A -+:104FB000000000240020222D000000000000FFFF60 -+:104FC00000282228000000000000000000294907F6 -+:104FD0000000000000000000002048110000000058 -+:104FE000000000220020222D000000000000FFFF32 -+:104FF00000282228000000000000000000294907C6 -+:105000000000000000000000002048110000000027 -+:105010000000002300201E2D0000000000000010F2 -+:1050200000221E27000000000000000000294907A0 -+:1050300000000000000000000040481100000000D7 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B0000142050205C002500000000001C3016860 -+:1052C000043F05C000000000022502090250015100 -+:1052D000000000000223024502A00241000000007D -+:1052E00003D705C005C005C0000000000649064AF6 -+:1052F000031F05C00000000005C005C503200340D2 -+:1053000000000000032A0282034203340000000070 -+:1053100005C005C005C005C00000000005C005515E -+:1053200005C005C00000000003BA05C004BB03446B -+:1053300000000000049A0450043D05C00000000075 -+:1053400004D005C0044104DD00000000045005073E -+:10535000035103750000000005C005C005C005C06D -+:105360000000000005C005C005C005C00000000029 -+:1053700005C005C0063F05C70000000005C005C008 -+:10538000000705C00000000005C005C005C005C03D -+:105390000000000005C005C005C005C000000000F9 -+:1053A00003F803ED0408040600000000040E040ADC -+:1053B000040C041000000000041C04180424042041 -+:1053C00000000000042C0428043404300000000015 -+:1053D00005C005C0043805C00000000005C005C0B8 -+:1053E00005C005C00000000005C005C005C005C01F -+:1053F0000000000000020679069700060000000089 -+:00000001FF -diff --git a/firmware/radeon/RV610_pfp.bin.ihex b/firmware/radeon/RV610_pfp.bin.ihex -new file mode 100644 -index 0000000..f55292c ---- /dev/null -+++ b/firmware/radeon/RV610_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001B8007C038B00D4401E00EE001E5F -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581A800C41C3A08 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFF000042C0400309002007D250049 -+:1000700000351402007D350B00255403007CD5802B -+:1000800000259C030095C00400D5001B007EDDC147 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA180000D4401E00D5801EAD -+:100140000080005300D4007500D4401E00CA08008F -+:1001500000CA0C0000CA100000D4801900D4C018D6 -+:1001600000D5001700D4801E00D4C01E00D5001E8C -+:1001700000E2001E00CA040000A00000007E828B86 -+:1001800000CA080000D4806000D4401E0080000037 -+:1001900000D4801E00CA080000D4806100D4401E34 -+:1001A0000080000000D4801E00CA080000CA0C00B5 -+:1001B00000D4401E00D4801600D4C01600D4801E87 -+:1001C000008001B800D4C01E00C6084300CA0C005D -+:1001D00000CA10000094800400CA140000E420F358 -+:1001E00000D4201300D5606500D4E01C00D5201C8D -+:1001F00000D5601C008000000006200100C60843F6 -+:1002000000CA0C0000CA1000009483F700CA140052 -+:1002100000E420F30080007900D4201300C60843D6 -+:1002200000CA0C0000CA1000009883EF00CA140036 -+:1002300000D400640080008D0000000000C414326F -+:1002400000C6184300C4082F0095400500C40C30B8 -+:1002500000D4401E0080000000EE001E009583F5D3 -+:1002600000C4103100D4403300D5206500D4A01C58 -+:1002700000D4E01C00D5201C00E4015E00D4001E68 -+:10028000008000000006200100CA1800000A2001BA -+:1002900000D6007600C408360098800700C61045D6 -+:1002A0000095011000D4001F00D46062008000009F -+:1002B00000D4206200CC383500CC1433008401BB5C -+:1002C00000D4007200D5401E0080000000EE001E29 -+:1002D00000E2001A008401BB00E2001A00CC104BBF -+:1002E00000CC0447002C9401007D098B0098400548 -+:1002F000007D15CB00D4001A008001B800D4006D39 -+:100300000034440100CC0C480098403A00CC2C4A00 -+:100310000095800400CC0449008001B800D4001A84 -+:1003200000D4C01A00282801008400F000CC10037B -+:100330000098801B0004380C008400F000CC1003EF -+:100340000098801700043808008400F000CC1003E7 -+:100350000098801300043804008400F000CC1003DF -+:100360000098801400CC104C009A800900CC144DE9 -+:10037000009840DC00D4006D00CC184800D5001A6D -+:1003800000D5401A008000C900D5801A0096C0D55B -+:1003900000D4006D008001B800D4006E009AC00344 -+:1003A00000D4006D00D4006E0080000000EC007FDF -+:1003B000009AC0CC00D4006D008001B800D4006E5B -+:1003C00000CC140300CC180300CC1C03007D910367 -+:1003D000007DD583007D190C0035CC1F0035701FC2 -+:1003E000007CF0CB007CD08B00880000007E8E8BE0 -+:1003F0000095C00400D4006E008001B800D4001A3B -+:1004000000D4C01A00CC080300CC0C0300CC1003AD -+:1004100000CC140300CC180300CC1C0300CC240334 -+:1004200000CC28030035C41F0036B01F007C704B81 -+:100430000034F01F007C704B0035701F007C704B47 -+:10044000007D8881007DCCC1007E5101007E9541F8 -+:10045000007C9082007CD4C2007C848B009AC00314 -+:10046000007C8C8B002C88010098809E00D4006D4D -+:100470000098409C00D4006E00CC084C00CC0C4D81 -+:1004800000CC104800D4801A00D4C01A00800101AA -+:1004900000D5001A00CC083200D40032009482D972 -+:1004A00000CA0C0000D4401E0080000000D4001ED2 -+:1004B00000E4011E00D4001E00CA080000CA0C009F -+:1004C00000CA100000D4401E00CA140000D4801ED0 -+:1004D00000D4C01E00D5001E00D5401E00D54034FB -+:1004E0000080000000EE001E0028040400E2001A54 -+:1004F00000E2001A00D4401A00CA380000CC0803F9 -+:1005000000CC0C0300CC0C0300CC0C03009882BD83 -+:1005100000000000008401BB00D7A06F0080000035 -+:1005200000EE001F00CA040000C2FF0000CC083427 -+:1005300000C13FFF007C74CB007CC90B007D010F24 -+:10054000009902B0007C738B008401BB00D7A06FC0 -+:100550000080000000EE001F00CA080000281900FB -+:10056000007D898B009580140028140400CA0C00BB -+:1005700000CA100000CA1C0000CA240000E2001FCC -+:1005800000D4C01A00D5001A00D5401A00CC1803B8 -+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -+:1005A000007D9C4700984297000000000080016198 -+:1005B00000D4C01A00D4401E00D4801E0080000069 -+:1005C00000EE001E00E4011E00D4001E00D4401EF8 -+:1005D00000EE001E00CA040000A00000007E828B16 -+:1005E00000E4013E00D4001E00D4401E00EE001EB8 -+:1005F00000CA040000A00000007E828B00CA080030 -+:1006000000248C06000CCC060098C00600CC104ECE -+:100610000099000400D4007300E4011E00D4001E01 -+:1006200000D4401E00D4801E0080000000EE001E9A -+:1006300000CA080000CA0C000034D01800251001C0 -+:100640000095002100C17FFF00CA100000CA1400FD -+:1006500000CA180000D4801D00D4C01D007DB18BDD -+:1006600000C1420200C2C00100D5801D0034DC0E72 -+:10067000007D5D4C007F734C00D7401E00D5001EEE -+:1006800000D5401E00C1420000C2C00000099C010C -+:100690000031DC10007F5F4C007F734C00042802A7 -+:1006A000007D838000D5A86F00D5806600D7401EEE -+:1006B00000EC005E00C8240200C82402008001B8DB -+:1006C00000D6007600D4401E00D4801E00D4C01E88 -+:1006D0000080000000EE001E0080000000EE001F01 -+:1006E00000D4001F0080000000D4001F00D4001FB1 -+:1006F0000088000000D4001F00000000000000007F -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:1008000000010171000201780003008F0004007FE5 -+:10081000000500030006003F000700320008012C1D -+:1008200000090046000A0036001001B6001700A2B9 -+:100830000022013A00230149002000B400240125D0 -+:100840000027004D0028006A002A0060002B00529B -+:10085000002F0065003200870034017F003C015604 -+:10086000003F00720041018C0044012E00550173CD -+:100870000056017A0060000B00610034006200380D -+:1008800000630038006400380065003800660038F6 -+:10089000006700380068003A00690041006A0048BB -+:1008A000006B0048006C0048006D0048006E004876 -+:1008B000006F00480000000600000006000000066F -+:1008C0000000000600000006000000060000000610 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV620_me.bin.ihex b/firmware/radeon/RV620_me.bin.ihex -new file mode 100644 -index 0000000..ba19ed8 ---- /dev/null -+++ b/firmware/radeon/RV620_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A000006044110000068D0000000000600000A8 -+:1000B000000006310000000000600000000006455E -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:1006600000000000006000000000066800000000BC -+:10067000006000000000065C0000000200210E2265 -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE000000000000060000000000662000000003E -+:100AF00000400000000000EB00000000006000006B -+:100B000000000665000000070020222D0000000004 -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E90000000068D0000001F00210230000000004D -+:100EA0000000000014C000000000068C00000004D8 -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000068D000000110021023000000000FB -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000068C00000000002B140500000000B2 -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A000000000010000000000600000000006458B -+:1019B000000000000040040F0000021300000000BF -+:1019C0000060000000000631000000000060000020 -+:1019D000000006450000021000600411000003151D -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B100000600000000006310000A00C002044110D -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E300000042004006044110000068D0000000032 -+:101E4000006000000000063100000000C0600000DB -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000006680000000000600000000002B539 -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:102240000000065F0000000000400000000002DE09 -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A00000000970000000020441125 -+:102600000000000000000000002048110000000051 -+:102610008A000000002044110000000000000000BB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D0000001A1FD002044110000000000000000E6 -+:1026E000D90048000000000000000000C0200400E5 -+:1026F000000000000000000000A0000A0000000030 -+:1027000000002257002044110000000000000003D8 -+:10271000C0484A20000000000000225D0020441153 -+:102720000000000000000000C04048000000000061 -+:1027300000000000006000000000064500000000EE -+:10274000C0200800000000000000225C00204411AE -+:10275000000000000000000300384A2200000000D2 -+:102760000000A1FC00204411000000000000000057 -+:10277000C0204800000000000001A1FD002044111D -+:102780000000000000000000002F022200000000F6 -+:10279000000000000CE0000000000000000000004D -+:1027A00040204800000000000000000140304A20A6 -+:1027B0000000000000000002C0304A2000000000BD -+:1027C0000000000100530A220000034B0000003FFC -+:1027D000C0280A20000000008100000000204411F1 -+:1027E000000000000000000100204811000000006F -+:1027F000000021F800204411000000000000001833 -+:102800000020481100000000000421F9006044117C -+:102810000000068D000000110021023000000000C1 -+:102820000000000014E00000000003540000001449 -+:10283000002F022200000000000000000CC0000079 -+:10284000000003640000201000204411000000007C -+:102850000000800000204811000000000001A2A438 -+:102860000020441100000000000000000060480249 -+:102870000000036E00002100002044110000000051 -+:1028800000000000C0204800000000000000000020 -+:10289000C02048000000000000000000C0204800E8 -+:1028A0000000000000000000C040480000000000E0 -+:1028B00000000004002F02220000000000000000C1 -+:1028C0000CC000000000036A00002010002044112A -+:1028D00000000000000080000020481100000000FF -+:1028E0000001A2A40020441100000000000000002C -+:1028F000004048020000035F00000028002F022271 -+:1029000000000000000000000CC00000000005C036 -+:102910000001A2A4002044110000000000000000FB -+:10292000004048020000035F0000002C0020362613 -+:102930000000000000000049002018110000000005 -+:102940000000003F002048110000000000000001CE -+:1029500000331A260000000000000000002F0226AD -+:1029600000000000000000000CC000000000037028 -+:102970000000002C00801A2D000000000000003F25 -+:10298000C0280A200000000000000015002F0222CD -+:1029900000000000000000000CE0000000000386C2 -+:1029A00000000006002F02220000000000000000CE -+:1029B0000CE00000000003B100000016002F02220E -+:1029C00000000000000000000CE00000000003B563 -+:1029D00000000020002F0222000000000000000084 -+:1029E0000CE000000000039C0000000F002F0222FA -+:1029F00000000000000000000CE00000000003A840 -+:102A000000000010002F0222000000000000000063 -+:102A10000CE00000000003A80000001E002F0222AE -+:102A200000000000000000000CE000000000039027 -+:102A30000000A2A4002044110000000000000000DB -+:102A400000404802000000000800000000290A229F -+:102A5000000000000000000340210E2000000000E4 -+:102A60000000000CC021122000000000000800003F -+:102A7000002812240000000000000014C0221620CC -+:102A80000000000000000000002914A40000000065 -+:102A90000000A2A40020441100000000000000007B -+:102AA000002948A2000000000000A1FE00204411FF -+:102AB000000000000000000000404803000000008B -+:102AC000810000000020441100000000000000010F -+:102AD0000020481100000000000021F800204411EF -+:102AE0000000000000000016002048110000000057 -+:102AF000000421F9006044110000068D000000155B -+:102B000000210230000000000000000014E000007E -+:102B1000000003920000210E00204411000000007C -+:102B200000000000C020480000000000000000007D -+:102B3000C0204800000000000000A2A400204411B2 -+:102B400000000000000000000040480200000000FB -+:102B5000810000000020441100000000000000017E -+:102B60000020481100000000000021F8002044115E -+:102B700000000000000000170020481100000000C5 -+:102B8000000421F9006044110000068D00000003DC -+:102B900000210230000000000000000014E00000EE -+:102BA0000000039E000021080020441100000000E6 -+:102BB00000000000C02048000000000000000000ED -+:102BC000C0204800000000000000A2A40020441122 -+:102BD000000000000000000000404802000000006B -+:102BE0000000A2A40020441100000000000000002A -+:102BF0000020480200000000800000000020441176 -+:102C0000000000000000000000204811000000004B -+:102C100081000000002044110000000000000010AE -+:102C200000204811000000000000000000200010FB -+:102C3000000000000000000014C00000000003AE0F -+:102C40000000000000400000000000000000201014 -+:102C50000020441100000000000080000020481106 -+:102C6000000000000001A2A40020441100000000A8 -+:102C70000000000600404811000000000000201085 -+:102C800000204411000000000000800000204811D6 -+:102C9000000000000001A2A4002044110000000078 -+:102CA00000000016006048110000036E00000000E4 -+:102CB000004000000000000000000000C0200800EC -+:102CC0000000000000000000C0200C000000000018 -+:102CD0000000001D00210223000000000000000091 -+:102CE00014E00000000003CE810000000020441129 -+:102CF000000000000000000100204811000000005A -+:102D0000000021F80020441100000000000000181D -+:102D10000020481100000000000421F90060441167 -+:102D20000000068D000000110021023000000000AC -+:102D30000000000014E00000000003C000002100BB -+:102D400000204411000000000000000000204802A4 -+:102D50000000000000000000002048030000000008 -+:102D6000BABECAFE0020481100000000CAFEBABE6A -+:102D70000020481100000000000020100020441135 -+:102D8000000000000000800000204811000000004A -+:102D90000000A2A400204411000000000000000474 -+:102DA0000040481100000000000021700020441184 -+:102DB00000000000000000000020480200000000A9 -+:102DC0000000000000204803000000008100000017 -+:102DD00000204411000000000000000A00204811FB -+:102DE00000000000000000000020001000000000B3 -+:102DF0000000000014C00000000003D38C0000009D -+:102E00000020441100000000CAFEBABE0040481174 -+:102E100000000000810000000020441100000000BC -+:102E200000000001002048110000000000003FFFEA -+:102E300040280A20000000008000000040280E20EA -+:102E40000000000040000000C02812200000000028 -+:102E500000040000006946220000068D000000000A -+:102E6000002014100000000000000000002F0223CA -+:102E700000000000000000000CC00000000003E1A2 -+:102E800000000000C0401800000003E400003FFF05 -+:102E9000C0281A2000000000000400000069462637 -+:102EA0000000068D00000000002018100000000047 -+:102EB00000000000002F02240000000000000000BD -+:102EC0000CC00000000003E700000000C0401C0030 -+:102ED000000003EA00003FFFC0281E2000000000A1 -+:102EE00000040000006946270000068D0000000075 -+:102EF00000201C1000000000000000000020440220 -+:102F00000000000000000000002820C500000000B4 -+:102F100000000000004948E800000000A580000013 -+:102F200000200811000000000000200000200C110B -+:102F30000000000083000000006044110000041243 -+:102F4000000000000020440200000000000000001B -+:102F5000C0204800000000000000000040204800A1 -+:102F6000000000000000001FC0210220000000003F -+:102F70000000000014C00000000003F70000201053 -+:102F800000204411000000000000800000204811D3 -+:102F9000000000000000FFFFC0481220000003FFF7 -+:102FA000A780000000200811000000000000A00021 -+:102FB00000200C110000000083000000006044119C -+:102FC0000000041200000000002044020000000085 -+:102FD00000000000C02048000000000000000000C9 -+:102FE000C0204800000000000000FFFFC0281220A1 -+:102FF00000000000830000000020441100000000D9 -+:103000000000000000304883000000008400000041 -+:10301000002044110000000000000000C020480013 -+:1030200000000000000000001D0000000000000083 -+:103030008300000000604411000004120000000042 -+:10304000C040040000000001A98000000020081119 -+:10305000000000000000C00000400C11000003FA56 -+:10306000AB80000000200811000000000000F8E024 -+:1030700000400C11000003FAAD8000000020081190 -+:10308000000000000000F88000400C11000003FA6E -+:10309000B380000000200811000000000000F3FCD5 -+:1030A00000400C11000003FAAF800000002008115E -+:1030B000000000000000E00000400C11000003FAD6 -+:1030C000B180000000200811000000000000F000A6 -+:1030D00000400C11000003FA83000000002044119E -+:1030E00000000000000021480020481100000000FE -+:1030F00084000000002044110000000000000000D7 -+:10310000C020480000000000000000001D0000007A -+:10311000000000000000000000800000000000002F -+:1031200001182000C0304620000000000000000010 -+:10313000D90048000000000000000000C02004008A -+:10314000000000000000000000A0000A00000000D5 -+:103150000218A000C030462000000000000000005F -+:10316000D90048000000000000000000C02004005A -+:10317000000000000000000000A0000A00000000A5 -+:103180000318C000C030462000000000000000000E -+:10319000D90048000000000000000000C02004002A -+:1031A000000000000000000000A0000A0000000075 -+:1031B0000418F8E0C03046200000000000000000C5 -+:1031C000D90048000000000000000000C0200400FA -+:1031D000000000000000000000A0000A0000000045 -+:1031E0000518F880C03046200000000000000000F4 -+:1031F000D90048000000000000000000C0200400CA -+:10320000000000000000000000A0000A0000000014 -+:103210000618E000C030462000000000000000005A -+:10322000D90048000000000000000000C020040099 -+:10323000000000000000000000A0000A00000000E4 -+:103240000718F000C0304620000000000000000019 -+:10325000D90048000000000000000000C020040069 -+:10326000000000000000000000A0000A00000000B4 -+:103270000818F3FCC03046200000000000000000E9 -+:10328000D90048000000000000000000C020040039 -+:10329000000000000000000000A0000A0000000084 -+:1032A0000000003000200A2D000000000000000097 -+:1032B000C0290C4000000000000000300020362330 -+:1032C0000000000000000000C0200400000000001A -+:1032D0000000000000A0000A0000000086000000BE -+:1032E00000204411000000000000000000404801E0 -+:1032F0000000000085000000C02044110000000014 -+:103300000000000000404801000000000000217C97 -+:10331000002044110000000000000018402102209D -+:10332000000000000000000014C000000000044580 -+:1033300000800000C0494A20000004460000000050 -+:10334000C02048000000000000000000C02048002D -+:103350000000000000000000C02048000000000045 -+:103360008100000000204411000000000000000166 -+:10337000002048110000000000000000C0200800EC -+:103380000000000000000000170000000000000026 -+:103390000004217F006044110000068D0000001F22 -+:1033A00000210230000000000000000014C00000F6 -+:1033B000000000000000000000404C020000044B30 -+:1033C00000000000C0200C00000000000000000011 -+:1033D000C02010000000000000000000C020140009 -+:1033E0000000000000000000C020180000000000E5 -+:1033F00000000000C0201C000000000000007F0052 -+:1034000000280A210000000000004500002F0222D1 -+:1034100000000000000000000CE000000000045963 -+:1034200000000000C020200000000000000000009C -+:1034300017000000000000000000001000280A2310 -+:103440000000000000000010002F02220000000019 -+:10345000000000000CE0000000000461810000009A -+:10346000002044110000000000000001002048116D -+:103470000000000000040000006946240000068DE2 -+:103480000000000000400000000004668100000011 -+:10349000002044110000000000000000002048113E -+:1034A000000000000000216D002044110000000019 -+:1034B00000000000002048040000000000000000A0 -+:1034C000006048050000069200000000002824F07B -+:1034D000000000000000000700280A230000000090 -+:1034E00000000001002F0222000000000000000088 -+:1034F0000AE000000000046D00000000002F00C979 -+:10350000000000000000000004E00000000004864D -+:1035100000000000004000000000049300000002D2 -+:10352000002F022200000000000000000AE000005E -+:103530000000047200000000002F00C9000000001D -+:103540000000000002E0000000000486000000000F -+:10355000004000000000049300000003002F02223E -+:1035600000000000000000000AE0000000000477F6 -+:1035700000000000002F00C9000000000000000053 -+:103580000CE0000000000486000000000040000085 -+:103590000000049300000004002F0222000000003D -+:1035A000000000000AE000000000047C00000000B1 -+:1035B000002F00C900000000000000000AE0000029 -+:1035C000000004860000000000400000000004939A -+:1035D00000000005002F0222000000000000000093 -+:1035E0000AE000000000048100000000002F00C974 -+:1035F000000000000000000006E00000000004865B -+:1036000000000000004000000000049300000006DD -+:10361000002F022200000000000000000AE000006D -+:103620000000048600000000002F00C90000000018 -+:103630000000000008E00000000004860000000018 -+:10364000004000000000049300007F0000280A21D1 -+:103650000000000000004500002F022200000000D2 -+:10366000000000000AE00000000000000000000868 -+:1036700000210A23000000000000000014C0000028 -+:1036800000000490000021690020441100000000A7 -+:1036900000000000C0204800000000000000000002 -+:1036A000C02048000000000000000000C0204800CA -+:1036B00000000000CAFEBABE004048110000000031 -+:1036C00000000000C02044000000000000000000D6 -+:1036D000C02000000000000000000000C0404800C2 -+:1036E0000000000000007F0000280A210000000008 -+:1036F00000004500002F0222000000000000000032 -+:103700000AE000000000049900000000C020000052 -+:103710000000000000000000C020000000000000C9 -+:1037200000000000C0400000000000000000000099 -+:1037300000404C080000045900000000C0200800B0 -+:10374000000000000000001040210E2000000000DA -+:1037500000000011402112200000000000000012B3 -+:1037600040211620000000000000216900204411C3 -+:1037700000000000000000000020480200000000DF -+:1037800000000000002102250000000000000000F1 -+:1037900014E00000000004A300040000C0494A2017 -+:1037A000000004A4FFFBFFFFC0284A200000000027 -+:1037B00000000000002102230000000000000000C3 -+:1037C00014E00000000004B000000000C020480029 -+:1037D0000000000000000000C020480000000000C1 -+:1037E0000000000000210224000000000000000092 -+:1037F00014C00000000000008100000000204411FF -+:10380000000000000000000C002048110000000033 -+:103810000000000000200010000000000000000078 -+:1038200014C00000000004ACA000000000204411FF -+:1038300000000000CAFEBABE0040481100000000AF -+:10384000810000000020441100000000000000047E -+:1038500000204811000000000000216B00204411EE -+:103860000000000000000000C02048100000000020 -+:10387000810000000020441100000000000000054D -+:1038800000204811000000000000216C00204411BD -+:103890000000000000000000C020481000000000F0 -+:1038A00000000000002F02240000000000000000C3 -+:1038B0000CE00000000000000000000000400000DC -+:1038C000000004AA00000000C0210A20000000003F -+:1038D0000000000014C00000000004C381000000CC -+:1038E00000204411000000000000000000204811EA -+:1038F000000000000000216D0020441100000000C5 -+:1039000000000000C020480000000000000000008F -+:10391000C060480000000692000000000040000067 -+:10392000000004C7810000000020441100000000D6 -+:103930000000000100204811000000000004000009 -+:10394000C02946200000000000000000C060000008 -+:103950000000068D0000000100210222000000008E -+:103960000000000014C00000000004CE0000216927 -+:10397000002044110000000000000000C0204800AA -+:103980000000000000000000C0204800000000000F -+:10399000000000000020481000000000CAFEBABE6F -+:1039A000004048110000000000000000C02044005A -+:1039B0000000000000000000C040481000000000AF -+:1039C0008100000000204411000000000000000100 -+:1039D0000020481100000000000021F800204411E0 -+:1039E000000000000000000E002048110000000050 -+:1039F000000421F9006044110000068D0000000061 -+:103A000000210230000000000000000014C000008F -+:103A1000000004D0000021800020441100000000BC -+:103A200000000000C020480000000000000000006E -+:103A3000C02000000000000000000000C02048007E -+:103A40000000000000000000C02000000000000096 -+:103A500000000000C040480000000000000000031B -+:103A600000333E2F00000000000000010021022171 -+:103A7000000000000000000014E00000000005004D -+:103A80000000002C00200A2D0000000000040000AF -+:103A900018E00C11000004EF0000000100333E2F7D -+:103AA0000000000000002169002044110000000017 -+:103AB000000000000020480200000000000000009C -+:103AC00000204803000000000000000800300A2227 -+:103AD0000000000000000000C020480000000000BE -+:103AE00000000000C0204800000000000000216924 -+:103AF00000204411000000000000000000204802E7 -+:103B0000000000000000000000204803000000004A -+:103B10000000000800300A22000000000000000041 -+:103B2000C02048000000000000000000D8C048008D -+:103B3000000004E30000216900204411000000009F -+:103B4000000000000020480200000000000000000B -+:103B500000204803000000000000000800300A2296 -+:103B60000000000000000000C0204800000000002D -+:103B700000000000C0204800000000000000002DF0 -+:103B80000020122D000000000000000000290C831E -+:103B90000000000000002169002044110000000026 -+:103BA00000000000002048020000000000000000AB -+:103BB00000204803000000000000000800300A2236 -+:103BC0000000000000000000C020480000000000CD -+:103BD00000000000C02048000000000000000011AC -+:103BE00000210224000000000000000014C00000BA -+:103BF000000000000000000000400000000004AAD7 -+:103C00000000002CC0203620000000000000002D25 -+:103C1000C0403620000000000000000F00210221FB -+:103C2000000000000000000014C0000000000505B6 -+:103C300000000000006000000000000B0000000019 -+:103C4000D90000000000000000000000C040040097 -+:103C500000000001B5000000002044110000000039 -+:103C6000000020000020481100000000B600000005 -+:103C700000204411000000000000A00000204811B6 -+:103C800000000000B7000000002044110000000008 -+:103C90000000C0000020481100000000B800000033 -+:103CA00000204411000000000000F8E0002048114E -+:103CB00000000000B90000000020441100000000D6 -+:103CC0000000F8800020481100000000BA00000049 -+:103CD00000204411000000000000E0000020481116 -+:103CE00000000000BB0000000020441100000000A4 -+:103CF0000000F0000020481100000000BC0000009F -+:103D000000204411000000000000F3FC00204811D6 -+:103D100000000000810000000020441100000000AD -+:103D2000000000020020481100000000000000FF19 -+:103D300000280E300000000000000000002F0223C9 -+:103D400000000000000000000CC000000000051989 -+:103D500000000000C020080000000000000000007B -+:103D600014C000000000052E0000000000200C110F -+:103D7000000000000000001C0020362300000000AE -+:103D80000000002B00203623000000000000002966 -+:103D90000020362300000000000000280020362309 -+:103DA0000000000000000017002036230000000083 -+:103DB000000000250020362300000000000000263F -+:103DC00000203623000000000000001500203623EC -+:103DD0000000000000000016002036230000000054 -+:103DE000FFFFE00000200C11000000000000002197 -+:103DF00000203623000000000000002200203623AF -+:103E00000000000000001FFF00200C110000000057 -+:103E100000000023002036230000000000000024E2 -+:103E20000020362300000000F1FFFFFF00283A2E9B -+:103E3000000000000000001AC0220E200000000058 -+:103E4000000000000029386E000000008100000022 -+:103E5000002044110000000000000006002048116E -+:103E6000000000000000002A402036200000000072 -+:103E70008700000000204411000000000000000046 -+:103E8000C0204800000000000000A1F40020441100 -+:103E900000000000000000000020481000000000AA -+:103EA0000000000000200C110000000000000030A5 -+:103EB00000203623000000009D0000000020441177 -+:103EC000000000000000001F40214A200000000008 -+:103ED00096000000002044110000000000000000D7 -+:103EE000C02048000000000000000000C0200C00BE -+:103EF0000000000000000000C020100000000000D2 -+:103F00000000001F00211624000000000000000037 -+:103F100014C00000000000000000001D0020362337 -+:103F2000000000000000000300281E230000000025 -+:103F3000000000080022222300000000FFFFF00024 -+:103F4000002822280000000000000000002920E8CE -+:103F5000000000000000001F0020362800000000C4 -+:103F60000000001800211E230000000000000020B7 -+:103F70000020362700000000000000020022162466 -+:103F80000000000000000000003014A80000000045 -+:103F90000000001E00203625000000000000000385 -+:103FA00000211A24000000001000000000281A263A -+:103FB00000000000EFFFFFFF00283A2E0000000085 -+:103FC00000000000004938CE0000067B0000000120 -+:103FD00040280A20000000000000000640280E20B3 -+:103FE0000000000000000300C028122000000000B4 -+:103FF0000000000800211224000000000000000062 -+:10400000C02016200000000000000000C0201A2080 -+:10401000000000000000000000210222000000005B -+:104020000000000014C000000000056681000000D0 -+:104030000020441100000000000000010020481191 -+:10404000000000000000225800300A240000000098 -+:1040500000040000006946220000068D000021696E -+:10406000002044110000000000000000002048056E -+:10407000000000000002000000294A2600000000A5 -+:10408000000000000020481000000000CAFEBABE78 -+:10409000002048110000000000000002002F022351 -+:1040A00000000000000000000CC000000000056ED1 -+:1040B00000000000C0201C100000000000000000F4 -+:1040C000C04000000000057C00000002002F022319 -+:1040D00000000000000000000CC000000000056EA1 -+:1040E00081000000002044110000000000000001D9 -+:1040F00000204811000000000000225800300A246F -+:104100000000000000040000006946220000068D47 -+:1041100000000000C0201C10000000000000000093 -+:10412000C04000000000057C00000000002F0223BA -+:1041300000000000000000000CC00000000005723C -+:1041400000000000C0201C00000000000000000073 -+:10415000C04000000000057C00000004002F022386 -+:1041600000000000000000000CC000000000057A04 -+:104170008100000000204411000000000000000049 -+:1041800000204811000000000000216D00204411B3 -+:104190000000000000000000C020480000000000F7 -+:1041A00000000000C060480000000692000000000F -+:1041B00000401C100000057C00000000C020000032 -+:1041C0000000000000000000C040000000000000EF -+:1041D000000000000EE000000000057E000000006E -+:1041E00000600000000005C900000000002F02244C -+:1041F00000000000000000000CC000000000058F5F -+:104200000000A2B7002044110000000000000000E0 -+:104210000020480700000000810000000020441139 -+:104220000000000000000001002048110000000014 -+:104230000004A2B6006044110000068D0000001AC0 -+:10424000002122300000000000000006002226307D -+:104250000000000000042004006044110000068DEE -+:104260000000A2C400204411000000000000000073 -+:10427000003048E9000000000000000000E00000FD -+:104280000000058D0000A2D10020441100000000B4 -+:104290000000000000404808000000000000A2D11B -+:1042A00000204411000000000000000100504A28D6 -+:1042B0000000000000000001002F022400000000A8 -+:1042C000000000000CC00000000005A00000A2BB20 -+:1042D00000204411000000000000000000204807FA -+:1042E00000000000810000000020441100000000D8 -+:1042F0000000000100204811000000000004A2BAE4 -+:10430000006044110000068D0000001A00212230D8 -+:10431000000000000000000600222630000000001F -+:1043200000042004006044110000068D0000A2C5B6 -+:10433000002044110000000000000000003048E9A7 -+:10434000000000000000000000E000000000059EEA -+:104350000000A2D200204411000000000000000074 -+:1043600000404808000000000000A2D200204411D4 -+:10437000000000000000000100504A28000000007A -+:1043800000000002002F02240000000000000000D6 -+:104390000CC00000000005B10000A2BF00204411C5 -+:1043A000000000000000000000204807000000009E -+:1043B0008100000000204411000000000000000106 -+:1043C00000204811000000000004A2BE006044115B -+:1043D0000000068D0000001A0021223000000000BD -+:1043E0000000000600222630000000000004200427 -+:1043F000006044110000068D0000A2C60020441198 -+:104400000000000000000000003048E9000000004B -+:104410000000000000E00000000005AF0000A2D393 -+:104420000020441100000000000000000040480887 -+:10443000000000000000A2D3002044110000000092 -+:104440000000000100504A28000000000000A2C344 -+:104450000020441100000000000000000020480778 -+:104460000000000081000000002044110000000056 -+:104470000000000100204811000000000004A2C25A -+:10448000006044110000068D0000001A0021223057 -+:10449000000000000000000600222630000000009E -+:1044A00000042004006044110000068D0000A2C733 -+:1044B000002044110000000000000000003048E926 -+:1044C000000000000000000000E00000000005BE49 -+:1044D0000000A2D4002044110000000000000000F1 -+:1044E00000404808000000000000A2D40020441151 -+:1044F000000000000000000100504A2800000000F9 -+:1045000085000000002044110000000000000000B1 -+:1045100000204801000000000000304A0020441143 -+:104520000000000001000000002048110000000011 -+:104530000000000000400000000005C4A4000000CE -+:10454000C02044110000000000000000C0404800EE -+:104550000000000000000000C0600000000005C96D -+:1045600000000000C0400400000000010000002C1A -+:1045700000203621000000008100000000204411CE -+:1045800000000000000000060020481100000000AC -+:1045900000000000002F02300000000000000000BA -+:1045A0000CC00000000005D0000000000020041135 -+:1045B000000000000000003000403621000005E34C -+:1045C000000000300020062D0000000000007E00EA -+:1045D000002806210000000000000000002F02213A -+:1045E00000000000000000000CE00000000005E3F7 -+:1045F00081000000002044110000000000000001C4 -+:1046000000204811000000000004A0920060441146 -+:104610000000068D00000031002036300000000050 -+:104620000004A093006044110000068D00000032D9 -+:1046300000203630000000000004A2B600604411E3 -+:104640000000068D0000003300203630000000001E -+:104650000004A2BA006044110000068D000000347E -+:1046600000203630000000000004A2BE00604411AB -+:104670000000068D000000350020363000000000EC -+:104680000004A2C2006044110000068D0000003644 -+:1046900000203630000000000004200400604411B7 -+:1046A0000000068D0001A2A40020441100000000BB -+:1046B0000000003F00204811000000000000003F03 -+:1046C00000204811000000000000003F00204811B9 -+:1046D000000000000000003F002048110000000022 -+:1046E0000000000500204811000000000000A1F4B7 -+:1046F00000204411000000000000000000204811CC -+:1047000000000000880000000020441100000000AC -+:10471000000000010020481100000000810000009E -+:104720000020441100000000000000060020481195 -+:104730000000000000000001002F02300000000017 -+:10474000000000000CE000000000062C000000301B -+:104750000020062D0000000000000000002F0221B4 -+:1047600000000000000000000CE000000000062C2B -+:104770008100000000204411000000000000000142 -+:10478000002048110000000000007E0000280621E3 -+:104790000000000000000000002F022100000000C7 -+:1047A000000000000CE00000000006050000A092E0 -+:1047B00000204411000000000000003100204A2DBC -+:1047C000000000000000A093002044110000000041 -+:1047D0000000003200204A2D000000000000A2B6B8 -+:1047E00000204411000000000000003300204A2D8A -+:1047F000000000000000A2BA0020441100000000E8 -+:104800000000003400204A2D000000000000A2BE7D -+:1048100000204411000000000000003500204A2D57 -+:10482000000000000000A2C20020441100000000AF -+:104830000000003600204A2D00000000000000307B -+:104840000020062D00000000000001FF00280621C6 -+:104850000000000000000000002F02210000000006 -+:10486000000000000CE000000000062B000000002B -+:1048700000210221000000000000000014C0000020 -+:104880000000060E0004A003006044110000068D25 -+:104890000000A00300204411000000000000000000 -+:1048A0000020481000000000000000010021062147 -+:1048B000000000000000000014C00000000006130B -+:1048C0000004A010006044110000068D0000A0103C -+:1048D00000204411000000000000000000204810EB -+:1048E000000000000000000100210621000000007F -+:1048F00000000000002F0221000000000000000066 -+:104900000CE000000000062B0004A0110060441120 -+:104910000000068D0000A0110020441100000000DE -+:104920000000000000204810000000000004A01259 -+:10493000006044110000068D0000A0120020441108 -+:1049400000000000000000000020481000000000EF -+:104950000004A013006044110000068D0000A013A5 -+:10496000002044110000000000000000002048105A -+:10497000000000000004A014006044110000068D37 -+:104980000000A014002044110000000000000000FE -+:1049900000204810000000000004A0150060441131 -+:1049A0000000068D0000A01500204411000000004A -+:1049B0000000000000204810000000000004A016C5 -+:1049C000006044110000068D0000A0160020441174 -+:1049D000000000000000000000204810000000005F -+:1049E0000004A017006044110000068D0000A0170D -+:1049F00000204411000000000000000000204810CA -+:104A00000000000000042004006044110000068D36 -+:104A10000000002C0080062D00000000FF000000B8 -+:104A20000020441100000000000000000020481198 -+:104A300000000000000000010020481100000000FC -+:104A4000000000020080481100000000000000008B -+:104A50000EE000000000063D000000300020062DA2 -+:104A600000000000000000020028062100000000F5 -+:104A700000000000002F02210000000000000000E4 -+:104A80000CE000000000063B810000000020441103 -+:104A9000000000000000000100204811000000009C -+:104AA00000042004006044110000068D0000100086 -+:104AB00000200811000000000000002B002036221A -+:104AC000000000000000000000600000000006413F -+:104AD0000000000000600000000005C99800000010 -+:104AE0000020441100000000000000000080481178 -+:104AF0000000000000000000C0600000000006414F -+:104B000000000000C0400400000000010000A2A45A -+:104B10000020441100000000000000220020481185 -+:104B20000000000089000000002044110000000087 -+:104B300000000001004048110000062D9700000011 -+:104B40000020441100000000000000000020481177 -+:104B5000000000008A000000002044110000000056 -+:104B600000000000004048110000062D0000000079 -+:104B7000006000000000065C0000201000204411CE -+:104B8000000000000000800000204811000000002C -+:104B90000001A2A4C0204411000000000000001683 -+:104BA000006048110000036E000020100020441136 -+:104BB000000000000001000000204811000000007B -+:104BC00081000000002044110000000000000001EE -+:104BD00000204811000000000000217C002044114A -+:104BE00000000000098000000020481100000000C3 -+:104BF000FFFFFFFF00204811000000000000000040 -+:104C00000020481100000000000000001700000014 -+:104C1000000000000004217F006044110000068DA8 -+:104C20000000001F00210230000000000000000012 -+:104C300014C00000000000000000000400404C11FF -+:104C400000000656000000000040000000000000C8 -+:104C50000000001700201E2D0000000000000004CE -+:104C600000291E27000000000000001700803627E2 -+:104C7000000000000000001700201E2D00000000B2 -+:104C8000FFFFFFFB00281E270000000000000017A8 -+:104C900000803627000000000000001700201E2DB5 -+:104CA000000000000000000800291E27000000008E -+:104CB00000000017008036270000000000000017E9 -+:104CC00000201E2D00000000FFFFFFF700281E2718 -+:104CD00000000000000000170080362700000000E0 -+:104CE000000020100020441100000000000080009F -+:104CF00000204811000000000001A2A4002044117F -+:104D00000000000000000016006048110000036E63 -+:104D100000002010002044110000000000010000ED -+:104D200000204811000000000000217C00204411F8 -+:104D30000000000001800000002048110000000079 -+:104D4000FFFFFFFF002048110000000000000000EE -+:104D500000204811000000000000000017000000C3 -+:104D6000000000008100000000204411000000004D -+:104D70000000000100204811000000000004217F15 -+:104D8000006044110000068D0000001F0021023069 -+:104D9000000000000000000014C000000000068CAD -+:104DA0000000001000404C110000067200000000DE -+:104DB000C0200400000000000000000038C0000017 -+:104DC000000000000000001D00200A2D000000006F -+:104DD0000000001E00200E2D000000000000001F3B -+:104DE0000020122D00000000000000200020162DE1 -+:104DF00000000000000021690020441100000000B4 -+:104E00000000000000204804000000000000000036 -+:104E100000204805000000000000000000204801BC -+:104E200000000000CAFEBABE0020481100000000C9 -+:104E30000000000400301224000000000000000008 -+:104E4000002F006400000000000000000CC0000003 -+:104E50000000068B0000000300281A22000000005A -+:104E6000000000080022122200000000FFFFF000F6 -+:104E7000002812240000000000000000002910C4D7 -+:104E8000000000000000001F004036240000000069 -+:104E90000000000000800000000000000000000092 -+:104EA0001AC000000000068D9F0000000020441181 -+:104EB00000000000CAFEBABE002048110000000039 -+:104EC000000000001AE00000000006900000000052 -+:104ED0000080000000000000000000001AC0000078 -+:104EE000000006929E000000002044110000000017 -+:104EF000CAFEBABE002048110000000000000000F9 -+:104F00001AE000000000069500000000008000008C -+:104F10000000000000000000006000000000000B26 -+:104F200000001000006004110000031500000000E4 -+:104F300000200411000000000000000000600811C3 -+:104F4000000001B20000225C0020441100000000BB -+:104F5000000000030020481100000000000022565D -+:104F600000204411000000000000001B0020481138 -+:104F7000000000000000A1FC00204411000000001F -+:104F80000000000100204811000000000001A1FD08 -+:104F9000C0204411000000000000002100201E2D50 -+:104FA000000000000000001000221E27000000008A -+:104FB000000000240020222D000000000000FFFF60 -+:104FC00000282228000000000000000000294907F6 -+:104FD0000000000000000000002048110000000058 -+:104FE000000000220020222D000000000000FFFF32 -+:104FF00000282228000000000000000000294907C6 -+:105000000000000000000000002048110000000027 -+:105010000000002300201E2D0000000000000010F2 -+:1050200000221E27000000000000000000294907A0 -+:1050300000000000000000000040481100000000D7 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B0000142050205C002500000000001C3016860 -+:1052C000043F05C000000000022502090250015100 -+:1052D000000000000223024502A00241000000007D -+:1052E00003D705C005C005C0000000000649064AF6 -+:1052F000031F05C00000000005C005C503200340D2 -+:1053000000000000032A0282034203340000000070 -+:1053100005C005C005C005C00000000005C005515E -+:1053200005C005C00000000003BA05C004BB03446B -+:1053300000000000049A0450043D05C00000000075 -+:1053400004D005C0044104DD00000000045005073E -+:10535000035103750000000005C005C005C005C06D -+:105360000000000005C005C005C005C00000000029 -+:1053700005C005C0063F05C70000000005C005C008 -+:10538000000705C00000000005C005C005C005C03D -+:105390000000000005C005C005C005C000000000F9 -+:1053A00003F803ED0408040600000000040E040ADC -+:1053B000040C041000000000041C04180424042041 -+:1053C00000000000042C0428043404300000000015 -+:1053D00005C005C0043805C00000000005C005C0B8 -+:1053E00005C005C00000000005C005C005C005C01F -+:1053F0000000000000020679069700060000000089 -+:00000001FF -diff --git a/firmware/radeon/RV620_pfp.bin.ihex b/firmware/radeon/RV620_pfp.bin.ihex -new file mode 100644 -index 0000000..f55292c ---- /dev/null -+++ b/firmware/radeon/RV620_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001B8007C038B00D4401E00EE001E5F -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581A800C41C3A08 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFF000042C0400309002007D250049 -+:1000700000351402007D350B00255403007CD5802B -+:1000800000259C030095C00400D5001B007EDDC147 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA180000D4401E00D5801EAD -+:100140000080005300D4007500D4401E00CA08008F -+:1001500000CA0C0000CA100000D4801900D4C018D6 -+:1001600000D5001700D4801E00D4C01E00D5001E8C -+:1001700000E2001E00CA040000A00000007E828B86 -+:1001800000CA080000D4806000D4401E0080000037 -+:1001900000D4801E00CA080000D4806100D4401E34 -+:1001A0000080000000D4801E00CA080000CA0C00B5 -+:1001B00000D4401E00D4801600D4C01600D4801E87 -+:1001C000008001B800D4C01E00C6084300CA0C005D -+:1001D00000CA10000094800400CA140000E420F358 -+:1001E00000D4201300D5606500D4E01C00D5201C8D -+:1001F00000D5601C008000000006200100C60843F6 -+:1002000000CA0C0000CA1000009483F700CA140052 -+:1002100000E420F30080007900D4201300C60843D6 -+:1002200000CA0C0000CA1000009883EF00CA140036 -+:1002300000D400640080008D0000000000C414326F -+:1002400000C6184300C4082F0095400500C40C30B8 -+:1002500000D4401E0080000000EE001E009583F5D3 -+:1002600000C4103100D4403300D5206500D4A01C58 -+:1002700000D4E01C00D5201C00E4015E00D4001E68 -+:10028000008000000006200100CA1800000A2001BA -+:1002900000D6007600C408360098800700C61045D6 -+:1002A0000095011000D4001F00D46062008000009F -+:1002B00000D4206200CC383500CC1433008401BB5C -+:1002C00000D4007200D5401E0080000000EE001E29 -+:1002D00000E2001A008401BB00E2001A00CC104BBF -+:1002E00000CC0447002C9401007D098B0098400548 -+:1002F000007D15CB00D4001A008001B800D4006D39 -+:100300000034440100CC0C480098403A00CC2C4A00 -+:100310000095800400CC0449008001B800D4001A84 -+:1003200000D4C01A00282801008400F000CC10037B -+:100330000098801B0004380C008400F000CC1003EF -+:100340000098801700043808008400F000CC1003E7 -+:100350000098801300043804008400F000CC1003DF -+:100360000098801400CC104C009A800900CC144DE9 -+:10037000009840DC00D4006D00CC184800D5001A6D -+:1003800000D5401A008000C900D5801A0096C0D55B -+:1003900000D4006D008001B800D4006E009AC00344 -+:1003A00000D4006D00D4006E0080000000EC007FDF -+:1003B000009AC0CC00D4006D008001B800D4006E5B -+:1003C00000CC140300CC180300CC1C03007D910367 -+:1003D000007DD583007D190C0035CC1F0035701FC2 -+:1003E000007CF0CB007CD08B00880000007E8E8BE0 -+:1003F0000095C00400D4006E008001B800D4001A3B -+:1004000000D4C01A00CC080300CC0C0300CC1003AD -+:1004100000CC140300CC180300CC1C0300CC240334 -+:1004200000CC28030035C41F0036B01F007C704B81 -+:100430000034F01F007C704B0035701F007C704B47 -+:10044000007D8881007DCCC1007E5101007E9541F8 -+:10045000007C9082007CD4C2007C848B009AC00314 -+:10046000007C8C8B002C88010098809E00D4006D4D -+:100470000098409C00D4006E00CC084C00CC0C4D81 -+:1004800000CC104800D4801A00D4C01A00800101AA -+:1004900000D5001A00CC083200D40032009482D972 -+:1004A00000CA0C0000D4401E0080000000D4001ED2 -+:1004B00000E4011E00D4001E00CA080000CA0C009F -+:1004C00000CA100000D4401E00CA140000D4801ED0 -+:1004D00000D4C01E00D5001E00D5401E00D54034FB -+:1004E0000080000000EE001E0028040400E2001A54 -+:1004F00000E2001A00D4401A00CA380000CC0803F9 -+:1005000000CC0C0300CC0C0300CC0C03009882BD83 -+:1005100000000000008401BB00D7A06F0080000035 -+:1005200000EE001F00CA040000C2FF0000CC083427 -+:1005300000C13FFF007C74CB007CC90B007D010F24 -+:10054000009902B0007C738B008401BB00D7A06FC0 -+:100550000080000000EE001F00CA080000281900FB -+:10056000007D898B009580140028140400CA0C00BB -+:1005700000CA100000CA1C0000CA240000E2001FCC -+:1005800000D4C01A00D5001A00D5401A00CC1803B8 -+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -+:1005A000007D9C4700984297000000000080016198 -+:1005B00000D4C01A00D4401E00D4801E0080000069 -+:1005C00000EE001E00E4011E00D4001E00D4401EF8 -+:1005D00000EE001E00CA040000A00000007E828B16 -+:1005E00000E4013E00D4001E00D4401E00EE001EB8 -+:1005F00000CA040000A00000007E828B00CA080030 -+:1006000000248C06000CCC060098C00600CC104ECE -+:100610000099000400D4007300E4011E00D4001E01 -+:1006200000D4401E00D4801E0080000000EE001E9A -+:1006300000CA080000CA0C000034D01800251001C0 -+:100640000095002100C17FFF00CA100000CA1400FD -+:1006500000CA180000D4801D00D4C01D007DB18BDD -+:1006600000C1420200C2C00100D5801D0034DC0E72 -+:10067000007D5D4C007F734C00D7401E00D5001EEE -+:1006800000D5401E00C1420000C2C00000099C010C -+:100690000031DC10007F5F4C007F734C00042802A7 -+:1006A000007D838000D5A86F00D5806600D7401EEE -+:1006B00000EC005E00C8240200C82402008001B8DB -+:1006C00000D6007600D4401E00D4801E00D4C01E88 -+:1006D0000080000000EE001E0080000000EE001F01 -+:1006E00000D4001F0080000000D4001F00D4001FB1 -+:1006F0000088000000D4001F00000000000000007F -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:1008000000010171000201780003008F0004007FE5 -+:10081000000500030006003F000700320008012C1D -+:1008200000090046000A0036001001B6001700A2B9 -+:100830000022013A00230149002000B400240125D0 -+:100840000027004D0028006A002A0060002B00529B -+:10085000002F0065003200870034017F003C015604 -+:10086000003F00720041018C0044012E00550173CD -+:100870000056017A0060000B00610034006200380D -+:1008800000630038006400380065003800660038F6 -+:10089000006700380068003A00690041006A0048BB -+:1008A000006B0048006C0048006D0048006E004876 -+:1008B000006F00480000000600000006000000066F -+:1008C0000000000600000006000000060000000610 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV630_me.bin.ihex b/firmware/radeon/RV630_me.bin.ihex -new file mode 100644 -index 0000000..ba3a7e6 ---- /dev/null -+++ b/firmware/radeon/RV630_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A000006044110000068A0000000000600000AB -+:1000B0000000062E00000000006000000000064264 -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:1006600000000000006000000000066500000000BF -+:1006700000600000000006590000000200210E2268 -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE00000000000006000000000065F0000000041 -+:100AF00000400000000000EB00000000006000006B -+:100B000000000662000000070020222D0000000007 -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E90000000068A0000001F002102300000000050 -+:100EA0000000000014C000000000068900000004DB -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000068A000000110021023000000000FE -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000068900000000002B140500000000B5 -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A000000000010000000000600000000006428E -+:1019B000000000000040040F0000021300000000BF -+:1019C000006000000000062E000000000060000023 -+:1019D0000000064200000210006004110000031520 -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B1000006000000000062E0000A00C0020441110 -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E300000042004006044110000068A0000000035 -+:101E4000006000000000062E00000000C0600000DE -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000006650000000000600000000002B53C -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:102240000000065C0000000000400000000002DE0C -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A00000000970000000020441125 -+:102600000000000000000000002048110000000051 -+:102610008A000000002044110000000000000000BB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D0000001A1FD002044110000000000000000E6 -+:1026E000D90048000000000000000000C0200400E5 -+:1026F000000000000000000000A0000A0000000030 -+:1027000000002257002044110000000000000003D8 -+:10271000C0484A20000000000000225D0020441153 -+:102720000000000000000000C04048000000000061 -+:1027300000000000006000000000064200000000F1 -+:10274000C0200800000000000000225C00204411AE -+:10275000000000000000000300384A2200000000D2 -+:102760000000A1FC00204411000000000000000057 -+:10277000C0204800000000000001A1FD002044111D -+:102780000000000000000000002F022200000000F6 -+:10279000000000000CE0000000000000000000004D -+:1027A00040204800000000000000000140304A20A6 -+:1027B0000000000000000002C0304A2000000000BD -+:1027C0000000000100530A220000034B0000003FFC -+:1027D000C0280A20000000008100000000204411F1 -+:1027E000000000000000000100204811000000006F -+:1027F000000021F800204411000000000000001833 -+:102800000020481100000000000421F9006044117C -+:102810000000068A000000110021023000000000C4 -+:102820000000000014E00000000003540000001449 -+:10283000002F022200000000000000000CC0000079 -+:10284000000003640000201000204411000000007C -+:102850000000800000204811000000000001A2A438 -+:102860000020441100000000000000000060480249 -+:102870000000036E00002100002044110000000051 -+:1028800000000000C0204800000000000000000020 -+:10289000C02048000000000000000000C0204800E8 -+:1028A0000000000000000000C040480000000000E0 -+:1028B00000000004002F02220000000000000000C1 -+:1028C0000CC000000000036A00002010002044112A -+:1028D00000000000000080000020481100000000FF -+:1028E0000001A2A40020441100000000000000002C -+:1028F000004048020000035F00000028002F022271 -+:1029000000000000000000000CC00000000005BD39 -+:102910000001A2A4002044110000000000000000FB -+:10292000004048020000035F0000002C0020362613 -+:102930000000000000000049002018110000000005 -+:102940000000003F002048110000000000000001CE -+:1029500000331A260000000000000000002F0226AD -+:1029600000000000000000000CC000000000037028 -+:102970000000002C00801A2D000000000000003F25 -+:10298000C0280A200000000000000015002F0222CD -+:1029900000000000000000000CE0000000000386C2 -+:1029A00000000006002F02220000000000000000CE -+:1029B0000CE00000000003B100000016002F02220E -+:1029C00000000000000000000CE00000000003B563 -+:1029D00000000020002F0222000000000000000084 -+:1029E0000CE000000000039C0000000F002F0222FA -+:1029F00000000000000000000CE00000000003A840 -+:102A000000000010002F0222000000000000000063 -+:102A10000CE00000000003A80000001E002F0222AE -+:102A200000000000000000000CE000000000039027 -+:102A30000000A2A4002044110000000000000000DB -+:102A400000404802000000000800000000290A229F -+:102A5000000000000000000340210E2000000000E4 -+:102A60000000000CC021122000000000000800003F -+:102A7000002812240000000000000014C0221620CC -+:102A80000000000000000000002914A40000000065 -+:102A90000000A2A40020441100000000000000007B -+:102AA000002948A2000000000000A1FE00204411FF -+:102AB000000000000000000000404803000000008B -+:102AC000810000000020441100000000000000010F -+:102AD0000020481100000000000021F800204411EF -+:102AE0000000000000000016002048110000000057 -+:102AF000000421F9006044110000068A000000155E -+:102B000000210230000000000000000014E000007E -+:102B1000000003920000210E00204411000000007C -+:102B200000000000C020480000000000000000007D -+:102B3000C0204800000000000000A2A400204411B2 -+:102B400000000000000000000040480200000000FB -+:102B5000810000000020441100000000000000017E -+:102B60000020481100000000000021F8002044115E -+:102B700000000000000000170020481100000000C5 -+:102B8000000421F9006044110000068A00000003DF -+:102B900000210230000000000000000014E00000EE -+:102BA0000000039E000021080020441100000000E6 -+:102BB00000000000C02048000000000000000000ED -+:102BC000C0204800000000000000A2A40020441122 -+:102BD000000000000000000000404802000000006B -+:102BE0000000A2A40020441100000000000000002A -+:102BF0000020480200000000800000000020441176 -+:102C0000000000000000000000204811000000004B -+:102C100081000000002044110000000000000010AE -+:102C200000204811000000000000000000200010FB -+:102C3000000000000000000014C00000000003AE0F -+:102C40000000000000400000000000000000201014 -+:102C50000020441100000000000080000020481106 -+:102C6000000000000001A2A40020441100000000A8 -+:102C70000000000600404811000000000000201085 -+:102C800000204411000000000000800000204811D6 -+:102C9000000000000001A2A4002044110000000078 -+:102CA00000000016006048110000036E00000000E4 -+:102CB000004000000000000000000000C0200800EC -+:102CC0000000000000000000C0200C000000000018 -+:102CD0000000001D00210223000000000000000091 -+:102CE00014E00000000003CE810000000020441129 -+:102CF000000000000000000100204811000000005A -+:102D0000000021F80020441100000000000000181D -+:102D10000020481100000000000421F90060441167 -+:102D20000000068A000000110021023000000000AF -+:102D30000000000014E00000000003C000002100BB -+:102D400000204411000000000000000000204802A4 -+:102D50000000000000000000002048030000000008 -+:102D6000BABECAFE0020481100000000CAFEBABE6A -+:102D70000020481100000000000020100020441135 -+:102D8000000000000000800000204811000000004A -+:102D90000000A2A400204411000000000000000474 -+:102DA0000040481100000000000021700020441184 -+:102DB00000000000000000000020480200000000A9 -+:102DC0000000000000204803000000008100000017 -+:102DD00000204411000000000000000A00204811FB -+:102DE00000000000000000000020001000000000B3 -+:102DF0000000000014C00000000003D38C0000009D -+:102E00000020441100000000CAFEBABE0040481174 -+:102E100000000000810000000020441100000000BC -+:102E200000000001002048110000000000003FFFEA -+:102E300040280A20000000008000000040280E20EA -+:102E40000000000040000000C02812200000000028 -+:102E500000040000006946220000068A000000000D -+:102E6000002014100000000000000000002F0223CA -+:102E700000000000000000000CC00000000003E1A2 -+:102E800000000000C0401800000003E400003FFF05 -+:102E9000C0281A2000000000000400000069462637 -+:102EA0000000068A0000000000201810000000004A -+:102EB00000000000002F02240000000000000000BD -+:102EC0000CC00000000003E700000000C0401C0030 -+:102ED000000003EA00003FFFC0281E2000000000A1 -+:102EE00000040000006946270000068A0000000078 -+:102EF00000201C1000000000000000000020440220 -+:102F00000000000000000000002820C500000000B4 -+:102F100000000000004948E800000000A580000013 -+:102F200000200811000000000000200000200C110B -+:102F30000000000083000000006044110000041243 -+:102F4000000000000020440200000000000000001B -+:102F5000C0204800000000000000000040204800A1 -+:102F6000000000000000001FC0210220000000003F -+:102F70000000000014C00000000003F70000201053 -+:102F800000204411000000000000800000204811D3 -+:102F9000000000000000FFFFC0481220000003FFF7 -+:102FA000A780000000200811000000000000A00021 -+:102FB00000200C110000000083000000006044119C -+:102FC0000000041200000000002044020000000085 -+:102FD00000000000C02048000000000000000000C9 -+:102FE000C0204800000000000000FFFFC0281220A1 -+:102FF00000000000830000000020441100000000D9 -+:103000000000000000304883000000008400000041 -+:10301000002044110000000000000000C020480013 -+:1030200000000000000000001D0000000000000083 -+:103030008300000000604411000004120000000042 -+:10304000C040040000000001A98000000020081119 -+:10305000000000000000C00000400C11000003FA56 -+:10306000AB80000000200811000000000000F8E024 -+:1030700000400C11000003FAAD8000000020081190 -+:10308000000000000000F88000400C11000003FA6E -+:10309000B380000000200811000000000000F3FCD5 -+:1030A00000400C11000003FAAF800000002008115E -+:1030B000000000000000E00000400C11000003FAD6 -+:1030C000B180000000200811000000000000F000A6 -+:1030D00000400C11000003FA83000000002044119E -+:1030E00000000000000021480020481100000000FE -+:1030F00084000000002044110000000000000000D7 -+:10310000C020480000000000000000001D0000007A -+:10311000000000000000000000800000000000002F -+:1031200001182000C0304620000000000000000010 -+:10313000D90048000000000000000000C02004008A -+:10314000000000000000000000A0000A00000000D5 -+:103150000218A000C030462000000000000000005F -+:10316000D90048000000000000000000C02004005A -+:10317000000000000000000000A0000A00000000A5 -+:103180000318C000C030462000000000000000000E -+:10319000D90048000000000000000000C02004002A -+:1031A000000000000000000000A0000A0000000075 -+:1031B0000418F8E0C03046200000000000000000C5 -+:1031C000D90048000000000000000000C0200400FA -+:1031D000000000000000000000A0000A0000000045 -+:1031E0000518F880C03046200000000000000000F4 -+:1031F000D90048000000000000000000C0200400CA -+:10320000000000000000000000A0000A0000000014 -+:103210000618E000C030462000000000000000005A -+:10322000D90048000000000000000000C020040099 -+:10323000000000000000000000A0000A00000000E4 -+:103240000718F000C0304620000000000000000019 -+:10325000D90048000000000000000000C020040069 -+:10326000000000000000000000A0000A00000000B4 -+:103270000818F3FCC03046200000000000000000E9 -+:10328000D90048000000000000000000C020040039 -+:10329000000000000000000000A0000A0000000084 -+:1032A0000000003000200A2D000000000000000097 -+:1032B000C0290C4000000000000000300020362330 -+:1032C0000000000000000000C0200400000000001A -+:1032D0000000000000A0000A0000000086000000BE -+:1032E00000204411000000000000000000404801E0 -+:1032F0000000000085000000C02044110000000014 -+:103300000000000000404801000000000000217C97 -+:10331000002044110000000000000000C020480010 -+:103320000000000000000000C02048000000000075 -+:1033300000000000C02048000000000081000000E4 -+:10334000002044110000000000000001002048118E -+:103350000000000000000000C02008000000000085 -+:103360000000000017000000000000000004217FA2 -+:10337000006044110000068A0000001F0021023096 -+:10338000000000000000000014C000000000000069 -+:103390000000000000404C02000004480000000053 -+:1033A000C0200C000000000000000000C020100041 -+:1033B0000000000000000000C02014000000000019 -+:1033C00000000000C0201800000000000000000005 -+:1033D000C0201C000000000000007F0000280A211F -+:1033E0000000000000004500002F02220000000045 -+:1033F000000000000CE00000000004560000000087 -+:10340000C0202000000000000000000017000000A5 -+:10341000000000000000001000280A230000000047 -+:1034200000000010002F0222000000000000000039 -+:103430000CE000000000045E810000000020441148 -+:103440000000000000000001002048110000000002 -+:1034500000040000006946240000068A0000000005 -+:1034600000400000000004638100000000204411BF -+:1034700000000000000000000020481100000000D3 -+:103480000000216D00204411000000000000000039 -+:103490000020480400000000000000000060480513 -+:1034A0000000068F00000000002824F0000000004B -+:1034B0000000000700280A230000000000000001AF -+:1034C000002F022200000000000000000AE00000BF -+:1034D0000000046A00000000002F00C90000000086 -+:1034E0000000000004E00000000004830000000071 -+:1034F000004000000000049000000002002F0222A3 -+:1035000000000000000000000AE000000000046F5E -+:1035100000000000002F00C90000000000000000B3 -+:1035200002E00000000004830000000000400000F2 -+:103530000000049000000003002F022200000000A1 -+:10354000000000000AE00000000004740000000019 -+:10355000002F00C900000000000000000CE0000087 -+:103560000000048300000000004000000000049000 -+:1035700000000004002F02220000000000000000F4 -+:103580000AE000000000047900000000002F00C9DC -+:1035900000000000000000000AE0000000000483BA -+:1035A0000000000000400000000004900000000542 -+:1035B000002F022200000000000000000AE00000CE -+:1035C0000000047E00000000002F00C90000000081 -+:1035D0000000000006E0000000000483000000007E -+:1035E000004000000000049000000006002F0222AE -+:1035F00000000000000000000AE00000000004835A -+:1036000000000000002F00C90000000000000000C2 -+:1036100008E00000000004830000000000400000FB -+:103620000000049000007F0000280A210000000034 -+:1036300000004500002F02220000000000000000F2 -+:103640000AE00000000000000000000800210A233A -+:10365000000000000000000014C000000000048D05 -+:10366000000021690020441100000000000000005B -+:10367000C02048000000000000000000C0204800FA -+:103680000000000000000000C02048000000000012 -+:10369000CAFEBABE00404811000000000000000051 -+:1036A000C02044000000000000000000C020000016 -+:1036B0000000000000000000C040480000000000C2 -+:1036C00000007F0000280A210000000000004500E3 -+:1036D000002F022200000000000000000AE00000AD -+:1036E0000000049600000000C02000000000000060 -+:1036F00000000000C02000000000000000000000EA -+:10370000C0400000000000000000000000404C0825 -+:103710000000045600000000C02008000000000067 -+:103720000000001040210E200000000000000011E9 -+:10373000402112200000000000000012402116204D -+:10374000000000000000216900204411000000007A -+:1037500000000000002048020000000000000000FF -+:1037600000210225000000000000000014E000001D -+:10377000000004A000040000C0494A20000004A189 -+:10378000FFFBFFFFC0284A200000000000000000EF -+:1037900000210223000000000000000014E00000EF -+:1037A000000004AD00000000C02048000000000040 -+:1037B00000000000C02048000000000000000000E1 -+:1037C00000210224000000000000000014C00000DE -+:1037D00000000000810000000020441100000000F3 -+:1037E0000000000C00204811000000000000000054 -+:1037F00000200010000000000000000014C00000C5 -+:10380000000004A9A00000000020441100000000F6 -+:10381000CAFEBABE0040481100000000810000004E -+:1038200000204411000000000000000400204811A6 -+:10383000000000000000216B002044110000000087 -+:1038400000000000C02048100000000081000000BF -+:103850000020441100000000000000050020481175 -+:10386000000000000000216C002044110000000056 -+:1038700000000000C0204810000000000000000010 -+:10388000002F022400000000000000000CE00000F7 -+:10389000000000000000000000400000000004A73D -+:1038A00000000000C0210A2000000000000000000D -+:1038B00014C00000000004C081000000002044117A -+:1038C000000000000000000000204811000000007F -+:1038D0000000216D002044110000000000000000E5 -+:1038E000C02048000000000000000000C060480048 -+:1038F0000000068F0000000000400000000004C42B -+:1039000081000000002044110000000000000001C0 -+:10391000002048110000000000040000C0294620DB -+:103920000000000000000000C06000000000068AE7 -+:103930000000000100210222000000000000000041 -+:1039400014C00000000004CB0000216900204411D5 -+:103950000000000000000000C0204800000000003F -+:1039600000000000C020480000000000000000002F -+:103970000020481000000000CAFEBABE00404811F6 -+:103980000000000000000000C02044000000000013 -+:1039900000000000C040481000000000810000004E -+:1039A0000020441100000000000000010020481128 -+:1039B00000000000000021F8002044110000000079 -+:1039C0000000000E0020481100000000000421F952 -+:1039D000006044110000068A00000000002102304F -+:1039E000000000000000000014C00000000004CD32 -+:1039F00000002180002044110000000000000000B1 -+:103A0000C02048000000000000000000C0200000AE -+:103A10000000000000000000C0204800000000007E -+:103A200000000000C02000000000000000000000B6 -+:103A3000C0404800000000000000000300333E2F9B -+:103A40000000000000000001002102210000000031 -+:103A50000000000014E00000000004FD0000002C45 -+:103A600000200A2D000000000004000018E00C11E6 -+:103A7000000004EC0000000100333E2F00000000B5 -+:103A80000000216900204411000000000000000037 -+:103A90000020480200000000000000000020480351 -+:103AA000000000000000000800300A2200000000B2 -+:103AB00000000000C02048000000000000000000DE -+:103AC000C0204800000000000000216900204411CF -+:103AD000000000000000000000204802000000007C -+:103AE0000000000000204803000000000000000863 -+:103AF00000300A220000000000000000C020480042 -+:103B00000000000000000000D8C04800000004E0F1 -+:103B100000002169002044110000000000000000A6 -+:103B200000204802000000000000000000204803C0 -+:103B3000000000000000000800300A220000000021 -+:103B400000000000C020480000000000000000004D -+:103B5000C0204800000000000000002D0020122DB1 -+:103B6000000000000000000000290C83000000009D -+:103B70000000216900204411000000000000000046 -+:103B80000020480200000000000000000020480360 -+:103B9000000000000000000800300A2200000000C1 -+:103BA00000000000C02048000000000000000000ED -+:103BB000C020480000000000000000110021022485 -+:103BC000000000000000000014C000000000000021 -+:103BD0000000000000400000000004A70000002CCE -+:103BE000C0203620000000000000002DC04036201C -+:103BF000000000000000000F002102210000000072 -+:103C00000000000014C000000000050200000000D9 -+:103C1000006000000000000B00000000D900000060 -+:103C20000000000000000000C0400400000000018F -+:103C3000B50000000020441100000000000020003A -+:103C40000020481100000000B600000000204411D0 -+:103C5000000000000000A00000204811000000004B -+:103C6000B700000000204411000000000000C00068 -+:103C70000020481100000000B8000000002044119E -+:103C8000000000000000F8E00020481100000000E3 -+:103C9000B900000000204411000000000000F8807E -+:103CA0000020481100000000BA000000002044116C -+:103CB000000000000000E0000020481100000000AB -+:103CC000BB00000000204411000000000000F000D4 -+:103CD0000020481100000000BC000000002044113A -+:103CE000000000000000F3FC00204811000000006C -+:103CF00081000000002044110000000000000002CC -+:103D00000020481100000000000000FF00280E30D5 -+:103D10000000000000000000002F0223000000004F -+:103D2000000000000CC000000000051600000000AC -+:103D3000C0200800000000000000000014C00000C7 -+:103D40000000052B0000000000200C110000000006 -+:103D50000000001C00203623000000000000002BA3 -+:103D60000020362300000000000000290020362338 -+:103D700000000000000000280020362300000000A2 -+:103D8000000000170020362300000000000000257E -+:103D9000002036230000000000000026002036230B -+:103DA0000000000000000015002036230000000085 -+:103DB000000000160020362300000000FFFFE00096 -+:103DC00000200C110000000000000021002036231C -+:103DD0000000000000000022002036230000000048 -+:103DE00000001FFF00200C11000000000000002355 -+:103DF00000203623000000000000002400203623AD -+:103E000000000000F1FFFFFF00283A2E0000000034 -+:103E10000000001AC0220E20000000000000000078 -+:103E20000029386E000000008100000000204411CD -+:103E30000000000000000006002048110000000003 -+:103E40000000002A4020362000000000870000000B -+:103E5000002044110000000000000000C0204800C5 -+:103E6000000000000000A1F4002044110000000048 -+:103E700000000000002048100000000000000000CA -+:103E800000200C110000000000000030002036234C -+:103E9000000000009D000000002044110000000010 -+:103EA0000000001F40214A20000000009600000092 -+:103EB000002044110000000000000000C020480065 -+:103EC0000000000000000000C0200C000000000006 -+:103ED00000000000C0201000000000000000001FD3 -+:103EE00000211624000000000000000014C00000A3 -+:103EF000000000000000001D00203623000000002C -+:103F00000000000300281E2300000000000000083D -+:103F10000022222300000000FFFFF00000282228DA -+:103F20000000000000000000002920E80000000060 -+:103F30000000001F002036280000000000000018CC -+:103F400000211E2300000000000000200020362772 -+:103F50000000000000000002002216240000000003 -+:103F600000000000003014A8000000000000001E47 -+:103F700000203625000000000000000300211A2464 -+:103F8000000000001000000000281A2600000000B9 -+:103F9000EFFFFFFF00283A2E0000000000000000A5 -+:103FA000004938CE000006780000000140280A20B1 -+:103FB000000000000000000640280E200000000065 -+:103FC00000000300C02812200000000000000008CC -+:103FD000002112240000000000000000C020162074 -+:103FE0000000000000000000C0201A2000000000B7 -+:103FF000000000000021022200000000000000007C -+:1040000014C000000000056381000000002044117E -+:104010000000000000000001002048110000000026 -+:104020000000225800300A240000000000040000B4 -+:10403000006946220000068A000021690020441120 -+:104040000000000000000000002048050000000003 -+:104050000002000000294A260000000000000000C5 -+:104060000020481000000000CAFEBABE002048111F -+:104070000000000000000002002F022300000000EA -+:10408000000000000CC000000000056B00000000F4 -+:10409000C0201C100000000000000000C040000014 -+:1040A0000000057900000002002F0223000000003C -+:1040B000000000000CC000000000056B8100000043 -+:1040C0000020441100000000000000010020481101 -+:1040D000000000000000225800300A240000000008 -+:1040E00000040000006946220000068A000000006B -+:1040F000C0201C100000000000000000C0400000B4 -+:104100000000057900000000002F022300000000DD -+:10411000000000000CC000000000056F000000005F -+:10412000C0201C000000000000000000C040000093 -+:104130000000057900000004002F022300000000A9 -+:10414000000000000CC000000000057781000000A6 -+:104150000020441100000000000000000020481171 -+:10416000000000000000216D00204411000000004C -+:1041700000000000C0204800000000000000000017 -+:10418000C06048000000068F0000000000401C10C6 -+:104190000000057900000000C020000000000000C1 -+:1041A00000000000C040000000000000000000000F -+:1041B0000EE000000000057B000000000060000031 -+:1041C000000005C600000000002F022400000000CF -+:1041D000000000000CC000000000058C0000A2B729 -+:1041E00000204411000000000000000000204807EB -+:1041F00000000000810000000020441100000000C9 -+:104200000000000100204811000000000004A2B6D8 -+:10421000006044110000068A0000001A00212230CC -+:104220000000000000000006002226300000000010 -+:1042300000042004006044110000068A0000A2C4AB -+:10424000002044110000000000000000003048E998 -+:10425000000000000000000000E000000000058AEF -+:104260000000A2D100204411000000000000000066 -+:1042700000404808000000000000A2D100204411C6 -+:10428000000000000000000100504A28000000006B -+:1042900000000001002F02240000000000000000C8 -+:1042A0000CC000000000059D0000A2BB00204411CE -+:1042B000000000000000000000204807000000008F -+:1042C00081000000002044110000000000000001F7 -+:1042D00000204811000000000004A2BA0060441150 -+:1042E0000000068A0000001A0021223000000000B1 -+:1042F0000000000600222630000000000004200418 -+:10430000006044110000068A0000A2C5002044118C -+:104310000000000000000000003048E9000000003C -+:104320000000000000E000000000059B0000A2D299 -+:104330000020441100000000000000000040480878 -+:10434000000000000000A2D2002044110000000084 -+:104350000000000100504A28000000000000000298 -+:10436000002F022400000000000000000CC000002C -+:10437000000005AE0000A2BF0020441100000000B4 -+:10438000000000000020480700000000810000003D -+:10439000002044110000000000000001002048112E -+:1043A000000000000004A2BE006044110000068A64 -+:1043B0000000001A0021223000000000000000066A -+:1043C0000022263000000000000420040060441198 -+:1043D0000000068A0000A2C6002044110000000070 -+:1043E00000000000003048E900000000000000006C -+:1043F00000E00000000005AC0000A2D30020441142 -+:10440000000000000000000000404808000000001C -+:104410000000A2D3002044110000000000000001B1 -+:1044200000504A28000000000000A2C300204411F0 -+:10443000000000000000000000204807000000000D -+:104440008100000000204411000000000000000175 -+:1044500000204811000000000004A2C200604411C6 -+:104460000000068A0000001A00212230000000002F -+:104470000000000600222630000000000004200496 -+:10448000006044110000068A0000A2C70020441109 -+:104490000000000000000000003048E900000000BB -+:1044A0000000000000E00000000005BB0000A2D4F6 -+:1044B00000204411000000000000000000404808F7 -+:1044C000000000000000A2D4002044110000000001 -+:1044D0000000000100504A28000000008500000094 -+:1044E00000204411000000000000000000204801EE -+:1044F000000000000000304A0020441100000000CD -+:104500000100000000204811000000000000000031 -+:1045100000400000000005C1A4000000C0204411BC -+:104520000000000000000000C04048000000000043 -+:1045300000000000C0600000000005C60000000090 -+:10454000C0400400000000010000002C00203621C3 -+:104550000000000081000000002044110000000065 -+:1045600000000006002048110000000000000000CC -+:10457000002F023000000000000000000CC000000E -+:10458000000005CD00000000002004110000000024 -+:104590000000003000403621000005E0000000303F -+:1045A0000020062D0000000000007E0000280621EB -+:1045B0000000000000000000002F022100000000A9 -+:1045C000000000000CE00000000005E08100000099 -+:1045D00000204411000000000000000100204811EC -+:1045E000000000000004A092006044110000068A50 -+:1045F0000000003100203630000000000004A093CD -+:10460000006044110000068A0000003200203630AD -+:10461000000000000004A2B6006044110000068AF9 -+:104620000000003300203630000000000004A2BA71 -+:10463000006044110000068A00000034002036307B -+:10464000000000000004A2BE006044110000068AC1 -+:104650000000003500203630000000000004A2C237 -+:10466000006044110000068A000000360020363049 -+:104670000000000000042004006044110000068ACD -+:104680000001A2A400204411000000000000003F2F -+:1046900000204811000000000000003F00204811E9 -+:1046A000000000000000003F002048110000000052 -+:1046B0000000003F0020481100000000000000053D -+:1046C00000204811000000000000A1F40020441167 -+:1046D0000000000000000000002048110000000061 -+:1046E00088000000002044110000000000000001CC -+:1046F000002048110000000081000000002044114B -+:10470000000000000000000600204811000000002A -+:1047100000000001002F0230000000000000000037 -+:104720000CE0000000000629000000300020062DEB -+:104730000000000000000000002F02210000000027 -+:10474000000000000CE000000000062981000000CD -+:10475000002044110000000000000001002048116A -+:104760000000000000007E0000280621000000007C -+:1047700000000000002F02210000000000000000E7 -+:104780000CE00000000006020000A092002044118E -+:10479000000000000000003100204A2D0000000051 -+:1047A0000000A0930020441100000000000000322F -+:1047B00000204A2D000000000000A2B60020441195 -+:1047C000000000000000003300204A2D000000001F -+:1047D0000000A2BA002044110000000000000034D4 -+:1047E00000204A2D000000000000A2BE002044115D -+:1047F000000000000000003500204A2D00000000ED -+:104800000000A2C200204411000000000000003699 -+:1048100000204A2D00000000000000300020062D7E -+:1048200000000000000001FF002806210000000039 -+:1048300000000000002F0221000000000000000026 -+:104840000CE000000000062800000000002102210A -+:10485000000000000000000014C000000000060B73 -+:104860000004A003006044110000068A0000A003B9 -+:10487000002044110000000000000000002048104B -+:1048800000000000000000010021062100000000DF -+:104890000000000014C00000000006100004A0107A -+:1048A000006044110000068A0000A010002044119E -+:1048B0000000000000000000002048100000000080 -+:1048C000000000010021062100000000000000009F -+:1048D000002F022100000000000000000CE000009A -+:1048E000000006280004A011006044110000068AA0 -+:1048F0000000A01100204411000000000000000092 -+:1049000000204810000000000004A01200604411C4 -+:104910000000068A0000A0120020441100000000E0 -+:104920000000000000204810000000000004A01358 -+:10493000006044110000068A0000A013002044110A -+:1049400000000000000000000020481000000000EF -+:104950000004A014006044110000068A0000A014A6 -+:10496000002044110000000000000000002048105A -+:10497000000000000004A015006044110000068A39 -+:104980000000A015002044110000000000000000FD -+:1049900000204810000000000004A0160060441130 -+:1049A0000000068A0000A01600204411000000004C -+:1049B0000000000000204810000000000004A017C4 -+:1049C000006044110000068A0000A0170020441176 -+:1049D000000000000000000000204810000000005F -+:1049E00000042004006044110000068A0000002C2E -+:1049F0000080062D00000000FF0000000020441190 -+:104A0000000000000000000000204811000000002D -+:104A1000000000010020481100000000000000021A -+:104A20000080481100000000000000000EE00000BF -+:104A30000000063A000000300020062D00000000B3 -+:104A40000000000200280621000000000000000015 -+:104A5000002F022100000000000000000CE0000018 -+:104A60000000063881000000002044110000000012 -+:104A70000000000100204811000000000004200494 -+:104A8000006044110000068A000010000020081198 -+:104A9000000000000000002B002036220000000073 -+:104AA00000000000006000000000063E0000000062 -+:104AB00000600000000005C69800000000204411BE -+:104AC000000000000000000000804811000000000D -+:104AD00000000000C06000000000063E0000000072 -+:104AE000C0400400000000010000A2A40020441106 -+:104AF000000000000000002200204811000000001B -+:104B000089000000002044110000000000000001A6 -+:104B1000004048110000062A9700000000204411C0 -+:104B2000000000000000000000204811000000000C -+:104B30008A00000000204411000000000000000076 -+:104B4000004048110000062A00000000006000003C -+:104B50000000065900002010002044110000000051 -+:104B60000000800000204811000000000001A2A405 -+:104B7000C020441100000000000000160060481131 -+:104B80000000036E0000201000204411000000000F -+:104B9000000100000020481100000000810000001A -+:104BA0000020441100000000000000010020481116 -+:104BB000000000000000217C0020441100000000E3 -+:104BC000098000000020481100000000FFFFFFFFE7 -+:104BD00000204811000000000000000000204811E3 -+:104BE00000000000000000001700000000000000AE -+:104BF0000004217F006044110000068A0000001FAD -+:104C000000210230000000000000000014C000007D -+:104C1000000000000000000400404C11000006539A -+:104C2000000000000040000000000000000000172D -+:104C300000201E2D000000000000000400291E2797 -+:104C40000000000000000017008036270000000070 -+:104C50000000001700201E2D00000000FFFFFFFBDA -+:104C600000281E27000000000000001700803627E3 -+:104C7000000000000000001700201E2D00000000B2 -+:104C80000000000800291E27000000000000001797 -+:104C900000803627000000000000001700201E2DB5 -+:104CA00000000000FFFFFFF700281E2700000000A3 -+:104CB00000000017008036270000000000002010D0 -+:104CC0000020441100000000000080000020481176 -+:104CD000000000000001A2A4002044110000000018 -+:104CE00000000016006048110000036E0000201054 -+:104CF00000204411000000000001000000204811C5 -+:104D0000000000000000217C002044110000000091 -+:104D1000018000000020481100000000FFFFFFFF9D -+:104D20000020481100000000000000000020481191 -+:104D3000000000000000000017000000000000005C -+:104D4000810000000020441100000000000000016C -+:104D500000204811000000000004217F0060441181 -+:104D60000000068A0000001F002102300000000041 -+:104D70000000000014C000000000068900000010C0 -+:104D800000404C110000066F00000000C02004002D -+:104D9000000000000000000038C00000000000001B -+:104DA0000000001D00200A2D000000000000001E71 -+:104DB00000200E2D000000000000001F0020122D1A -+:104DC00000000000000000200020162D0000000060 -+:104DD00000002169002044110000000000000000D4 -+:104DE00000204804000000000000000000204805EA -+:104DF000000000000000000000204801000000004A -+:104E0000CAFEBABE002048110000000000000004E5 -+:104E1000003012240000000000000000002F006499 -+:104E200000000000000000000CC000000000068828 -+:104E30000000000300281A22000000000000000803 -+:104E40000022122200000000FFFFF00000281224C0 -+:104E50000000000000000000002910C40000000055 -+:104E60000000001F00403624000000000000000089 -+:104E70000080000000000000000000001AC00000D8 -+:104E80000000068A9F00000000204411000000007E -+:104E9000CAFEBABE00204811000000000000000059 -+:104EA0001AE000000000068D0000000000800000F5 -+:104EB00000000000000000001AC000000000068F83 -+:104EC0009E0000000020441100000000CAFEBABE8F -+:104ED0000020481100000000000000001AE000005F -+:104EE00000000692000000000080000000000000AA -+:104EF00000000000006000000000000B0000100037 -+:104F000000600411000003150000000000200411DF -+:104F1000000000000000000000600811000001B265 -+:104F20000000225C0020441100000000000000038B -+:104F3000002048110000000000002256002044110B -+:104F4000000000000000001B0020481100000000CD -+:104F50000000A1FC0020441100000000000000013E -+:104F600000204811000000000001A1FDC0204411F4 -+:104F7000000000000000002100201E2D00000000A5 -+:104F80000000001000221E27000000000000002486 -+:104F90000020222D000000000000FFFF0028222832 -+:104FA0000000000000000000002949070000000088 -+:104FB0000000000000204811000000000000002256 -+:104FC0000020222D000000000000FFFF0028222802 -+:104FD0000000000000000000002949070000000058 -+:104FE0000000000000204811000000000000002325 -+:104FF00000201E2D000000000000001000221E27CF -+:105000000000000000000000002949070000000027 -+:1050100000000000004048110000000000000000F7 -+:105020000000000000000000000000000000000080 -+:105030000000000000000000000000000000000070 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B000014204FF05BD02500000000001C3016867 -+:1052C000043F05BD00000000022502090250015103 -+:1052D000000000000223024502A00241000000007D -+:1052E00003D705BD05BD05BD000000000646064705 -+:1052F000031F05BD0000000005BD05C203200340DB -+:1053000000000000032A0282034203340000000070 -+:1053100005BD05BD05BD05BD0000000005BD054E70 -+:1053200005BD05BD0000000003BA05BD04B8034477 -+:10533000000000000497044D043D05BD000000007E -+:1053400004CD05BD044104DA00000000044D05044D -+:10535000035103750000000005BD05BD05BD05BD79 -+:105360000000000005BD05BD05BD05BD0000000035 -+:1053700005BD05BD063C05C40000000005BD05BD1A -+:10538000000705BD0000000005BD05BD05BD05BD4C -+:105390000000000005BD05BD05BD05BD0000000005 -+:1053A00003F803ED0408040600000000040E040ADC -+:1053B000040C041000000000041C04180424042041 -+:1053C00000000000042C0428043404300000000015 -+:1053D00005BD05BD043805BD0000000005BD05BDC7 -+:1053E00005BD05BD0000000005BD05BD05BD05BD31 -+:1053F000000000000002067606940006000000008F -+:00000001FF -diff --git a/firmware/radeon/RV630_pfp.bin.ihex b/firmware/radeon/RV630_pfp.bin.ihex -new file mode 100644 -index 0000000..f55292c ---- /dev/null -+++ b/firmware/radeon/RV630_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001B8007C038B00D4401E00EE001E5F -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581A800C41C3A08 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFF000042C0400309002007D250049 -+:1000700000351402007D350B00255403007CD5802B -+:1000800000259C030095C00400D5001B007EDDC147 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA180000D4401E00D5801EAD -+:100140000080005300D4007500D4401E00CA08008F -+:1001500000CA0C0000CA100000D4801900D4C018D6 -+:1001600000D5001700D4801E00D4C01E00D5001E8C -+:1001700000E2001E00CA040000A00000007E828B86 -+:1001800000CA080000D4806000D4401E0080000037 -+:1001900000D4801E00CA080000D4806100D4401E34 -+:1001A0000080000000D4801E00CA080000CA0C00B5 -+:1001B00000D4401E00D4801600D4C01600D4801E87 -+:1001C000008001B800D4C01E00C6084300CA0C005D -+:1001D00000CA10000094800400CA140000E420F358 -+:1001E00000D4201300D5606500D4E01C00D5201C8D -+:1001F00000D5601C008000000006200100C60843F6 -+:1002000000CA0C0000CA1000009483F700CA140052 -+:1002100000E420F30080007900D4201300C60843D6 -+:1002200000CA0C0000CA1000009883EF00CA140036 -+:1002300000D400640080008D0000000000C414326F -+:1002400000C6184300C4082F0095400500C40C30B8 -+:1002500000D4401E0080000000EE001E009583F5D3 -+:1002600000C4103100D4403300D5206500D4A01C58 -+:1002700000D4E01C00D5201C00E4015E00D4001E68 -+:10028000008000000006200100CA1800000A2001BA -+:1002900000D6007600C408360098800700C61045D6 -+:1002A0000095011000D4001F00D46062008000009F -+:1002B00000D4206200CC383500CC1433008401BB5C -+:1002C00000D4007200D5401E0080000000EE001E29 -+:1002D00000E2001A008401BB00E2001A00CC104BBF -+:1002E00000CC0447002C9401007D098B0098400548 -+:1002F000007D15CB00D4001A008001B800D4006D39 -+:100300000034440100CC0C480098403A00CC2C4A00 -+:100310000095800400CC0449008001B800D4001A84 -+:1003200000D4C01A00282801008400F000CC10037B -+:100330000098801B0004380C008400F000CC1003EF -+:100340000098801700043808008400F000CC1003E7 -+:100350000098801300043804008400F000CC1003DF -+:100360000098801400CC104C009A800900CC144DE9 -+:10037000009840DC00D4006D00CC184800D5001A6D -+:1003800000D5401A008000C900D5801A0096C0D55B -+:1003900000D4006D008001B800D4006E009AC00344 -+:1003A00000D4006D00D4006E0080000000EC007FDF -+:1003B000009AC0CC00D4006D008001B800D4006E5B -+:1003C00000CC140300CC180300CC1C03007D910367 -+:1003D000007DD583007D190C0035CC1F0035701FC2 -+:1003E000007CF0CB007CD08B00880000007E8E8BE0 -+:1003F0000095C00400D4006E008001B800D4001A3B -+:1004000000D4C01A00CC080300CC0C0300CC1003AD -+:1004100000CC140300CC180300CC1C0300CC240334 -+:1004200000CC28030035C41F0036B01F007C704B81 -+:100430000034F01F007C704B0035701F007C704B47 -+:10044000007D8881007DCCC1007E5101007E9541F8 -+:10045000007C9082007CD4C2007C848B009AC00314 -+:10046000007C8C8B002C88010098809E00D4006D4D -+:100470000098409C00D4006E00CC084C00CC0C4D81 -+:1004800000CC104800D4801A00D4C01A00800101AA -+:1004900000D5001A00CC083200D40032009482D972 -+:1004A00000CA0C0000D4401E0080000000D4001ED2 -+:1004B00000E4011E00D4001E00CA080000CA0C009F -+:1004C00000CA100000D4401E00CA140000D4801ED0 -+:1004D00000D4C01E00D5001E00D5401E00D54034FB -+:1004E0000080000000EE001E0028040400E2001A54 -+:1004F00000E2001A00D4401A00CA380000CC0803F9 -+:1005000000CC0C0300CC0C0300CC0C03009882BD83 -+:1005100000000000008401BB00D7A06F0080000035 -+:1005200000EE001F00CA040000C2FF0000CC083427 -+:1005300000C13FFF007C74CB007CC90B007D010F24 -+:10054000009902B0007C738B008401BB00D7A06FC0 -+:100550000080000000EE001F00CA080000281900FB -+:10056000007D898B009580140028140400CA0C00BB -+:1005700000CA100000CA1C0000CA240000E2001FCC -+:1005800000D4C01A00D5001A00D5401A00CC1803B8 -+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -+:1005A000007D9C4700984297000000000080016198 -+:1005B00000D4C01A00D4401E00D4801E0080000069 -+:1005C00000EE001E00E4011E00D4001E00D4401EF8 -+:1005D00000EE001E00CA040000A00000007E828B16 -+:1005E00000E4013E00D4001E00D4401E00EE001EB8 -+:1005F00000CA040000A00000007E828B00CA080030 -+:1006000000248C06000CCC060098C00600CC104ECE -+:100610000099000400D4007300E4011E00D4001E01 -+:1006200000D4401E00D4801E0080000000EE001E9A -+:1006300000CA080000CA0C000034D01800251001C0 -+:100640000095002100C17FFF00CA100000CA1400FD -+:1006500000CA180000D4801D00D4C01D007DB18BDD -+:1006600000C1420200C2C00100D5801D0034DC0E72 -+:10067000007D5D4C007F734C00D7401E00D5001EEE -+:1006800000D5401E00C1420000C2C00000099C010C -+:100690000031DC10007F5F4C007F734C00042802A7 -+:1006A000007D838000D5A86F00D5806600D7401EEE -+:1006B00000EC005E00C8240200C82402008001B8DB -+:1006C00000D6007600D4401E00D4801E00D4C01E88 -+:1006D0000080000000EE001E0080000000EE001F01 -+:1006E00000D4001F0080000000D4001F00D4001FB1 -+:1006F0000088000000D4001F00000000000000007F -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:1008000000010171000201780003008F0004007FE5 -+:10081000000500030006003F000700320008012C1D -+:1008200000090046000A0036001001B6001700A2B9 -+:100830000022013A00230149002000B400240125D0 -+:100840000027004D0028006A002A0060002B00529B -+:10085000002F0065003200870034017F003C015604 -+:10086000003F00720041018C0044012E00550173CD -+:100870000056017A0060000B00610034006200380D -+:1008800000630038006400380065003800660038F6 -+:10089000006700380068003A00690041006A0048BB -+:1008A000006B0048006C0048006D0048006E004876 -+:1008B000006F00480000000600000006000000066F -+:1008C0000000000600000006000000060000000610 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV635_me.bin.ihex b/firmware/radeon/RV635_me.bin.ihex -new file mode 100644 -index 0000000..ba3a7e6 ---- /dev/null -+++ b/firmware/radeon/RV635_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A000006044110000068A0000000000600000AB -+:1000B0000000062E00000000006000000000064264 -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:1006600000000000006000000000066500000000BF -+:1006700000600000000006590000000200210E2268 -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE00000000000006000000000065F0000000041 -+:100AF00000400000000000EB00000000006000006B -+:100B000000000662000000070020222D0000000007 -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E90000000068A0000001F002102300000000050 -+:100EA0000000000014C000000000068900000004DB -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000068A000000110021023000000000FE -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000068900000000002B140500000000B5 -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A000000000010000000000600000000006428E -+:1019B000000000000040040F0000021300000000BF -+:1019C000006000000000062E000000000060000023 -+:1019D0000000064200000210006004110000031520 -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B1000006000000000062E0000A00C0020441110 -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E300000042004006044110000068A0000000035 -+:101E4000006000000000062E00000000C0600000DE -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000006650000000000600000000002B53C -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:102240000000065C0000000000400000000002DE0C -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A00000000970000000020441125 -+:102600000000000000000000002048110000000051 -+:102610008A000000002044110000000000000000BB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D0000001A1FD002044110000000000000000E6 -+:1026E000D90048000000000000000000C0200400E5 -+:1026F000000000000000000000A0000A0000000030 -+:1027000000002257002044110000000000000003D8 -+:10271000C0484A20000000000000225D0020441153 -+:102720000000000000000000C04048000000000061 -+:1027300000000000006000000000064200000000F1 -+:10274000C0200800000000000000225C00204411AE -+:10275000000000000000000300384A2200000000D2 -+:102760000000A1FC00204411000000000000000057 -+:10277000C0204800000000000001A1FD002044111D -+:102780000000000000000000002F022200000000F6 -+:10279000000000000CE0000000000000000000004D -+:1027A00040204800000000000000000140304A20A6 -+:1027B0000000000000000002C0304A2000000000BD -+:1027C0000000000100530A220000034B0000003FFC -+:1027D000C0280A20000000008100000000204411F1 -+:1027E000000000000000000100204811000000006F -+:1027F000000021F800204411000000000000001833 -+:102800000020481100000000000421F9006044117C -+:102810000000068A000000110021023000000000C4 -+:102820000000000014E00000000003540000001449 -+:10283000002F022200000000000000000CC0000079 -+:10284000000003640000201000204411000000007C -+:102850000000800000204811000000000001A2A438 -+:102860000020441100000000000000000060480249 -+:102870000000036E00002100002044110000000051 -+:1028800000000000C0204800000000000000000020 -+:10289000C02048000000000000000000C0204800E8 -+:1028A0000000000000000000C040480000000000E0 -+:1028B00000000004002F02220000000000000000C1 -+:1028C0000CC000000000036A00002010002044112A -+:1028D00000000000000080000020481100000000FF -+:1028E0000001A2A40020441100000000000000002C -+:1028F000004048020000035F00000028002F022271 -+:1029000000000000000000000CC00000000005BD39 -+:102910000001A2A4002044110000000000000000FB -+:10292000004048020000035F0000002C0020362613 -+:102930000000000000000049002018110000000005 -+:102940000000003F002048110000000000000001CE -+:1029500000331A260000000000000000002F0226AD -+:1029600000000000000000000CC000000000037028 -+:102970000000002C00801A2D000000000000003F25 -+:10298000C0280A200000000000000015002F0222CD -+:1029900000000000000000000CE0000000000386C2 -+:1029A00000000006002F02220000000000000000CE -+:1029B0000CE00000000003B100000016002F02220E -+:1029C00000000000000000000CE00000000003B563 -+:1029D00000000020002F0222000000000000000084 -+:1029E0000CE000000000039C0000000F002F0222FA -+:1029F00000000000000000000CE00000000003A840 -+:102A000000000010002F0222000000000000000063 -+:102A10000CE00000000003A80000001E002F0222AE -+:102A200000000000000000000CE000000000039027 -+:102A30000000A2A4002044110000000000000000DB -+:102A400000404802000000000800000000290A229F -+:102A5000000000000000000340210E2000000000E4 -+:102A60000000000CC021122000000000000800003F -+:102A7000002812240000000000000014C0221620CC -+:102A80000000000000000000002914A40000000065 -+:102A90000000A2A40020441100000000000000007B -+:102AA000002948A2000000000000A1FE00204411FF -+:102AB000000000000000000000404803000000008B -+:102AC000810000000020441100000000000000010F -+:102AD0000020481100000000000021F800204411EF -+:102AE0000000000000000016002048110000000057 -+:102AF000000421F9006044110000068A000000155E -+:102B000000210230000000000000000014E000007E -+:102B1000000003920000210E00204411000000007C -+:102B200000000000C020480000000000000000007D -+:102B3000C0204800000000000000A2A400204411B2 -+:102B400000000000000000000040480200000000FB -+:102B5000810000000020441100000000000000017E -+:102B60000020481100000000000021F8002044115E -+:102B700000000000000000170020481100000000C5 -+:102B8000000421F9006044110000068A00000003DF -+:102B900000210230000000000000000014E00000EE -+:102BA0000000039E000021080020441100000000E6 -+:102BB00000000000C02048000000000000000000ED -+:102BC000C0204800000000000000A2A40020441122 -+:102BD000000000000000000000404802000000006B -+:102BE0000000A2A40020441100000000000000002A -+:102BF0000020480200000000800000000020441176 -+:102C0000000000000000000000204811000000004B -+:102C100081000000002044110000000000000010AE -+:102C200000204811000000000000000000200010FB -+:102C3000000000000000000014C00000000003AE0F -+:102C40000000000000400000000000000000201014 -+:102C50000020441100000000000080000020481106 -+:102C6000000000000001A2A40020441100000000A8 -+:102C70000000000600404811000000000000201085 -+:102C800000204411000000000000800000204811D6 -+:102C9000000000000001A2A4002044110000000078 -+:102CA00000000016006048110000036E00000000E4 -+:102CB000004000000000000000000000C0200800EC -+:102CC0000000000000000000C0200C000000000018 -+:102CD0000000001D00210223000000000000000091 -+:102CE00014E00000000003CE810000000020441129 -+:102CF000000000000000000100204811000000005A -+:102D0000000021F80020441100000000000000181D -+:102D10000020481100000000000421F90060441167 -+:102D20000000068A000000110021023000000000AF -+:102D30000000000014E00000000003C000002100BB -+:102D400000204411000000000000000000204802A4 -+:102D50000000000000000000002048030000000008 -+:102D6000BABECAFE0020481100000000CAFEBABE6A -+:102D70000020481100000000000020100020441135 -+:102D8000000000000000800000204811000000004A -+:102D90000000A2A400204411000000000000000474 -+:102DA0000040481100000000000021700020441184 -+:102DB00000000000000000000020480200000000A9 -+:102DC0000000000000204803000000008100000017 -+:102DD00000204411000000000000000A00204811FB -+:102DE00000000000000000000020001000000000B3 -+:102DF0000000000014C00000000003D38C0000009D -+:102E00000020441100000000CAFEBABE0040481174 -+:102E100000000000810000000020441100000000BC -+:102E200000000001002048110000000000003FFFEA -+:102E300040280A20000000008000000040280E20EA -+:102E40000000000040000000C02812200000000028 -+:102E500000040000006946220000068A000000000D -+:102E6000002014100000000000000000002F0223CA -+:102E700000000000000000000CC00000000003E1A2 -+:102E800000000000C0401800000003E400003FFF05 -+:102E9000C0281A2000000000000400000069462637 -+:102EA0000000068A0000000000201810000000004A -+:102EB00000000000002F02240000000000000000BD -+:102EC0000CC00000000003E700000000C0401C0030 -+:102ED000000003EA00003FFFC0281E2000000000A1 -+:102EE00000040000006946270000068A0000000078 -+:102EF00000201C1000000000000000000020440220 -+:102F00000000000000000000002820C500000000B4 -+:102F100000000000004948E800000000A580000013 -+:102F200000200811000000000000200000200C110B -+:102F30000000000083000000006044110000041243 -+:102F4000000000000020440200000000000000001B -+:102F5000C0204800000000000000000040204800A1 -+:102F6000000000000000001FC0210220000000003F -+:102F70000000000014C00000000003F70000201053 -+:102F800000204411000000000000800000204811D3 -+:102F9000000000000000FFFFC0481220000003FFF7 -+:102FA000A780000000200811000000000000A00021 -+:102FB00000200C110000000083000000006044119C -+:102FC0000000041200000000002044020000000085 -+:102FD00000000000C02048000000000000000000C9 -+:102FE000C0204800000000000000FFFFC0281220A1 -+:102FF00000000000830000000020441100000000D9 -+:103000000000000000304883000000008400000041 -+:10301000002044110000000000000000C020480013 -+:1030200000000000000000001D0000000000000083 -+:103030008300000000604411000004120000000042 -+:10304000C040040000000001A98000000020081119 -+:10305000000000000000C00000400C11000003FA56 -+:10306000AB80000000200811000000000000F8E024 -+:1030700000400C11000003FAAD8000000020081190 -+:10308000000000000000F88000400C11000003FA6E -+:10309000B380000000200811000000000000F3FCD5 -+:1030A00000400C11000003FAAF800000002008115E -+:1030B000000000000000E00000400C11000003FAD6 -+:1030C000B180000000200811000000000000F000A6 -+:1030D00000400C11000003FA83000000002044119E -+:1030E00000000000000021480020481100000000FE -+:1030F00084000000002044110000000000000000D7 -+:10310000C020480000000000000000001D0000007A -+:10311000000000000000000000800000000000002F -+:1031200001182000C0304620000000000000000010 -+:10313000D90048000000000000000000C02004008A -+:10314000000000000000000000A0000A00000000D5 -+:103150000218A000C030462000000000000000005F -+:10316000D90048000000000000000000C02004005A -+:10317000000000000000000000A0000A00000000A5 -+:103180000318C000C030462000000000000000000E -+:10319000D90048000000000000000000C02004002A -+:1031A000000000000000000000A0000A0000000075 -+:1031B0000418F8E0C03046200000000000000000C5 -+:1031C000D90048000000000000000000C0200400FA -+:1031D000000000000000000000A0000A0000000045 -+:1031E0000518F880C03046200000000000000000F4 -+:1031F000D90048000000000000000000C0200400CA -+:10320000000000000000000000A0000A0000000014 -+:103210000618E000C030462000000000000000005A -+:10322000D90048000000000000000000C020040099 -+:10323000000000000000000000A0000A00000000E4 -+:103240000718F000C0304620000000000000000019 -+:10325000D90048000000000000000000C020040069 -+:10326000000000000000000000A0000A00000000B4 -+:103270000818F3FCC03046200000000000000000E9 -+:10328000D90048000000000000000000C020040039 -+:10329000000000000000000000A0000A0000000084 -+:1032A0000000003000200A2D000000000000000097 -+:1032B000C0290C4000000000000000300020362330 -+:1032C0000000000000000000C0200400000000001A -+:1032D0000000000000A0000A0000000086000000BE -+:1032E00000204411000000000000000000404801E0 -+:1032F0000000000085000000C02044110000000014 -+:103300000000000000404801000000000000217C97 -+:10331000002044110000000000000000C020480010 -+:103320000000000000000000C02048000000000075 -+:1033300000000000C02048000000000081000000E4 -+:10334000002044110000000000000001002048118E -+:103350000000000000000000C02008000000000085 -+:103360000000000017000000000000000004217FA2 -+:10337000006044110000068A0000001F0021023096 -+:10338000000000000000000014C000000000000069 -+:103390000000000000404C02000004480000000053 -+:1033A000C0200C000000000000000000C020100041 -+:1033B0000000000000000000C02014000000000019 -+:1033C00000000000C0201800000000000000000005 -+:1033D000C0201C000000000000007F0000280A211F -+:1033E0000000000000004500002F02220000000045 -+:1033F000000000000CE00000000004560000000087 -+:10340000C0202000000000000000000017000000A5 -+:10341000000000000000001000280A230000000047 -+:1034200000000010002F0222000000000000000039 -+:103430000CE000000000045E810000000020441148 -+:103440000000000000000001002048110000000002 -+:1034500000040000006946240000068A0000000005 -+:1034600000400000000004638100000000204411BF -+:1034700000000000000000000020481100000000D3 -+:103480000000216D00204411000000000000000039 -+:103490000020480400000000000000000060480513 -+:1034A0000000068F00000000002824F0000000004B -+:1034B0000000000700280A230000000000000001AF -+:1034C000002F022200000000000000000AE00000BF -+:1034D0000000046A00000000002F00C90000000086 -+:1034E0000000000004E00000000004830000000071 -+:1034F000004000000000049000000002002F0222A3 -+:1035000000000000000000000AE000000000046F5E -+:1035100000000000002F00C90000000000000000B3 -+:1035200002E00000000004830000000000400000F2 -+:103530000000049000000003002F022200000000A1 -+:10354000000000000AE00000000004740000000019 -+:10355000002F00C900000000000000000CE0000087 -+:103560000000048300000000004000000000049000 -+:1035700000000004002F02220000000000000000F4 -+:103580000AE000000000047900000000002F00C9DC -+:1035900000000000000000000AE0000000000483BA -+:1035A0000000000000400000000004900000000542 -+:1035B000002F022200000000000000000AE00000CE -+:1035C0000000047E00000000002F00C90000000081 -+:1035D0000000000006E0000000000483000000007E -+:1035E000004000000000049000000006002F0222AE -+:1035F00000000000000000000AE00000000004835A -+:1036000000000000002F00C90000000000000000C2 -+:1036100008E00000000004830000000000400000FB -+:103620000000049000007F0000280A210000000034 -+:1036300000004500002F02220000000000000000F2 -+:103640000AE00000000000000000000800210A233A -+:10365000000000000000000014C000000000048D05 -+:10366000000021690020441100000000000000005B -+:10367000C02048000000000000000000C0204800FA -+:103680000000000000000000C02048000000000012 -+:10369000CAFEBABE00404811000000000000000051 -+:1036A000C02044000000000000000000C020000016 -+:1036B0000000000000000000C040480000000000C2 -+:1036C00000007F0000280A210000000000004500E3 -+:1036D000002F022200000000000000000AE00000AD -+:1036E0000000049600000000C02000000000000060 -+:1036F00000000000C02000000000000000000000EA -+:10370000C0400000000000000000000000404C0825 -+:103710000000045600000000C02008000000000067 -+:103720000000001040210E200000000000000011E9 -+:10373000402112200000000000000012402116204D -+:10374000000000000000216900204411000000007A -+:1037500000000000002048020000000000000000FF -+:1037600000210225000000000000000014E000001D -+:10377000000004A000040000C0494A20000004A189 -+:10378000FFFBFFFFC0284A200000000000000000EF -+:1037900000210223000000000000000014E00000EF -+:1037A000000004AD00000000C02048000000000040 -+:1037B00000000000C02048000000000000000000E1 -+:1037C00000210224000000000000000014C00000DE -+:1037D00000000000810000000020441100000000F3 -+:1037E0000000000C00204811000000000000000054 -+:1037F00000200010000000000000000014C00000C5 -+:10380000000004A9A00000000020441100000000F6 -+:10381000CAFEBABE0040481100000000810000004E -+:1038200000204411000000000000000400204811A6 -+:10383000000000000000216B002044110000000087 -+:1038400000000000C02048100000000081000000BF -+:103850000020441100000000000000050020481175 -+:10386000000000000000216C002044110000000056 -+:1038700000000000C0204810000000000000000010 -+:10388000002F022400000000000000000CE00000F7 -+:10389000000000000000000000400000000004A73D -+:1038A00000000000C0210A2000000000000000000D -+:1038B00014C00000000004C081000000002044117A -+:1038C000000000000000000000204811000000007F -+:1038D0000000216D002044110000000000000000E5 -+:1038E000C02048000000000000000000C060480048 -+:1038F0000000068F0000000000400000000004C42B -+:1039000081000000002044110000000000000001C0 -+:10391000002048110000000000040000C0294620DB -+:103920000000000000000000C06000000000068AE7 -+:103930000000000100210222000000000000000041 -+:1039400014C00000000004CB0000216900204411D5 -+:103950000000000000000000C0204800000000003F -+:1039600000000000C020480000000000000000002F -+:103970000020481000000000CAFEBABE00404811F6 -+:103980000000000000000000C02044000000000013 -+:1039900000000000C040481000000000810000004E -+:1039A0000020441100000000000000010020481128 -+:1039B00000000000000021F8002044110000000079 -+:1039C0000000000E0020481100000000000421F952 -+:1039D000006044110000068A00000000002102304F -+:1039E000000000000000000014C00000000004CD32 -+:1039F00000002180002044110000000000000000B1 -+:103A0000C02048000000000000000000C0200000AE -+:103A10000000000000000000C0204800000000007E -+:103A200000000000C02000000000000000000000B6 -+:103A3000C0404800000000000000000300333E2F9B -+:103A40000000000000000001002102210000000031 -+:103A50000000000014E00000000004FD0000002C45 -+:103A600000200A2D000000000004000018E00C11E6 -+:103A7000000004EC0000000100333E2F00000000B5 -+:103A80000000216900204411000000000000000037 -+:103A90000020480200000000000000000020480351 -+:103AA000000000000000000800300A2200000000B2 -+:103AB00000000000C02048000000000000000000DE -+:103AC000C0204800000000000000216900204411CF -+:103AD000000000000000000000204802000000007C -+:103AE0000000000000204803000000000000000863 -+:103AF00000300A220000000000000000C020480042 -+:103B00000000000000000000D8C04800000004E0F1 -+:103B100000002169002044110000000000000000A6 -+:103B200000204802000000000000000000204803C0 -+:103B3000000000000000000800300A220000000021 -+:103B400000000000C020480000000000000000004D -+:103B5000C0204800000000000000002D0020122DB1 -+:103B6000000000000000000000290C83000000009D -+:103B70000000216900204411000000000000000046 -+:103B80000020480200000000000000000020480360 -+:103B9000000000000000000800300A2200000000C1 -+:103BA00000000000C02048000000000000000000ED -+:103BB000C020480000000000000000110021022485 -+:103BC000000000000000000014C000000000000021 -+:103BD0000000000000400000000004A70000002CCE -+:103BE000C0203620000000000000002DC04036201C -+:103BF000000000000000000F002102210000000072 -+:103C00000000000014C000000000050200000000D9 -+:103C1000006000000000000B00000000D900000060 -+:103C20000000000000000000C0400400000000018F -+:103C3000B50000000020441100000000000020003A -+:103C40000020481100000000B600000000204411D0 -+:103C5000000000000000A00000204811000000004B -+:103C6000B700000000204411000000000000C00068 -+:103C70000020481100000000B8000000002044119E -+:103C8000000000000000F8E00020481100000000E3 -+:103C9000B900000000204411000000000000F8807E -+:103CA0000020481100000000BA000000002044116C -+:103CB000000000000000E0000020481100000000AB -+:103CC000BB00000000204411000000000000F000D4 -+:103CD0000020481100000000BC000000002044113A -+:103CE000000000000000F3FC00204811000000006C -+:103CF00081000000002044110000000000000002CC -+:103D00000020481100000000000000FF00280E30D5 -+:103D10000000000000000000002F0223000000004F -+:103D2000000000000CC000000000051600000000AC -+:103D3000C0200800000000000000000014C00000C7 -+:103D40000000052B0000000000200C110000000006 -+:103D50000000001C00203623000000000000002BA3 -+:103D60000020362300000000000000290020362338 -+:103D700000000000000000280020362300000000A2 -+:103D8000000000170020362300000000000000257E -+:103D9000002036230000000000000026002036230B -+:103DA0000000000000000015002036230000000085 -+:103DB000000000160020362300000000FFFFE00096 -+:103DC00000200C110000000000000021002036231C -+:103DD0000000000000000022002036230000000048 -+:103DE00000001FFF00200C11000000000000002355 -+:103DF00000203623000000000000002400203623AD -+:103E000000000000F1FFFFFF00283A2E0000000034 -+:103E10000000001AC0220E20000000000000000078 -+:103E20000029386E000000008100000000204411CD -+:103E30000000000000000006002048110000000003 -+:103E40000000002A4020362000000000870000000B -+:103E5000002044110000000000000000C0204800C5 -+:103E6000000000000000A1F4002044110000000048 -+:103E700000000000002048100000000000000000CA -+:103E800000200C110000000000000030002036234C -+:103E9000000000009D000000002044110000000010 -+:103EA0000000001F40214A20000000009600000092 -+:103EB000002044110000000000000000C020480065 -+:103EC0000000000000000000C0200C000000000006 -+:103ED00000000000C0201000000000000000001FD3 -+:103EE00000211624000000000000000014C00000A3 -+:103EF000000000000000001D00203623000000002C -+:103F00000000000300281E2300000000000000083D -+:103F10000022222300000000FFFFF00000282228DA -+:103F20000000000000000000002920E80000000060 -+:103F30000000001F002036280000000000000018CC -+:103F400000211E2300000000000000200020362772 -+:103F50000000000000000002002216240000000003 -+:103F600000000000003014A8000000000000001E47 -+:103F700000203625000000000000000300211A2464 -+:103F8000000000001000000000281A2600000000B9 -+:103F9000EFFFFFFF00283A2E0000000000000000A5 -+:103FA000004938CE000006780000000140280A20B1 -+:103FB000000000000000000640280E200000000065 -+:103FC00000000300C02812200000000000000008CC -+:103FD000002112240000000000000000C020162074 -+:103FE0000000000000000000C0201A2000000000B7 -+:103FF000000000000021022200000000000000007C -+:1040000014C000000000056381000000002044117E -+:104010000000000000000001002048110000000026 -+:104020000000225800300A240000000000040000B4 -+:10403000006946220000068A000021690020441120 -+:104040000000000000000000002048050000000003 -+:104050000002000000294A260000000000000000C5 -+:104060000020481000000000CAFEBABE002048111F -+:104070000000000000000002002F022300000000EA -+:10408000000000000CC000000000056B00000000F4 -+:10409000C0201C100000000000000000C040000014 -+:1040A0000000057900000002002F0223000000003C -+:1040B000000000000CC000000000056B8100000043 -+:1040C0000020441100000000000000010020481101 -+:1040D000000000000000225800300A240000000008 -+:1040E00000040000006946220000068A000000006B -+:1040F000C0201C100000000000000000C0400000B4 -+:104100000000057900000000002F022300000000DD -+:10411000000000000CC000000000056F000000005F -+:10412000C0201C000000000000000000C040000093 -+:104130000000057900000004002F022300000000A9 -+:10414000000000000CC000000000057781000000A6 -+:104150000020441100000000000000000020481171 -+:10416000000000000000216D00204411000000004C -+:1041700000000000C0204800000000000000000017 -+:10418000C06048000000068F0000000000401C10C6 -+:104190000000057900000000C020000000000000C1 -+:1041A00000000000C040000000000000000000000F -+:1041B0000EE000000000057B000000000060000031 -+:1041C000000005C600000000002F022400000000CF -+:1041D000000000000CC000000000058C0000A2B729 -+:1041E00000204411000000000000000000204807EB -+:1041F00000000000810000000020441100000000C9 -+:104200000000000100204811000000000004A2B6D8 -+:10421000006044110000068A0000001A00212230CC -+:104220000000000000000006002226300000000010 -+:1042300000042004006044110000068A0000A2C4AB -+:10424000002044110000000000000000003048E998 -+:10425000000000000000000000E000000000058AEF -+:104260000000A2D100204411000000000000000066 -+:1042700000404808000000000000A2D100204411C6 -+:10428000000000000000000100504A28000000006B -+:1042900000000001002F02240000000000000000C8 -+:1042A0000CC000000000059D0000A2BB00204411CE -+:1042B000000000000000000000204807000000008F -+:1042C00081000000002044110000000000000001F7 -+:1042D00000204811000000000004A2BA0060441150 -+:1042E0000000068A0000001A0021223000000000B1 -+:1042F0000000000600222630000000000004200418 -+:10430000006044110000068A0000A2C5002044118C -+:104310000000000000000000003048E9000000003C -+:104320000000000000E000000000059B0000A2D299 -+:104330000020441100000000000000000040480878 -+:10434000000000000000A2D2002044110000000084 -+:104350000000000100504A28000000000000000298 -+:10436000002F022400000000000000000CC000002C -+:10437000000005AE0000A2BF0020441100000000B4 -+:10438000000000000020480700000000810000003D -+:10439000002044110000000000000001002048112E -+:1043A000000000000004A2BE006044110000068A64 -+:1043B0000000001A0021223000000000000000066A -+:1043C0000022263000000000000420040060441198 -+:1043D0000000068A0000A2C6002044110000000070 -+:1043E00000000000003048E900000000000000006C -+:1043F00000E00000000005AC0000A2D30020441142 -+:10440000000000000000000000404808000000001C -+:104410000000A2D3002044110000000000000001B1 -+:1044200000504A28000000000000A2C300204411F0 -+:10443000000000000000000000204807000000000D -+:104440008100000000204411000000000000000175 -+:1044500000204811000000000004A2C200604411C6 -+:104460000000068A0000001A00212230000000002F -+:104470000000000600222630000000000004200496 -+:10448000006044110000068A0000A2C70020441109 -+:104490000000000000000000003048E900000000BB -+:1044A0000000000000E00000000005BB0000A2D4F6 -+:1044B00000204411000000000000000000404808F7 -+:1044C000000000000000A2D4002044110000000001 -+:1044D0000000000100504A28000000008500000094 -+:1044E00000204411000000000000000000204801EE -+:1044F000000000000000304A0020441100000000CD -+:104500000100000000204811000000000000000031 -+:1045100000400000000005C1A4000000C0204411BC -+:104520000000000000000000C04048000000000043 -+:1045300000000000C0600000000005C60000000090 -+:10454000C0400400000000010000002C00203621C3 -+:104550000000000081000000002044110000000065 -+:1045600000000006002048110000000000000000CC -+:10457000002F023000000000000000000CC000000E -+:10458000000005CD00000000002004110000000024 -+:104590000000003000403621000005E0000000303F -+:1045A0000020062D0000000000007E0000280621EB -+:1045B0000000000000000000002F022100000000A9 -+:1045C000000000000CE00000000005E08100000099 -+:1045D00000204411000000000000000100204811EC -+:1045E000000000000004A092006044110000068A50 -+:1045F0000000003100203630000000000004A093CD -+:10460000006044110000068A0000003200203630AD -+:10461000000000000004A2B6006044110000068AF9 -+:104620000000003300203630000000000004A2BA71 -+:10463000006044110000068A00000034002036307B -+:10464000000000000004A2BE006044110000068AC1 -+:104650000000003500203630000000000004A2C237 -+:10466000006044110000068A000000360020363049 -+:104670000000000000042004006044110000068ACD -+:104680000001A2A400204411000000000000003F2F -+:1046900000204811000000000000003F00204811E9 -+:1046A000000000000000003F002048110000000052 -+:1046B0000000003F0020481100000000000000053D -+:1046C00000204811000000000000A1F40020441167 -+:1046D0000000000000000000002048110000000061 -+:1046E00088000000002044110000000000000001CC -+:1046F000002048110000000081000000002044114B -+:10470000000000000000000600204811000000002A -+:1047100000000001002F0230000000000000000037 -+:104720000CE0000000000629000000300020062DEB -+:104730000000000000000000002F02210000000027 -+:10474000000000000CE000000000062981000000CD -+:10475000002044110000000000000001002048116A -+:104760000000000000007E0000280621000000007C -+:1047700000000000002F02210000000000000000E7 -+:104780000CE00000000006020000A092002044118E -+:10479000000000000000003100204A2D0000000051 -+:1047A0000000A0930020441100000000000000322F -+:1047B00000204A2D000000000000A2B60020441195 -+:1047C000000000000000003300204A2D000000001F -+:1047D0000000A2BA002044110000000000000034D4 -+:1047E00000204A2D000000000000A2BE002044115D -+:1047F000000000000000003500204A2D00000000ED -+:104800000000A2C200204411000000000000003699 -+:1048100000204A2D00000000000000300020062D7E -+:1048200000000000000001FF002806210000000039 -+:1048300000000000002F0221000000000000000026 -+:104840000CE000000000062800000000002102210A -+:10485000000000000000000014C000000000060B73 -+:104860000004A003006044110000068A0000A003B9 -+:10487000002044110000000000000000002048104B -+:1048800000000000000000010021062100000000DF -+:104890000000000014C00000000006100004A0107A -+:1048A000006044110000068A0000A010002044119E -+:1048B0000000000000000000002048100000000080 -+:1048C000000000010021062100000000000000009F -+:1048D000002F022100000000000000000CE000009A -+:1048E000000006280004A011006044110000068AA0 -+:1048F0000000A01100204411000000000000000092 -+:1049000000204810000000000004A01200604411C4 -+:104910000000068A0000A0120020441100000000E0 -+:104920000000000000204810000000000004A01358 -+:10493000006044110000068A0000A013002044110A -+:1049400000000000000000000020481000000000EF -+:104950000004A014006044110000068A0000A014A6 -+:10496000002044110000000000000000002048105A -+:10497000000000000004A015006044110000068A39 -+:104980000000A015002044110000000000000000FD -+:1049900000204810000000000004A0160060441130 -+:1049A0000000068A0000A01600204411000000004C -+:1049B0000000000000204810000000000004A017C4 -+:1049C000006044110000068A0000A0170020441176 -+:1049D000000000000000000000204810000000005F -+:1049E00000042004006044110000068A0000002C2E -+:1049F0000080062D00000000FF0000000020441190 -+:104A0000000000000000000000204811000000002D -+:104A1000000000010020481100000000000000021A -+:104A20000080481100000000000000000EE00000BF -+:104A30000000063A000000300020062D00000000B3 -+:104A40000000000200280621000000000000000015 -+:104A5000002F022100000000000000000CE0000018 -+:104A60000000063881000000002044110000000012 -+:104A70000000000100204811000000000004200494 -+:104A8000006044110000068A000010000020081198 -+:104A9000000000000000002B002036220000000073 -+:104AA00000000000006000000000063E0000000062 -+:104AB00000600000000005C69800000000204411BE -+:104AC000000000000000000000804811000000000D -+:104AD00000000000C06000000000063E0000000072 -+:104AE000C0400400000000010000A2A40020441106 -+:104AF000000000000000002200204811000000001B -+:104B000089000000002044110000000000000001A6 -+:104B1000004048110000062A9700000000204411C0 -+:104B2000000000000000000000204811000000000C -+:104B30008A00000000204411000000000000000076 -+:104B4000004048110000062A00000000006000003C -+:104B50000000065900002010002044110000000051 -+:104B60000000800000204811000000000001A2A405 -+:104B7000C020441100000000000000160060481131 -+:104B80000000036E0000201000204411000000000F -+:104B9000000100000020481100000000810000001A -+:104BA0000020441100000000000000010020481116 -+:104BB000000000000000217C0020441100000000E3 -+:104BC000098000000020481100000000FFFFFFFFE7 -+:104BD00000204811000000000000000000204811E3 -+:104BE00000000000000000001700000000000000AE -+:104BF0000004217F006044110000068A0000001FAD -+:104C000000210230000000000000000014C000007D -+:104C1000000000000000000400404C11000006539A -+:104C2000000000000040000000000000000000172D -+:104C300000201E2D000000000000000400291E2797 -+:104C40000000000000000017008036270000000070 -+:104C50000000001700201E2D00000000FFFFFFFBDA -+:104C600000281E27000000000000001700803627E3 -+:104C7000000000000000001700201E2D00000000B2 -+:104C80000000000800291E27000000000000001797 -+:104C900000803627000000000000001700201E2DB5 -+:104CA00000000000FFFFFFF700281E2700000000A3 -+:104CB00000000017008036270000000000002010D0 -+:104CC0000020441100000000000080000020481176 -+:104CD000000000000001A2A4002044110000000018 -+:104CE00000000016006048110000036E0000201054 -+:104CF00000204411000000000001000000204811C5 -+:104D0000000000000000217C002044110000000091 -+:104D1000018000000020481100000000FFFFFFFF9D -+:104D20000020481100000000000000000020481191 -+:104D3000000000000000000017000000000000005C -+:104D4000810000000020441100000000000000016C -+:104D500000204811000000000004217F0060441181 -+:104D60000000068A0000001F002102300000000041 -+:104D70000000000014C000000000068900000010C0 -+:104D800000404C110000066F00000000C02004002D -+:104D9000000000000000000038C00000000000001B -+:104DA0000000001D00200A2D000000000000001E71 -+:104DB00000200E2D000000000000001F0020122D1A -+:104DC00000000000000000200020162D0000000060 -+:104DD00000002169002044110000000000000000D4 -+:104DE00000204804000000000000000000204805EA -+:104DF000000000000000000000204801000000004A -+:104E0000CAFEBABE002048110000000000000004E5 -+:104E1000003012240000000000000000002F006499 -+:104E200000000000000000000CC000000000068828 -+:104E30000000000300281A22000000000000000803 -+:104E40000022122200000000FFFFF00000281224C0 -+:104E50000000000000000000002910C40000000055 -+:104E60000000001F00403624000000000000000089 -+:104E70000080000000000000000000001AC00000D8 -+:104E80000000068A9F00000000204411000000007E -+:104E9000CAFEBABE00204811000000000000000059 -+:104EA0001AE000000000068D0000000000800000F5 -+:104EB00000000000000000001AC000000000068F83 -+:104EC0009E0000000020441100000000CAFEBABE8F -+:104ED0000020481100000000000000001AE000005F -+:104EE00000000692000000000080000000000000AA -+:104EF00000000000006000000000000B0000100037 -+:104F000000600411000003150000000000200411DF -+:104F1000000000000000000000600811000001B265 -+:104F20000000225C0020441100000000000000038B -+:104F3000002048110000000000002256002044110B -+:104F4000000000000000001B0020481100000000CD -+:104F50000000A1FC0020441100000000000000013E -+:104F600000204811000000000001A1FDC0204411F4 -+:104F7000000000000000002100201E2D00000000A5 -+:104F80000000001000221E27000000000000002486 -+:104F90000020222D000000000000FFFF0028222832 -+:104FA0000000000000000000002949070000000088 -+:104FB0000000000000204811000000000000002256 -+:104FC0000020222D000000000000FFFF0028222802 -+:104FD0000000000000000000002949070000000058 -+:104FE0000000000000204811000000000000002325 -+:104FF00000201E2D000000000000001000221E27CF -+:105000000000000000000000002949070000000027 -+:1050100000000000004048110000000000000000F7 -+:105020000000000000000000000000000000000080 -+:105030000000000000000000000000000000000070 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B000014204FF05BD02500000000001C3016867 -+:1052C000043F05BD00000000022502090250015103 -+:1052D000000000000223024502A00241000000007D -+:1052E00003D705BD05BD05BD000000000646064705 -+:1052F000031F05BD0000000005BD05C203200340DB -+:1053000000000000032A0282034203340000000070 -+:1053100005BD05BD05BD05BD0000000005BD054E70 -+:1053200005BD05BD0000000003BA05BD04B8034477 -+:10533000000000000497044D043D05BD000000007E -+:1053400004CD05BD044104DA00000000044D05044D -+:10535000035103750000000005BD05BD05BD05BD79 -+:105360000000000005BD05BD05BD05BD0000000035 -+:1053700005BD05BD063C05C40000000005BD05BD1A -+:10538000000705BD0000000005BD05BD05BD05BD4C -+:105390000000000005BD05BD05BD05BD0000000005 -+:1053A00003F803ED0408040600000000040E040ADC -+:1053B000040C041000000000041C04180424042041 -+:1053C00000000000042C0428043404300000000015 -+:1053D00005BD05BD043805BD0000000005BD05BDC7 -+:1053E00005BD05BD0000000005BD05BD05BD05BD31 -+:1053F000000000000002067606940006000000008F -+:00000001FF -diff --git a/firmware/radeon/RV635_pfp.bin.ihex b/firmware/radeon/RV635_pfp.bin.ihex -new file mode 100644 -index 0000000..f55292c ---- /dev/null -+++ b/firmware/radeon/RV635_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001B8007C038B00D4401E00EE001E5F -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581A800C41C3A08 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFF000042C0400309002007D250049 -+:1000700000351402007D350B00255403007CD5802B -+:1000800000259C030095C00400D5001B007EDDC147 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA180000D4401E00D5801EAD -+:100140000080005300D4007500D4401E00CA08008F -+:1001500000CA0C0000CA100000D4801900D4C018D6 -+:1001600000D5001700D4801E00D4C01E00D5001E8C -+:1001700000E2001E00CA040000A00000007E828B86 -+:1001800000CA080000D4806000D4401E0080000037 -+:1001900000D4801E00CA080000D4806100D4401E34 -+:1001A0000080000000D4801E00CA080000CA0C00B5 -+:1001B00000D4401E00D4801600D4C01600D4801E87 -+:1001C000008001B800D4C01E00C6084300CA0C005D -+:1001D00000CA10000094800400CA140000E420F358 -+:1001E00000D4201300D5606500D4E01C00D5201C8D -+:1001F00000D5601C008000000006200100C60843F6 -+:1002000000CA0C0000CA1000009483F700CA140052 -+:1002100000E420F30080007900D4201300C60843D6 -+:1002200000CA0C0000CA1000009883EF00CA140036 -+:1002300000D400640080008D0000000000C414326F -+:1002400000C6184300C4082F0095400500C40C30B8 -+:1002500000D4401E0080000000EE001E009583F5D3 -+:1002600000C4103100D4403300D5206500D4A01C58 -+:1002700000D4E01C00D5201C00E4015E00D4001E68 -+:10028000008000000006200100CA1800000A2001BA -+:1002900000D6007600C408360098800700C61045D6 -+:1002A0000095011000D4001F00D46062008000009F -+:1002B00000D4206200CC383500CC1433008401BB5C -+:1002C00000D4007200D5401E0080000000EE001E29 -+:1002D00000E2001A008401BB00E2001A00CC104BBF -+:1002E00000CC0447002C9401007D098B0098400548 -+:1002F000007D15CB00D4001A008001B800D4006D39 -+:100300000034440100CC0C480098403A00CC2C4A00 -+:100310000095800400CC0449008001B800D4001A84 -+:1003200000D4C01A00282801008400F000CC10037B -+:100330000098801B0004380C008400F000CC1003EF -+:100340000098801700043808008400F000CC1003E7 -+:100350000098801300043804008400F000CC1003DF -+:100360000098801400CC104C009A800900CC144DE9 -+:10037000009840DC00D4006D00CC184800D5001A6D -+:1003800000D5401A008000C900D5801A0096C0D55B -+:1003900000D4006D008001B800D4006E009AC00344 -+:1003A00000D4006D00D4006E0080000000EC007FDF -+:1003B000009AC0CC00D4006D008001B800D4006E5B -+:1003C00000CC140300CC180300CC1C03007D910367 -+:1003D000007DD583007D190C0035CC1F0035701FC2 -+:1003E000007CF0CB007CD08B00880000007E8E8BE0 -+:1003F0000095C00400D4006E008001B800D4001A3B -+:1004000000D4C01A00CC080300CC0C0300CC1003AD -+:1004100000CC140300CC180300CC1C0300CC240334 -+:1004200000CC28030035C41F0036B01F007C704B81 -+:100430000034F01F007C704B0035701F007C704B47 -+:10044000007D8881007DCCC1007E5101007E9541F8 -+:10045000007C9082007CD4C2007C848B009AC00314 -+:10046000007C8C8B002C88010098809E00D4006D4D -+:100470000098409C00D4006E00CC084C00CC0C4D81 -+:1004800000CC104800D4801A00D4C01A00800101AA -+:1004900000D5001A00CC083200D40032009482D972 -+:1004A00000CA0C0000D4401E0080000000D4001ED2 -+:1004B00000E4011E00D4001E00CA080000CA0C009F -+:1004C00000CA100000D4401E00CA140000D4801ED0 -+:1004D00000D4C01E00D5001E00D5401E00D54034FB -+:1004E0000080000000EE001E0028040400E2001A54 -+:1004F00000E2001A00D4401A00CA380000CC0803F9 -+:1005000000CC0C0300CC0C0300CC0C03009882BD83 -+:1005100000000000008401BB00D7A06F0080000035 -+:1005200000EE001F00CA040000C2FF0000CC083427 -+:1005300000C13FFF007C74CB007CC90B007D010F24 -+:10054000009902B0007C738B008401BB00D7A06FC0 -+:100550000080000000EE001F00CA080000281900FB -+:10056000007D898B009580140028140400CA0C00BB -+:1005700000CA100000CA1C0000CA240000E2001FCC -+:1005800000D4C01A00D5001A00D5401A00CC1803B8 -+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -+:1005A000007D9C4700984297000000000080016198 -+:1005B00000D4C01A00D4401E00D4801E0080000069 -+:1005C00000EE001E00E4011E00D4001E00D4401EF8 -+:1005D00000EE001E00CA040000A00000007E828B16 -+:1005E00000E4013E00D4001E00D4401E00EE001EB8 -+:1005F00000CA040000A00000007E828B00CA080030 -+:1006000000248C06000CCC060098C00600CC104ECE -+:100610000099000400D4007300E4011E00D4001E01 -+:1006200000D4401E00D4801E0080000000EE001E9A -+:1006300000CA080000CA0C000034D01800251001C0 -+:100640000095002100C17FFF00CA100000CA1400FD -+:1006500000CA180000D4801D00D4C01D007DB18BDD -+:1006600000C1420200C2C00100D5801D0034DC0E72 -+:10067000007D5D4C007F734C00D7401E00D5001EEE -+:1006800000D5401E00C1420000C2C00000099C010C -+:100690000031DC10007F5F4C007F734C00042802A7 -+:1006A000007D838000D5A86F00D5806600D7401EEE -+:1006B00000EC005E00C8240200C82402008001B8DB -+:1006C00000D6007600D4401E00D4801E00D4C01E88 -+:1006D0000080000000EE001E0080000000EE001F01 -+:1006E00000D4001F0080000000D4001F00D4001FB1 -+:1006F0000088000000D4001F00000000000000007F -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:1008000000010171000201780003008F0004007FE5 -+:10081000000500030006003F000700320008012C1D -+:1008200000090046000A0036001001B6001700A2B9 -+:100830000022013A00230149002000B400240125D0 -+:100840000027004D0028006A002A0060002B00529B -+:10085000002F0065003200870034017F003C015604 -+:10086000003F00720041018C0044012E00550173CD -+:100870000056017A0060000B00610034006200380D -+:1008800000630038006400380065003800660038F6 -+:10089000006700380068003A00690041006A0048BB -+:1008A000006B0048006C0048006D0048006E004876 -+:1008B000006F00480000000600000006000000066F -+:1008C0000000000600000006000000060000000610 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV670_me.bin.ihex b/firmware/radeon/RV670_me.bin.ihex -new file mode 100644 -index 0000000..9fbfc0e ---- /dev/null -+++ b/firmware/radeon/RV670_me.bin.ihex -@@ -0,0 +1,1345 @@ -+:1000000000000000C020040000000000000000000C -+:1000100000A0000A000000000000FFFF00284621A9 -+:100020000000000000000000D900480000000000AF -+:1000300000000000C02004000000000000000000DC -+:1000400000A0000A000000000000000000E0000026 -+:100050000000000000010000C02946200000000050 -+:1000600000000000D900480000000000000000006F -+:10007000C0200400000000000000000000A0000AF2 -+:10008000000000008100000000204411000000007A -+:1000900000000001002048110000000000042004BE -+:1000A000006044110000067C0000000000600000B9 -+:1000B0000000062400000000006000000000063878 -+:1000C00000000000C02008000000000000000F0039 -+:1000D000002816220000000000000008002116255C -+:1000E000000000000000001800203625000000007D -+:1000F0008D000000002044110000000000000004FA -+:10010000002F022500000000000000000CE00000AD -+:1001100000000018004120000040481100000019B4 -+:100120000042200000204811000000008E00000066 -+:1001300000204411000000000000002800204A2D8B -+:1001400000000000900000000020441100000000AA -+:100150000000000000204805000000000000000C26 -+:1001600000211622000000000000000300281625D0 -+:10017000000000000000001900211A220000000009 -+:100180000000000400281A26000000000000000003 -+:10019000002914C5000000000000001900203625C9 -+:1001A0000000000000000000003A140200000000FF -+:1001B00000000016002116250000000000000003CA -+:1001C00000281625000000000000001700200E2D5A -+:1001D00000000000FFFFFFFC00280E2300000000CD -+:1001E00000000000002914A3000000000000001718 -+:1001F00000203625000000000000800000280E22AC -+:10020000000000000000000700220E230000000094 -+:10021000000000000029386E0000000020000000EF -+:1002200000280E22000000000000000600210E231E -+:1002300000000000000000000029386E00000000EF -+:100240000000000000220222000000000000000068 -+:1002500014E0000000000038000000002EE0000064 -+:1002600000000035000000002CE000000000003716 -+:100270000000000000400E2D0000003900000008C2 -+:1002800000200E2D00000000000000090040122D8B -+:10029000000000460000000100400E2D0000003963 -+:1002A00000000000C0200C0000000000003FFFFC28 -+:1002B0000028122300000000000000020022122487 -+:1002C000000000000000001F00211E2300000000AD -+:1002D0000000000014E000000000003E00000008E4 -+:1002E00000401C11000000410000000D00201E2DE8 -+:1002F000000000000000000F00281E270000000082 -+:100300000000000300221E27000000007FC0000044 -+:1003100000281A23000000000000001400211A2603 -+:10032000000000000000000100331A260000000059 -+:100330000000000800221A26000000000000000053 -+:1003400000290CC700000000000000270020362410 -+:100350000000000000007F000028122100000000C3 -+:1003600000001400002F0224000000000000000024 -+:100370000CE000000000004B0000000100290E23EB -+:10038000000000000000000E0020362300000000E6 -+:100390000000E0000020441100000000FFF8000011 -+:1003A00000294A230000000000000000003A2C024F -+:1003B000000000000000000200220E2B00000000E0 -+:1003C000FC00000000280E23000000000000000FC9 -+:1003D000002036230000000000001FFF00294A23F0 -+:1003E000000000000000002700204A2D000000004F -+:1003F000000000000020481100000000000000295B -+:1004000000200E2D00000000060A020000294A23E9 -+:100410000000000000000000002048110000000063 -+:100420000000000000204811000000000000000152 -+:1004300000210222000000000000000014E0000083 -+:1004400000000061000000002EE000000000005FDE -+:10045000000000002CE000000000005E0000000032 -+:1004600000400E2D000000620000000100400E2D33 -+:10047000000000620000000A00200E2D00000000B5 -+:100480000000000B0040122D0000006A0000000078 -+:10049000C0200C0000000000003FFFFC00281223D9 -+:1004A00000000000000000020022122400000000F2 -+:1004B0007FC0000000281623000000000000001488 -+:1004C0000021162500000000000000010033162561 -+:1004D000000000008000000000280E230000000043 -+:1004E0000000000000290CA3000000003FFFFC00FA -+:1004F00000290E23000000000000001F00211E2321 -+:10050000000000000000000014E000000000006D8A -+:100510000000010000401C11000000700000000DF0 -+:1005200000201E2D00000000000000F000281E2703 -+:10053000000000000000000400221E270000000050 -+:100540008100000000204411000000000000000DA8 -+:100550000020481100000000FFFFF0FF00281A30C3 -+:10056000000000000000A02800204411000000004E -+:1005700000000000002948E6000000000000A0186C -+:1005800000204411000000003FFFFFFF00284A2325 -+:10059000000000000000A010002044110000000036 -+:1005A00000000000002048040000000000000030AF -+:1005B0000020162D00000000000000020029162572 -+:1005C0000000000000000030002036250000000080 -+:1005D000000000250020162D000000000000000093 -+:1005E000002F00A300000000000000000CC000006D -+:1005F00000000083000000260020162D00000000EF -+:1006000000000000002F00A4000000000000000017 -+:100610000CC000000000008400000000004000004A -+:100620000000008A000000250020362300000000A2 -+:100630000000002600203624000000000000001703 -+:1006400000201E2D000000000000000200210227F3 -+:10065000000000000000000014E000000000008A1C -+:1006600000000000006000000000065900000000CB -+:10067000006000000000064D0000000200210E2274 -+:10068000000000000000000014C000000000008D09 -+:1006900000000012C040362000000093000000005F -+:1006A0002EE0000000000091000000002CE000009F -+:1006B000000000900000000200400E2D000000929B -+:1006C0000000000300400E2D000000920000000C0E -+:1006D00000200E2D00000000000000120020362334 -+:1006E000000000000000000300210E2200000000B6 -+:1006F0000000000014C00000000000980000A00CE2 -+:10070000002044110000000000000000C02048004C -+:100710000000000000000000C0404800000000A0F1 -+:100720000000A00C002044110000000000000000A8 -+:100730000020481100000000000000002EE0000032 -+:100740000000009E000000002CE000000000009D62 -+:100750000000000200400E2D0000009F000000037A -+:1007600000400E2D0000009F0000000C00200E2D08 -+:10077000000000000000000000204803000000000E -+:1007800000000000003A0C0200000000003F0000E2 -+:1007900000280E23000000000000001000210E239E -+:1007A00000000000000000110020362300000000BF -+:1007B0000000001E0021022B0000000000000000CD -+:1007C00014C00000000000A700000016C020362062 -+:1007D000000000000000001F0021022B00000000AC -+:1007E0000000000014C00000000000AA0000001576 -+:1007F000C0203620000000000000000800210E2B61 -+:10080000000000000000007F00280E230000000010 -+:1008100000000000002F0223000000000000000084 -+:100820000CE00000000000E10000000027000000D4 -+:10083000000000000000000000600000000002A3B3 -+:1008400000000001002F0223000000000000000053 -+:100850000AE00000000000B300000000006000009B -+:100860000000013A81000000002044110000000057 -+:100870000000000600204811000000000000000CED -+:1008800000221E300000000099800000002044116A -+:1008900000000000000000040020122D00000000F5 -+:1008A00000000008002212240000000000000010D8 -+:1008B00000201811000000000000000000291CE4C6 -+:1008C0000000000000000000006048070000012F49 -+:1008D0009B00000000204411000000000000000008 -+:1008E00000204802000000009C000000002044118D -+:1008F00000000000000000000033146F0000000042 -+:100900000000000100333E23000000000000000052 -+:10091000D9004800000000000000000000203C0555 -+:1009200000000000810000000020441100000000D1 -+:100930000000000E00204811000000000000000030 -+:1009400000201010000000000000E007002044110B -+:10095000000000000000000F0021022B000000003A -+:100960000000000014C00000000000CB00F8FF08E9 -+:1009700000204811000000009800000000404811CD -+:10098000000000DC000000F000280E220000000043 -+:10099000000000A0002F0223000000000000000063 -+:1009A0000CC00000000000DA0000001100200E2D35 -+:1009B0000000000000000001002F022300000000E2 -+:1009C000000000000CE00000000000D50000000264 -+:1009D000002F022300000000000000000CE00000D7 -+:1009E000000000D400003F0000400C11000000D6C1 -+:1009F00000001F0000400C11000000D600000F0096 -+:100A000000200C11000000000038000900294A23D2 -+:100A1000000000003F00000000280E2B0000000036 -+:100A20000000000200220E2300000000000000076A -+:100A300000494A23000000DC00380F09002048115B -+:100A400000000000680000070020481100000000BE -+:100A50000000000800214A270000000000000000FC -+:100A60000020481100000000060A020000294A2464 -+:100A700000000000000000000020481100000000FD -+:100A80000000000000204811000000000000A20249 -+:100A9000002044110000000000FF000000280E228A -+:100AA000000000000000008000294A230000000030 -+:100AB0000000002700200E2D00000000000000268E -+:100AC0000020122D0000000000000000002F008315 -+:100AD00000000000000000000CE00000000000EA40 -+:100AE000000000000060000000000653000000004D -+:100AF00000400000000000EB00000000006000006B -+:100B000000000656000000070020222D0000000013 -+:100B10000000000500220E2200000000001000006E -+:100B200000280E23000000000000000000292068BB -+:100B30000000000000000000003A0C02000000006D -+:100B4000000000EF00280E2300000000000000005D -+:100B500000292068000000000000001700200E2D72 -+:100B6000000000000000000300210223000000003C -+:100B70000000000014E00000000000F80000000B7E -+:100B800000210228000000000000000014C0000046 -+:100B9000000000F8000004000029222800000000E6 -+:100BA0000000001400203628000000000000001C97 -+:100BB00000210E22000000000000000014C0000010 -+:100BC000000000FD0000A30C002044110000000004 -+:100BD0000000000000204811000000000000001E7E -+:100BE00000210E22000000000000000014C00000E0 -+:100BF0000000010B0000A30F0020441100000000C2 -+:100C00000000001100200E2D000000000000000177 -+:100C1000002F022300000000000000000CC00000B4 -+:100C200000000104FFFFFFFF004048110000010B1E -+:100C300000000002002F022300000000000000005E -+:100C40000CC00000000001070000FFFF0040481139 -+:100C50000000010B00000004002F02230000000030 -+:100C6000000000000CC000000000010A000000FFAE -+:100C7000004048110000010B000000010020481155 -+:100C8000000000000002C400002044110000000029 -+:100C90000000001F00210E220000000000000000E4 -+:100CA00014C00000000001120000001040210E20BE -+:100CB00000000000000000130020362300000000A8 -+:100CC0000000001840224A20000000000000001030 -+:100CD000C0424A20000001140000000000200C1156 -+:100CE0000000000000000013002036230000000078 -+:100CF000000000000020481100000000000000007B -+:100D000000204811000000000000000A002010111F -+:100D10000000000000000000002F0224000000007E -+:100D2000000000000CE000000000011B00000000BB -+:100D300000204811000000000000000100531224B0 -+:100D400000000117FFBFFFFF00283A2E000000003F -+:100D50000000001B00210222000000000000000033 -+:100D600014C000000000012E81000000002044118A -+:100D7000000000000000000D0020481100000000ED -+:100D80000000001800220E3000000000FC000000EF -+:100D900000280E2300000000810000000020441104 -+:100DA000000000000000000E0020481100000000BC -+:100DB0000000000000201010000000000000E00E05 -+:100DC000002044110000000007F8FF08002048112F -+:100DD000000000000000000000294A23000000007D -+:100DE0000000001C00201E2D000000000000000874 -+:100DF00000214A27000000000000000000204811E8 -+:100E000000000000060A020000294A240000000039 -+:100E10000000000000204811000000000000000059 -+:100E200000204811000000000000000000800000C9 -+:100E300000000000810000000020441100000000BC -+:100E40000000000100204811000000000000217C8B -+:100E50000020441100000000008000000020481124 -+:100E60000000000000000000002048060000000014 -+:100E70000000000800214A270000000000000000D8 -+:100E800017000000000000000004217F00604411F2 -+:100E90000000067C0000001F00210230000000005E -+:100EA0000000000014C000000000067B00000004E9 -+:100EB00000404C1100000135810000000020441169 -+:100EC00000000000000000010020481100000000A8 -+:100ED000000021F800204411000000000000001C68 -+:100EE0000020481100000000000421F900604411B6 -+:100EF0000000067C0000001100210230000000000C -+:100F00000000000014E000000000013C00000000B0 -+:100F100000800000000000000000000000600000F1 -+:100F20000000000B00000000006004110000031529 -+:100F3000000000000020041100000000000000007C -+:100F400000600811000001B2000000000060000015 -+:100F5000000001600000FFFF40280E20000000009C -+:100F600000000010C0211220000000000000FFFF60 -+:100F7000402806200000000000000010C0210A20C8 -+:100F800000000000000000000034146100000000B8 -+:100F90000000000000741882000002BB0001A1FDE7 -+:100FA00000604411000002E000003FFF002F022F0C -+:100FB00000000000000000000CC00000000001471D -+:100FC00000000000C040040000000001000000001C -+:100FD000006000000000000B000000000060041131 -+:100FE00000000315000000000020041100000000B4 -+:100FF0000000000000600811000001B200003FFF87 -+:10100000002F022F00000000000000000CE0000094 -+:10101000000000000000000000600000000001600F -+:101020000000001040210E20000000000000FFFF23 -+:10103000C0281220000000000000001040211620EF -+:10104000000000000000FFFFC0681A20000002BB83 -+:101050000001A1FD00604411000002E000003FFF1C -+:10106000002F022F00000000000000000CC0000054 -+:101070000000015800000000C04004000000000112 -+:101080000000225C0020441100000000000000016C -+:1010900000300A2F000000000000000100210A2299 -+:1010A000000000000000000300384A220000000099 -+:1010B0000000225600204411000000000000001A29 -+:1010C00000204811000000000000A1FC0020441195 -+:1010D0000000000000000001008048110000000036 -+:1010E00000000000006000000000000B0000000095 -+:1010F000006000000000018F0000000000600000A0 -+:10110000000001A000003FFF002F022F00000000A0 -+:10111000000000000CE000000000000000000000E3 -+:1011200000202C0800000000000000000020241116 -+:101130000000000000000000002028110000000056 -+:10114000000022560020441100000000000000169C -+:1011500000204811000000000000225C0020441123 -+:101160000000000000000003002048110000000003 -+:1011700093800000002044110000000000000002E5 -+:1011800000221E290000000000000000007048EB53 -+:101190000000019C0000000000600000000002BB95 -+:1011A00000000001403306200000000000000000A5 -+:1011B000C03024090000000000003FFF002F022F74 -+:1011C00000000000000000000CE000000000000033 -+:1011D0000000000000600000000002A3000000000A -+:1011E000002F022100000000000000000AE00000C3 -+:1011F0000000018100000000006000000000013AD2 -+:101200000000000000400000000001869500000082 -+:10121000002044110000000000000000002F022107 -+:1012200000000000000000000CE00000000001864B -+:1012300000000000C0204800000000000000000185 -+:10124000005306210000018292000000002044119A -+:101250000000000000000000C0604800000001978E -+:101260000001A1FD00204411000000000000001159 -+:101270000020062D00000000000000000078042A75 -+:10128000000002FB00000000002028090000000010 -+:1012900000003FFF002F022F0000000000000000B0 -+:1012A0000CC000000000017400000000C0400400F9 -+:1012B000000000010000021000600411000003158E -+:1012C00000003FFF002F022F000000000000000080 -+:1012D0000CE000000000019400000015C020362042 -+:1012E0000000000000000016C020362000000000B2 -+:1012F0003F800000002004110000000046000000B4 -+:1013000000600811000001B2000000000080000031 -+:10131000000000000000A1FC0020441100000000BB -+:1013200000003FFF002F022F00000000000000001F -+:101330000CC000000000019B00000001008048116B -+:1013400000000000000000210080481100000000A3 -+:101350000000FFFF40280E200000000000000010E9 -+:10136000C0211220000000000000FFFF40281620CE -+:101370000000000000000010C0811A2000000000E2 -+:101380008100000000204411000000000000000661 -+:1013900000204811000000000000000800221E305C -+:1013A000000000000000002900201A2D00000000AD -+:1013B0000000E0000020441100000000FFFBFF09D6 -+:1013C00000204811000000000000000F0020222D26 -+:1013D0000000000000001FFF00294A280000000054 -+:1013E000000000060020222D000000000000000088 -+:1013F000002920E80000000000000000002048084C -+:101400000000000000000000002048110000000063 -+:10141000060A020000294A26000000000000000021 -+:1014200000204811000000000000000000204811CA -+:101430000000000000000100002018110000000062 -+:101440000000000800621E280000012F00000008B4 -+:1014500000822228000000000002C0000020441189 -+:10146000000000000000001500600E2D000001BD0E -+:101470000000001600600E2D000001BD0000C00835 -+:1014800000204411000000000000001700200E2D75 -+:10149000000000000000000014C00000000001B9BE -+:1014A0000000000000200411000000000000000007 -+:1014B0000020480100000000390000000020481111 -+:1014C00000000000000000000020481100000000A3 -+:1014D000000000000080480200000000000000182A -+:1014E00000202E2D0000000000000000003B0D63D6 -+:1014F000000000000000000800224A230000000055 -+:101500000000001000224A23000000000000001824 -+:1015100000224A2300000000000000000080480371 -+:101520000000000000000000006000000000000B50 -+:10153000000010000060041100000315000000000E -+:1015400000200411000000000000000000600811ED -+:10155000000001B2000000070021062F000000007B -+:101560000000001300200A2D000000000000000110 -+:1015700000202C11000000000000FFFF4028222066 -+:10158000000000000000000F0026222800000000DC -+:101590000000001040212620000000000000000F85 -+:1015A000002626290000000000000000002028027C -+:1015B000000000000000225600204411000000003E -+:1015C0000000001B00204811000000000000000087 -+:1015D000002F022100000000000000000CE00000CD -+:1015E000000001E00000225C002044110000000027 -+:1015F0000000008100204811000000000000A1FC54 -+:1016000000204411000000000000000100204811EB -+:10161000000000000000008000201C1100000000FD -+:1016200000000000002F0227000000000000000062 -+:101630000CE00000000001DC000000000060000081 -+:10164000000001E90000000100531E27000001D83E -+:101650000000000100202C11000000000000001F0D -+:1016600000280A22000000000000001F00282A2A8B -+:10167000000000000000000100530621000001D11D -+:101680000000225C00204411000000000000000265 -+:1016900000304A2F000000000000A1FC002044118F -+:1016A00000000000000000010020481100000000C0 -+:1016B0000000000100301E2F0000000000000000AC -+:1016C000002F022700000000000000000CE00000D6 -+:1016D000000000000000000000600000000001E9C0 -+:1016E0000000000100531E27000001E50000FFFF7D -+:1016F00040280E20000000000000000F00260E23EE -+:101700000000000000000010C021122000000000B6 -+:101710000000000F0026122400000000000000005E -+:1017200000201411000000000000000000601811EB -+:10173000000002BB0001A1FD0020441100000000D8 -+:1017400000000000002F022B00000000000000003D -+:101750000CE00000000001F8000000100022162834 -+:1017600000000000FFFF0000002816250000000018 -+:101770000000FFFF00281A29000000000000000000 -+:10178000002948C500000000000000000020480AB1 -+:10179000000000000000000000202C1100000000EC -+:1017A000000000100022162300000000FFFF0000D0 -+:1017B00000281625000000000000FFFF00281A2462 -+:1017C0000000000000000000002948C500000000E3 -+:1017D0000000000000731503000002050000000077 -+:1017E0000020180500000000000000000073152410 -+:1017F0000000020500000000002D14C500000000DC -+:1018000000000000003008A20000000000000000FE -+:101810000020480200000000000000000020280214 -+:101820000000000000000000002020030000000075 -+:101830000000000000802404000000000000000FF1 -+:1018400000210225000000000000000014C000007C -+:101850000000067B00000000002B140500000000C3 -+:1018600000000001009016250000000000000000AC -+:10187000006000000000000B000000000060041188 -+:10188000000003150000000000200411000000000B -+:101890000000000000600811000001B200002256A4 -+:1018A00000204411000000000000001A00294A2214 -+:1018B0000000000000000000C02000000000000048 -+:1018C00000003FFF002F022F00000000000000007A -+:1018D0000CE000000000000000000000C020040038 -+:1018E000000000000000225C002044110000000005 -+:1018F0000000000300384A21000000000000A1FCA5 -+:1019000000204411000000000000000100204811E8 -+:10191000000000000000FFFF40281220000000002F -+:1019200000000010C0211A20000000000000FFFF8E -+:1019300040280E200000000000000010C0211620EA -+:10194000000000000000000000741465000002BBED -+:101950000001A1FD00604411000002E00000000150 -+:10196000003306210000000000000000002F0221CB -+:1019700000000000000000000CC000000000021980 -+:1019800000003FFF002F022F0000000000000000B9 -+:101990000CC000000000021200000000C040040063 -+:1019A0000000000100000000006000000000063898 -+:1019B000000000000040040F0000021300000000BF -+:1019C000006000000000062400000000006000002D -+:1019D000000006380000021000600411000003152A -+:1019E0000000000000600000000001A000000000F6 -+:1019F000006000000000019C00000000006000008A -+:101A0000000002BB0000000000600000000002A314 -+:101A1000938000000020441100000000000000003E -+:101A2000002048080000000000000000002F022FE6 -+:101A300000000000000000000AE000000000023288 -+:101A400000000000006000000000013A00000000FB -+:101A50000040000000000236950000000020441104 -+:101A60000000000000000000002F022F0000000016 -+:101A7000000000000CE00000000002360000000042 -+:101A8000C0404800000002339200000000204411D2 -+:101A90000000000000000000C0204800000000001E -+:101AA0000000225600204411000000000000001633 -+:101AB00000204811000000000000225C00204411BA -+:101AC000000000000000000300204811000000009A -+:101AD0000000A1FC002044110000000000000001F3 -+:101AE00000204811000000000001A1FD0020441169 -+:101AF000000000000000000000600411000002FB74 -+:101B000000000000C04004000000000100000000D0 -+:101B100000600000000006240000A00C002044111A -+:101B20000000000000000000C0204800000000008D -+:101B300000000000C040480000000000000000005D -+:101B4000006000000000000B0000001840210A2087 -+:101B50000000000000000003002F0222000000002F -+:101B6000000000000AE000000000024C0000001429 -+:101B70000020222D00000000000801010029222879 -+:101B800000000000000000140020362800000000C3 -+:101B90000000A30C00204411000000000000000021 -+:101BA000C02048000000000000000000C0204800E5 -+:101BB0000000000000000000C0404800000002518A -+:101BC00000000000006000000000000B000000109A -+:101BD00000600411000003153F8000000020041184 -+:101BE000000000000000000000600811000001B2C9 -+:101BF0000000225C002044110000000000000003EF -+:101C000000204811000000000000000000600000FB -+:101C10000000027C0000001700201E2D00000000C4 -+:101C20000000000100211E2700000000000000004D -+:101C300014E000000000026A0000001200201E2DC7 -+:101C4000000000000000FFFF00281E270000000029 -+:101C50000000000000341C2700000000000000000D -+:101C600012C000000000025F0000000000201C11F4 -+:101C70000000000000000000002F00E50000000050 -+:101C80000000000008C00000000002620000000028 -+:101C900000201407000000000000001200201E2D8C -+:101CA000000000000000001000211E2700000000BE -+:101CB0000000000000341C4700000000000000008D -+:101CC00012C00000000002670000000000201C118C -+:101CD0000000000000000000002F00E600000000EF -+:101CE0000000000008C000000000026A00000000C0 -+:101CF0000020180700000000000000000060000045 -+:101D0000000002C100002256002044110000000023 -+:101D1000000000000034202300000000000000004C -+:101D200012C00000000002720000000000342044D5 -+:101D3000000000000000000012C00000000002715E -+:101D40000000001600404811000002760000001854 -+:101D500000404811000002760000000000342044DA -+:101D6000000000000000000012C00000000002752A -+:101D70000000001700404811000002760000001922 -+:101D800000204811000000000000A1FC00204411C8 -+:101D900000000000000000010020481100000000C9 -+:101DA0000001A1FD00604411000002E900003FFFB6 -+:101DB000002F022F00000000000000000CC00000F7 -+:101DC0000000025600000000C040040000000001B6 -+:101DD0000000001040210620000000000000FFFF6E -+:101DE000C0280A20000000000000001040210E2042 -+:101DF000000000000000FFFFC028122000000000CB -+:101E00000000001040211620000000000000FFFF2D -+:101E1000C0881A200000000081000000002044114A -+:101E20000000000000000001002048110000000038 -+:101E300000042004006044110000067C0000000043 -+:101E4000006000000000062400000000C0600000E8 -+:101E5000000002A30000000500200A2D0000000081 -+:101E60000000000800220A22000000000000002BF1 -+:101E700000201A2D000000000000001C00201E2D74 -+:101E8000000000000000700000281E270000000075 -+:101E90000000000000311CE6000000000000002AE5 -+:101EA00000201A2D000000000000000C00221A265D -+:101EB0000000000000000000002F00E6000000000D -+:101EC0000000000006E00000000002920000000098 -+:101ED00000201C11000000000000000000200C1178 -+:101EE000000000000000002B00203623000000004E -+:101EF0000000001000201811000000000000000089 -+:101F000000691CE20000012F9380000000204411B2 -+:101F10000000000000000000002048070000000052 -+:101F200095000000002044110000000000000000A7 -+:101F3000002F022F00000000000000000CE0000055 -+:101F40000000029D0000000100333E2F0000000051 -+:101F500000000000D90048000000000092000000CE -+:101F6000002044110000000000000000C0204800D4 -+:101F7000000000000000001C0040362700000000A8 -+:101F80000000000CC0220A20000000000000002910 -+:101F9000002036220000000000000028C04036204B -+:101FA000000000000000A2A4002044110000000076 -+:101FB000000000090020481100000000A1000000FE -+:101FC00000204411000000000000000100804811C2 -+:101FD000000000000000002100201E2D0000000075 -+:101FE00000000000002C1CE30000000000000021A5 -+:101FF00000203627000000000000002200201E2DD7 -+:102000000000000000000000002C1CE400000000A4 -+:1020100000000022002036270000000000000023FE -+:1020200000201E2D0000000000000000003120A351 -+:102030000000000000000000002D1D07000000004F -+:1020400000000023002036270000000000000024CC -+:1020500000201E2D0000000000000000003120C400 -+:102060000000000000000000002D1D07000000001F -+:10207000000000240080362700000000000000213E -+:10208000002036230000000000000022002036243B -+:10209000000000000000000000311CA30000000050 -+:1020A0000000002300203627000000000000000090 -+:1020B00000311CC40000000000000024008036270E -+:1020C000000000000000001A002036270000000079 -+:1020D0000000001B00203628000000000000001750 -+:1020E00000201E2D00000000000000020021022739 -+:1020F000000000000000000014C00000000002DC2E -+:102100000000000000400000000002D90000001A9A -+:1021100000203627000000000000001B00203628A9 -+:10212000000000000000001700201E2D000000002D -+:102130000000000200210227000000000000000053 -+:1021400014E00000000002D9000000030021022773 -+:10215000000000000000000014E00000000002DCAD -+:102160000000002300201E2D0000000000000000E1 -+:10217000002E00E1000000000000000002C000008E -+:10218000000002DC0000002100201E2D00000000E5 -+:1021900000000000003120A100000000000000004D -+:1021A000002E00E8000000000000000006C0000053 -+:1021B000000002DC0000002400201E2D00000000B2 -+:1021C00000000000002E00E20000000000000000FF -+:1021D00002C00000000002DC0000002200201E2DD2 -+:1021E0000000000000000000003120C200000000DC -+:1021F00000000000002E00E80000000000000000C9 -+:1022000006C00000000002DC0000000000600000CA -+:10221000000006590000000000600000000002B548 -+:102220000000000000400000000002DE000000008E -+:1022300000600000000002B5000000000060000027 -+:10224000000006500000000000400000000002DE18 -+:102250000000000000600000000002A70000000075 -+:1022600000400000000002DE0000001A00201E2DC9 -+:10227000000000000000001B0080222D0000000074 -+:102280000000001000221E230000000000000000DB -+:1022900000294887000000000000000000311CA356 -+:1022A000000000000000001000221E2700000000B7 -+:1022B0000000000000294887000000000000001016 -+:1022C00000221E230000000000000000003120C496 -+:1022D000000000000000FFFF00282228000000008E -+:1022E0000000000000894907000000000000001005 -+:1022F00000221E2300000000000000000029488783 -+:10230000000000000000001000221E21000000005C -+:102310000000000000294847000000000000000005 -+:1023200000311CA3000000000000001000221E2746 -+:1023300000000000000000000029488700000000A5 -+:102340000000000000311CA100000000000000108F -+:1023500000221E270000000000000000002948475E -+:10236000000000000000001000221E2300000000FA -+:1023700000000000003120C4000000000000FFFF4A -+:102380000028222800000000000000000029490762 -+:10239000000000000000001000221E2100000000CC -+:1023A00000000000003120C2000000000000FFFF1C -+:1023B00000282228000000000000000000894907D2 -+:1023C000000000000000001000221E23000000009A -+:1023D0000000000000294887000000000000000104 -+:1023E00000220A210000000000000000003308A2C3 -+:1023F000000000000000001000221E22000000006B -+:102400000000001000212222000000000000000057 -+:1024100000294907000000000000000000311CA353 -+:10242000000000000000001000221E270000000035 -+:1024300000000000002948870000000000000001A3 -+:1024400000220A210000000000000000003008A265 -+:10245000000000000000001000221E22000000000A -+:1024600000000010002122220000000000000000F7 -+:1024700000294907000000000000001000221E2370 -+:102480000000000000000000003120C40000000037 -+:102490000000FFFF002822280000000000000000CC -+:1024A000002949070000000000000000003808C5AE -+:1024B00000000000000000000030084100000000A3 -+:1024C0000000000100220A220000000000000000BD -+:1024D000003308A2000000000000001000221E22AD -+:1024E0000000000000000010002122220000000077 -+:1024F00000000000008949070000000000000017EC -+:102500000020222D000000000000000014C0000088 -+:1025100000000318FFFFFFEF002806210000000065 -+:10252000000000140020222D000000000000F8E050 -+:1025300000204411000000000000000000294901B3 -+:1025400000000000000000000089490100000000B8 -+:102550000000000000204811000000000000000002 -+:102560000020481100000000060A02000080481107 -+:102570000000000000000000C0200000000000007B -+:1025800097000000C020441100000000000000007F -+:10259000C0204811000000008A0000000020441103 -+:1025A00000000000000000000020481100000000B2 -+:1025B0000000225C00204411000000000000000028 -+:1025C000C0204800000000000000A1FC00204411D1 -+:1025D0000000000000000000C020480000000000D3 -+:1025E00000000000C0200400000000000000000007 -+:1025F00000A0000A00000000970000000020441125 -+:102600000000000000000000002048110000000051 -+:102610008A000000002044110000000000000000BB -+:1026200000204811000000000000225C002044113E -+:102630000000000000000000C02048000000000072 -+:102640000000A1FC00204411000000000000000078 -+:10265000C02048000000000000000000C02004006E -+:10266000000000000000000000A0000A00000000C0 -+:10267000970000000020441100000000000000004E -+:1026800000204811000000008A00000000204411D2 -+:1026900000000000000000000020481100000000C1 -+:1026A0000000225C00204411000000000000000037 -+:1026B000C0204800000000000000A1FC00204411E0 -+:1026C0000000000000000000C020480000000000E2 -+:1026D0000001A1FD002044110000000000000000E6 -+:1026E000D90048000000000000000000C0200400E5 -+:1026F000000000000000000000A0000A0000000030 -+:1027000000002257002044110000000000000003D8 -+:10271000C0484A20000000000000225D0020441153 -+:102720000000000000000000C04048000000000061 -+:1027300000000000006000000000063800000000FB -+:10274000C0200800000000000000225C00204411AE -+:10275000000000000000000300384A2200000000D2 -+:102760000000A1FC00204411000000000000000057 -+:10277000C0204800000000000001A1FD002044111D -+:102780000000000000000000002F022200000000F6 -+:10279000000000000CE0000000000000000000004D -+:1027A00040204800000000000000000140304A20A6 -+:1027B0000000000000000002C0304A2000000000BD -+:1027C0000000000100530A220000034B0000003FFC -+:1027D000C0280A20000000008100000000204411F1 -+:1027E000000000000000000100204811000000006F -+:1027F000000021F800204411000000000000001833 -+:102800000020481100000000000421F9006044117C -+:102810000000067C000000110021023000000000D2 -+:102820000000000014E00000000003540000001449 -+:10283000002F022200000000000000000CC0000079 -+:10284000000003620001A2A4002044110000000067 -+:1028500000000000006048020000036A0000210040 -+:10286000002044110000000000000000C0204800CB -+:102870000000000000000000C02048000000000030 -+:1028800000000000C0204800000000000000000020 -+:10289000C04048000000000000000004002F022299 -+:1028A00000000000000000000CC0000000000366F3 -+:1028B0000001A2A40020441100000000000000005C -+:1028C000004048020000035D00000028002F0222A3 -+:1028D00000000000000000000CC00000000005B374 -+:1028E0000001A2A40020441100000000000000002C -+:1028F000004048020000035D0000002C0020362646 -+:102900000000000000000049002018110000000035 -+:102910000000003F002048110000000000000001FE -+:1029200000331A260000000000000000002F0226DD -+:1029300000000000000000000CC000000000036C5C -+:102940000000002C00801A2D000000000000003F55 -+:10295000C0280A200000000000000015002F0222FD -+:1029600000000000000000000CE0000000000382F6 -+:1029700000000006002F02220000000000000000FE -+:102980000CE00000000003AD00000016002F022242 -+:1029900000000000000000000CE00000000003AF99 -+:1029A00000000020002F02220000000000000000B4 -+:1029B0000CE00000000003980000000F002F02222E -+:1029C00000000000000000000CE00000000003A474 -+:1029D00000000010002F0222000000000000000094 -+:1029E0000CE00000000003A40000001E002F0222E3 -+:1029F00000000000000000000CE000000000038C5C -+:102A00000000A2A40020441100000000000000000B -+:102A100000404802000000000800000000290A22CF -+:102A2000000000000000000340210E200000000014 -+:102A30000000000CC021122000000000000800006F -+:102A4000002812240000000000000014C0221620FC -+:102A50000000000000000000002914A40000000095 -+:102A60000000A2A4002044110000000000000000AB -+:102A7000002948A2000000000000A1FE002044112F -+:102A800000000000000000000040480300000000BB -+:102A9000810000000020441100000000000000013F -+:102AA0000020481100000000000021F8002044111F -+:102AB0000000000000000016002048110000000087 -+:102AC000000421F9006044110000067C000000159C -+:102AD00000210230000000000000000014E00000AF -+:102AE0000000038E0000210E0020441100000000B1 -+:102AF00000000000C02048000000000000000000AE -+:102B0000C0204800000000000000A2A400204411E2 -+:102B1000000000000000000000404802000000002B -+:102B200081000000002044110000000000000001AE -+:102B30000020481100000000000021F8002044118E -+:102B400000000000000000170020481100000000F5 -+:102B5000000421F9006044110000067C000000031D -+:102B600000210230000000000000000014E000001E -+:102B70000000039A0000210800204411000000001A -+:102B800000000000C020480000000000000000001D -+:102B9000C0204800000000000000A2A40020441152 -+:102BA000000000000000000000404802000000009B -+:102BB0000000A2A40020441100000000000000005A -+:102BC00000204802000000008000000000204411A6 -+:102BD000000000000000000000204811000000007C -+:102BE00081000000002044110000000000000010DF -+:102BF000002048110000000000000000002000102C -+:102C0000000000000000000014C00000000003AA43 -+:102C10000000000000400000000000000001A2A42D -+:102C20000020441100000000000000060040481190 -+:102C3000000000000001A2A40020441100000000D8 -+:102C400000000016006048110000036A0000000048 -+:102C5000004000000000000000000000C02008004C -+:102C60000000000000000000C0200C000000000078 -+:102C70000000001D002102230000000000000000F1 -+:102C800014E00000000003C4810000000020441193 -+:102C900000000000000000010020481100000000BA -+:102CA000000021F80020441100000000000000187E -+:102CB0000020481100000000000421F900604411C8 -+:102CC0000000067C0000001100210230000000001E -+:102CD0000000000014E00000000003B80000210024 -+:102CE0000020441100000000000000000020480205 -+:102CF0000000000000000000002048030000000069 -+:102D0000BABECAFE0020481100000000CAFEBABECA -+:102D100000204811000000000000A2A4002044117F -+:102D20000000000000000004004048110000000006 -+:102D3000000021700020441100000000000000008D -+:102D400000204802000000000000000000204803AE -+:102D5000000000008100000000204411000000007D -+:102D60000000000A002048110000000000000000E0 -+:102D700000200010000000000000000014C000004F -+:102D8000000003C98C000000002044110000000076 -+:102D9000CAFEBABE004048110000000081000000D9 -+:102DA0000020441100000000000000010020481134 -+:102DB0000000000000003FFF40280A200000000043 -+:102DC0008000000040280E200000000040000000AD -+:102DD000C028122000000000000400000069462204 -+:102DE0000000067C0000000000201410000000001D -+:102DF00000000000002F022300000000000000007F -+:102E00000CC00000000003D700000000C040180004 -+:102E1000000003DA00003FFFC0281A200000000075 -+:102E200000040000006946260000067C0000000047 -+:102E3000002018100000000000000000002F0224F5 -+:102E400000000000000000000CC00000000003DDD6 -+:102E500000000000C0401C00000003E000003FFF35 -+:102E6000C0281E2000000000000400000069462762 -+:102E70000000067C0000000000201C100000000084 -+:102E800000000000002044020000000000000000DC -+:102E9000002820C50000000000000000004948E8AC -+:102EA00000000000A58000000020081100000000C4 -+:102EB0000000200000200C11000000008300000032 -+:102EC00000604411000004080000000000204402DB -+:102ED0000000000000000000C020480000000000CA -+:102EE0000000000040204800000000000000001F1B -+:102EF000C0210220000000000000000014C00000FB -+:102F0000000003ED0000201000204411000000002C -+:102F10000000800000204811000000000000FFFFBA -+:102F2000C0481220000003F5A7800000002008110F -+:102F3000000000000000A00000200C1100000000B4 -+:102F4000830000000060441100000408000000003D -+:102F5000002044020000000000000000C0204800E3 -+:102F60000000000000000000C02048000000000039 -+:102F70000000FFFFC02812200000000083000000B6 -+:102F800000204411000000000000000000304883D1 -+:102F90000000000084000000002044110000000038 -+:102FA00000000000C02048000000000000000000F9 -+:102FB0001D000000000000008300000000604411BC -+:102FC0000000040800000000C040040000000001F0 -+:102FD000A980000000200811000000000000C000CF -+:102FE00000400C11000003F0AB800000002008112D -+:102FF000000000000000F8E000400C11000003F0A9 -+:10300000AD80000000200811000000000000F880E2 -+:1030100000400C11000003F0B380000000200811F4 -+:10302000000000000000F3FC00400C11000003F061 -+:10303000AF80000000200811000000000000E00048 -+:1030400000400C11000003F0B180000000200811C6 -+:10305000000000000000F00000400C11000003F030 -+:1030600083000000002044110000000000002148FF -+:1030700000204811000000008400000000204411DE -+:103080000000000000000000C02048000000000018 -+:10309000000000001D000000000000000000000013 -+:1030A000008000000000000001182000C030462011 -+:1030B0000000000000000000D900480000000000EF -+:1030C00000000000C020040000000000000000001C -+:1030D00000A0000A000000000218A000C030462036 -+:1030E0000000000000000000D900480000000000BF -+:1030F00000000000C02004000000000000000000EC -+:1031000000A0000A000000000318C000C0304620E4 -+:103110000000000000000000D9004800000000008E -+:1031200000000000C02004000000000000000000BB -+:1031300000A0000A000000000418F8E0C03046209B -+:103140000000000000000000D9004800000000005E -+:1031500000000000C020040000000000000000008B -+:1031600000A0000A000000000518F880C0304620CA -+:103170000000000000000000D9004800000000002E -+:1031800000000000C020040000000000000000005B -+:1031900000A0000A000000000618E000C030462031 -+:1031A0000000000000000000D900480000000000FE -+:1031B00000000000C020040000000000000000002B -+:1031C00000A0000A000000000718F000C0304620F0 -+:1031D0000000000000000000D900480000000000CE -+:1031E00000000000C02004000000000000000000FB -+:1031F00000A0000A000000000818F3FCC0304620C0 -+:103200000000000000000000D9004800000000009D -+:1032100000000000C02004000000000000000000CA -+:1032200000A0000A000000000000003000200A2D6D -+:103230000000000000000000C0290C400000000059 -+:1032400000000030002036230000000000000000D5 -+:10325000C0200400000000000000000000A0000AE0 -+:103260000000000086000000002044110000000063 -+:103270000000000000404801000000008500000040 -+:10328000C020441100000000000000000040480180 -+:10329000000000000000217C00204411000000001C -+:1032A00000000000C02048000000000000000000F6 -+:1032B000C02048000000000000000000C0204800BE -+:1032C0000000000081000000002044110000000008 -+:1032D0000000000100204811000000000000000074 -+:1032E000C0200800000000000000000017000000DF -+:1032F000000000000004217F006044110000067CF3 -+:103300000000001F0021023000000000000000004B -+:1033100014C00000000000000000000000404C024B -+:103320000000043E00000000C0200C00000000006F -+:1033300000000000C020100000000000000000009D -+:10334000C02014000000000000000000C020180091 -+:103350000000000000000000C0201C000000000071 -+:1033600000007F0000280A21000000000000450046 -+:10337000002F022200000000000000000CE000000E -+:103380000000044C00000000C020200000000000ED -+:103390000000000017000000000000000000001006 -+:1033A00000280A230000000000000010002F022265 -+:1033B00000000000000000000CE0000000000454C9 -+:1033C0008100000000204411000000000000000106 -+:1033D000002048110000000000040000006946249D -+:1033E0000000067C000000000040000000000459BE -+:1033F00081000000002044110000000000000000D7 -+:1034000000204811000000000000216D0020441140 -+:103410000000000000000000002048040000000040 -+:103420000000000000604805000006810000000068 -+:10343000002824F0000000000000000700280A23F4 -+:103440000000000000000001002F02220000000028 -+:10345000000000000AE0000000000460000000001E -+:10346000002F00C9000000000000000004E0000080 -+:103470000000047900000000004000000000048605 -+:1034800000000002002F02220000000000000000E7 -+:103490000AE000000000046500000000002F00C9E1 -+:1034A000000000000000000002E0000000000479BD -+:1034B000000000000040000000000486000000033F -+:1034C000002F022200000000000000000AE00000BF -+:1034D0000000046A00000000002F00C90000000086 -+:1034E000000000000CE00000000004790000000073 -+:1034F000004000000000048600000004002F0222AB -+:1035000000000000000000000AE000000000046F5E -+:1035100000000000002F00C90000000000000000B3 -+:103520000AE00000000004790000000000400000F4 -+:103530000000048600000005002F022200000000A9 -+:10354000000000000AE00000000004740000000019 -+:10355000002F00C9000000000000000006E000008D -+:103560000000047900000000004000000000048614 -+:1035700000000006002F02220000000000000000F2 -+:103580000AE000000000047900000000002F00C9DC -+:10359000000000000000000008E0000000000479C6 -+:1035A00000000000004000000000048600007F00D2 -+:1035B00000280A210000000000004500002F022220 -+:1035C00000000000000000000AE000000000000011 -+:1035D0000000000800210A23000000000000000095 -+:1035E00014C0000000000483000021690020441181 -+:1035F0000000000000000000C020480000000000A3 -+:1036000000000000C0204800000000000000000092 -+:10361000C020480000000000CAFEBABE00404811A9 -+:103620000000000000000000C02044000000000076 -+:1036300000000000C02000000000000000000000AA -+:10364000C04048000000000000007F0000280A2160 -+:103650000000000000004500002F022200000000D2 -+:10366000000000000AE000000000048C00000000E0 -+:10367000C02000000000000000000000C02000008A -+:103680000000000000000000C0400000000000003A -+:103690000000000000404C080000044C0000000046 -+:1036A000C0200800000000000000001040210E2093 -+:1036B0000000000000000011402112200000000066 -+:1036C00000000012402116200000000000002169C7 -+:1036D000002044110000000000000000002048020B -+:1036E0000000000000000000002102250000000092 -+:1036F0000000000014E00000000004960004000038 -+:10370000C0494A2000000497FFFBFFFFC0284A2061 -+:103710000000000000000000002102230000000063 -+:103720000000000014E00000000004A300000000FE -+:10373000C02048000000000000000000C020480039 -+:103740000000000000000000002102240000000032 -+:103750000000000014C00000000000008100000014 -+:1037600000204411000000000000000C002048115F -+:103770000000000000000000002000100000000019 -+:103780000000000014C000000000049FA000000022 -+:103790000020441100000000CAFEBABE00404811DB -+:1037A0000000000081000000002044110000000023 -+:1037B0000000000400204811000000000000216B00 -+:1037C000002044110000000000000000C02048104C -+:1037D00000000000810000000020441100000000F3 -+:1037E0000000000500204811000000000000216CCE -+:1037F000002044110000000000000000C02048101C -+:103800000000000000000000002F02240000000063 -+:10381000000000000CE000000000000000000000BC -+:10382000004000000000049D00000000C0210A20AC -+:10383000000000000000000014C00000000004B6FA -+:103840008100000000204411000000000000000082 -+:1038500000204811000000000000216D00204411EC -+:103860000000000000000000C02048000000000030 -+:1038700000000000C0604800000006810000000059 -+:1038800000400000000004BA810000000020441144 -+:1038900000000000000000010020481100000000AE -+:1038A00000040000C02946200000000000000000C5 -+:1038B000C06000000000067C000000010021022220 -+:1038C000000000000000000014C00000000004C15F -+:1038D00000002169002044110000000000000000E9 -+:1038E000C02048000000000000000000C020480088 -+:1038F0000000000000000000002048100000000050 -+:10390000CAFEBABE004048110000000000000000DE -+:10391000C02044000000000000000000C04048102B -+:1039200000000000810000000020441100000000A1 -+:10393000000000010020481100000000000021F8F4 -+:1039400000204411000000000000000E002048117B -+:1039500000000000000421F9006044110000067C12 -+:103960000000000000210230000000000000000004 -+:1039700014C00000000004C3000021800020441196 -+:103980000000000000000000C0204800000000000F -+:1039900000000000C0200000000000000000000047 -+:1039A000C02048000000000000000000C02000000F -+:1039B0000000000000000000C040480000000000BF -+:1039C0000000000300333E2F000000000000000153 -+:1039D00000210221000000000000000014E00000AF -+:1039E000000004F30000002C00200A2D000000005D -+:1039F0000004000018E00C11000004E200000001C7 -+:103A000000333E2F00000000000021690020441117 -+:103A1000000000000000000000204802000000003C -+:103A20000000000000204803000000000000000823 -+:103A300000300A220000000000000000C020480002 -+:103A40000000000000000000C0204800000000004E -+:103A50000000216900204411000000000000000067 -+:103A60000020480200000000000000000020480381 -+:103A7000000000000000000800300A2200000000E2 -+:103A800000000000C020480000000000000000000E -+:103A9000D8C04800000004D600002169002044116D -+:103AA00000000000000000000020480200000000AC -+:103AB0000000000000204803000000000000000893 -+:103AC00000300A220000000000000000C020480072 -+:103AD0000000000000000000C020480000000000BE -+:103AE0000000002D0020122D00000000000000004A -+:103AF00000290C830000000000002169002044110F -+:103B0000000000000000000000204802000000004B -+:103B10000000000000204803000000000000000832 -+:103B200000300A220000000000000000C020480011 -+:103B30000000000000000000C0204800000000005D -+:103B4000000000110021022400000000000000001D -+:103B500014C0000000000000000000000040000051 -+:103B60000000049D0000002CC02036200000000052 -+:103B70000000002DC0403620000000000000000FB3 -+:103B800000210221000000000000000014C000001D -+:103B9000000004F800000000006000000000000BBE -+:103BA00000000000D900000000000000000000003C -+:103BB000C040040000000001B500000000204411D6 -+:103BC000000000000000200000204811000000005C -+:103BD000B600000000204411000000000000A0001A -+:103BE0000020481100000000B70000000020441130 -+:103BF000000000000000C00000204811000000008C -+:103C0000B800000000204411000000000000F8E0AF -+:103C10000020481100000000B900000000204411FD -+:103C2000000000000000F8800020481100000000A3 -+:103C3000BA00000000204411000000000000E00075 -+:103C40000020481100000000BB00000000204411CB -+:103C5000000000000000F0000020481100000000FB -+:103C6000BC00000000204411000000000000F3FC34 -+:103C700000204811000000008100000000204411D5 -+:103C800000000000000000020020481100000000B9 -+:103C9000000000FF00280E300000000000000000BF -+:103CA000002F022300000000000000000CC00000F4 -+:103CB0000000050C00000000C0200800000000000B -+:103CC0000000000014C000000000052100000000FA -+:103CD00000200C11000000000000001C0020362312 -+:103CE000000000000000002B002036230000000030 -+:103CF00000000029002036230000000000000028FA -+:103D000000203623000000000000001700203623AA -+:103D10000000000000000025002036230000000005 -+:103D200000000026002036230000000000000015DF -+:103D3000002036230000000000000016002036237B -+:103D400000000000FFFFE00000200C110000000058 -+:103D500000000021002036230000000000000022A7 -+:103D6000002036230000000000001FFF00200C117F -+:103D700000000000000000230020362300000000A7 -+:103D8000000000240020362300000000F1FFFFFFA8 -+:103D900000283A2E000000000000001AC0220E2069 -+:103DA00000000000000000000029386E0000000044 -+:103DB0008100000000204411000000000000000607 -+:103DC00000204811000000000000002A402036209A -+:103DD00000000000870000000020441100000000E7 -+:103DE00000000000C0204800000000000000A1F416 -+:103DF00000204411000000000000000000204810D6 -+:103E0000000000000000000000200C110000000075 -+:103E10000000003000203623000000009D0000005C -+:103E200000204411000000000000001F40214A2033 -+:103E30000000000096000000002044110000000077 -+:103E400000000000C020480000000000000000004A -+:103E5000C0200C000000000000000000C020100086 -+:103E6000000000000000001F0021162400000000D8 -+:103E70000000000014C00000000000000000001D51 -+:103E800000203623000000000000000300281E234D -+:103E900000000000000000080022222300000000B3 -+:103EA000FFFFF000002822280000000000000000B2 -+:103EB000002920E8000000000000001F0020362834 -+:103EC000000000000000001800211E230000000078 -+:103ED0000000002000203627000000000000000243 -+:103EE000002216240000000000000000003014A88A -+:103EF000000000000000001E002036250000000029 -+:103F00000000000300211A2400000000100000003F -+:103F100000281A2600000000EFFFFFFF00283A2EBD -+:103F20000000000000000000004938CE0000066AD2 -+:103F30000000000140280A200000000000000006E8 -+:103F400040280E200000000000000300C0281220BE -+:103F50000000000000000008002112240000000002 -+:103F600000000000C020162000000000000000003B -+:103F7000C0201A20000000000000000000210222E2 -+:103F8000000000000000000014C0000000000559FF -+:103F9000810000000020441100000000000000012A -+:103FA00000204811000000000000225800300A24C0 -+:103FB0000000000000040000006946220000067CAA -+:103FC00000002169002044110000000000000000F2 -+:103FD00000204805000000000002000000294A26D9 -+:103FE0000000000000000000002048100000000059 -+:103FF000CAFEBABE00204811000000000000000206 -+:10400000002F022300000000000000000CC0000090 -+:104010000000056100000000C0201C10000000002E -+:1040200000000000C04000000000056F000000021A -+:10403000002F022300000000000000000CC0000060 -+:104040000000056181000000002044110000000014 -+:10405000000000010020481100000000000022586C -+:1040600000300A240000000000040000006946221D -+:104070000000067C00000000C0201C1000000000B2 -+:1040800000000000C04000000000056F00000000BC -+:10409000002F022300000000000000000CC0000000 -+:1040A0000000056500000000C0201C0000000000AA -+:1040B00000000000C04000000000056F0000000488 -+:1040C000002F022300000000000000000CC00000D0 -+:1040D0000000056D81000000002044110000000078 -+:1040E0000000000000204811000000000000216DC9 -+:1040F000002044110000000000000000C020480023 -+:104100000000000000000000C060480000000681C0 -+:104110000000000000401C100000056F00000000BF -+:10412000C02000000000000000000000C0400000AF -+:1041300000000000000000000EE00000000005711B -+:104140000000000000600000000005BC000000004E -+:10415000002F022400000000000000000CC000003E -+:10416000000005820000A2B70020441100000000FA -+:10417000000000000020480700000000810000004F -+:104180000020441100000000000000010020481140 -+:10419000000000000004A2B6006044110000067C8C -+:1041A0000000001A0021223000000000000000067C -+:1041B00000222630000000000004200400604411AA -+:1041C0000000067C0000A2C4002044110000000092 -+:1041D00000000000003048E900000000000000007E -+:1041E00000E00000000005800000A2D10020441182 -+:1041F000000000000000000000404808000000002F -+:104200000000A2D1002044110000000000000001C5 -+:1042100000504A280000000000000001002F022486 -+:1042200000000000000000000CC00000000005932A -+:104230000000A2BB002044110000000000000000AC -+:104240000020480700000000810000000020441109 -+:1042500000000000000000010020481100000000E4 -+:104260000004A2BA006044110000067C0000001A9D -+:10427000002122300000000000000006002226304D -+:104280000000000000042004006044110000067CCF -+:104290000000A2C500204411000000000000000042 -+:1042A000003048E9000000000000000000E00000CD -+:1042B000000005910000A2D200204411000000007F -+:1042C0000000000000404808000000000000A2D2EA -+:1042D00000204411000000000000000100504A28A6 -+:1042E0000000000000000002002F02240000000077 -+:1042F000000000000CC00000000005A40000A2BFE8 -+:1043000000204411000000000000000000204807C9 -+:1043100000000000810000000020441100000000A7 -+:104320000000000100204811000000000004A2BEAF -+:10433000006044110000067C0000001A00212230B9 -+:1043400000000000000000060022263000000000EF -+:1043500000042004006044110000067C0000A2C696 -+:10436000002044110000000000000000003048E977 -+:10437000000000000000000000E00000000005A2B6 -+:104380000000A2D300204411000000000000000043 -+:1043900000404808000000000000A2D300204411A3 -+:1043A000000000000000000100504A28000000004A -+:1043B0000000A2C300204411000000000000000023 -+:1043C0000020480700000000810000000020441188 -+:1043D0000000000000000001002048110000000063 -+:1043E0000004A2C2006044110000067C0000001A14 -+:1043F00000212230000000000000000600222630CC -+:104400000000000000042004006044110000067C4D -+:104410000000A2C7002044110000000000000000BE -+:10442000003048E9000000000000000000E000004B -+:10443000000005B10000A2D40020441100000000DB -+:104440000000000000404808000000000000A2D466 -+:1044500000204411000000000000000100504A2824 -+:104460000000000085000000002044110000000052 -+:104470000000000000204801000000000000304A59 -+:10448000002044110000000001000000002048113D -+:10449000000000000000000000400000000005B720 -+:1044A000A4000000C0204411000000000000000033 -+:1044B000C04048000000000000000000C060000094 -+:1044C000000005BC00000000C04004000000000126 -+:1044D0000000002C002036210000000081000000B8 -+:1044E00000204411000000000000000600204811D8 -+:1044F0000000000000000000002F0230000000005B -+:10450000000000000CC00000000005C30000000017 -+:10451000002004110000000000000030004036219F -+:10452000000005D6000000300020062D000000002D -+:1045300000007E00002806210000000000000000AE -+:10454000002F022100000000000000000CE000002D -+:10455000000005D68100000000204411000000008A -+:104560000000000100204811000000000004A0929B -+:10457000006044110000067C00000031002036304D -+:10458000000000000004A093006044110000067CBD -+:104590000000003200203630000000000004A2B607 -+:1045A000006044110000067C00000033002036301B -+:1045B000000000000004A2BA006044110000067C64 -+:1045C0000000003400203630000000000004A2BECD -+:1045D000006044110000067C0000003500203630E9 -+:1045E000000000000004A2C2006044110000067C2C -+:1045F00000000036002036300000000000042004D7 -+:10460000006044110000067C0001A2A400204411B7 -+:10461000000000000000003F0020481100000000E2 -+:104620000000003F00204811000000000000003F93 -+:1046300000204811000000000000003F0020481149 -+:1046400000000000000000050020481100000000EC -+:104650000000A1F400204411000000000000000050 -+:1046600000204811000000008800000000204411D4 -+:1046700000000000000000010020481100000000C0 -+:10468000810000000020441100000000000000062E -+:10469000002048110000000000000001002F02303F -+:1046A00000000000000000000CE000000000061FF9 -+:1046B000000000300020062D000000000000000077 -+:1046C000002F022100000000000000000CE00000AC -+:1046D0000000061F810000000020441100000000BF -+:1046E00000000001002048110000000000007E00D2 -+:1046F000002806210000000000000000002F022119 -+:1047000000000000000000000CE00000000005F8C0 -+:104710000000A092002044110000000000000031C1 -+:1047200000204A2D000000000000A093002044114A -+:10473000000000000000003200204A2D00000000B0 -+:104740000000A2B600204411000000000000003369 -+:1047500000204A2D000000000000A2BA00204411F1 -+:10476000000000000000003400204A2D000000007E -+:104770000000A2BE0020441100000000000000352F -+:1047800000204A2D000000000000A2C200204411B9 -+:10479000000000000000003600204A2D000000004C -+:1047A000000000300020062D00000000000001FF86 -+:1047B000002806210000000000000000002F022158 -+:1047C00000000000000000000CE000000000061ED9 -+:1047D0000000000000210221000000000000000095 -+:1047E00014C00000000006010004A0030060441192 -+:1047F0000000067C0000A00300204411000000001F -+:10480000000000000020481000000000000000012F -+:1048100000210621000000000000000014C000007C -+:10482000000006060004A010006044110000067C91 -+:104830000000A01000204411000000000000000053 -+:1048400000204810000000000000000100210621A7 -+:104850000000000000000000002F02210000000006 -+:10486000000000000CE000000000061E0004A01183 -+:10487000006044110000067C0000A01100204411DB -+:1048800000000000000000000020481000000000B0 -+:104890000004A012006044110000067C0000A01279 -+:1048A000002044110000000000000000002048101B -+:1048B000000000000004A013006044110000067C0A -+:1048C0000000A013002044110000000000000000C0 -+:1048D00000204810000000000004A01400604411F3 -+:1048E0000000067C0000A01400204411000000001D -+:1048F0000000000000204810000000000004A01587 -+:10490000006044110000067C0000A0150020441146 -+:10491000000000000000000000204810000000001F -+:104920000004A016006044110000067C0000A016E0 -+:10493000002044110000000000000000002048108A -+:10494000000000000004A017006044110000067C75 -+:104950000000A0170020441100000000000000002B -+:1049600000204810000000000004200400604411F2 -+:104970000000067C0000002C0080062D00000000D6 -+:10498000FF000000002044110000000000000000B3 -+:104990000020481100000000000000010020481124 -+:1049A000000000000000000200804811000000002C -+:1049B000000000000EE000000000063000000030A3 -+:1049C0000020062D00000000000000020028062143 -+:1049D0000000000000000000002F02210000000085 -+:1049E000000000000CE000000000062E8100000026 -+:1049F00000204411000000000000000100204811C8 -+:104A00000000000000042004006044110000067C47 -+:104A10000000100000200811000000000000002B22 -+:104A200000203622000000000000000000600000AE -+:104A3000000006340000000000600000000005BC1B -+:104A40009800000000204411000000000000000059 -+:104A5000008048110000000000000000C06000005D -+:104A60000000063400000000C04004000000000107 -+:104A70000000A2A400204411000000000000002259 -+:104A800000204811000000008900000000204411AF -+:104A90000000000000000001004048110000062056 -+:104AA00097000000002044110000000000000000FA -+:104AB00000204811000000008A000000002044117E -+:104AC0000000000000000000004048110000062027 -+:104AD00000000000006000000000064D0001A2A4DC -+:104AE000C0204411000000000000001600604811C2 -+:104AF0000000036A000020100020441100000000A4 -+:104B000000010000002048110000000081000000AA -+:104B100000204411000000000000000100204811A6 -+:104B2000000000000000217C002044110000000073 -+:104B3000098000000020481100000000FFFFFFFF77 -+:104B40000020481100000000000000000020481173 -+:104B5000000000000000000017000000000000003E -+:104B60000004217F006044110000067C0000001F4B -+:104B700000210230000000000000000014C000000E -+:104B8000000000000000000400404C110000064737 -+:104B900000000000004000000000000000000017BE -+:104BA00000201E2D000000000000000400291E2728 -+:104BB0000000000000000017008036270000000001 -+:104BC0000000001700201E2D00000000FFFFFFFB6B -+:104BD00000281E2700000000000000170080362774 -+:104BE000000000000000001700201E2D0000000043 -+:104BF0000000000800291E27000000000000001728 -+:104C000000803627000000000000001700201E2D45 -+:104C100000000000FFFFFFF700281E270000000033 -+:104C20000000001700803627000000000001A2A449 -+:104C30000020441100000000000000160060481130 -+:104C40000000036A00002010002044110000000052 -+:104C50000001000000204811000000000000217C3D -+:104C600000204411000000000180000000204811D5 -+:104C700000000000FFFFFFFF0020481100000000BF -+:104C800000000000002048110000000000000000AB -+:104C90001700000000000000810000000020441107 -+:104CA000000000000000000100204811000000008A -+:104CB0000004217F006044110000067C0000001FFA -+:104CC00000210230000000000000000014C00000BD -+:104CD0000000067B0000001000404C11000006613F -+:104CE00000000000C02004000000000000000000E0 -+:104CF00038C00000000000000000001D00200A2D48 -+:104D0000000000000000001E00200E2D000000002A -+:104D10000000001F0020122D0000000000000020F5 -+:104D20000020162D00000000000021690020441121 -+:104D30000000000000000000002048040000000007 -+:104D400000000000002048050000000000000000F6 -+:104D50000020480100000000CAFEBABE0020481131 -+:104D600000000000000000040030122400000000D9 -+:104D700000000000002F00640000000000000000A0 -+:104D80000CC000000000067A0000000300281A2270 -+:104D900000000000000000080022122200000000B5 -+:104DA000FFFFF000002812240000000000000000B7 -+:104DB000002910C4000000000000001F004036243D -+:104DC0000000000000000000008000000000000063 -+:104DD000000000001AC000000000067C9F000000D8 -+:104DE0000020441100000000CAFEBABE0020481195 -+:104DF00000000000000000001AE000000000067F34 -+:104E00000000000000800000000000000000000022 -+:104E10001AC00000000006819E000000002044111E -+:104E200000000000CAFEBABE0020481100000000C9 -+:104E3000000000001AE000000000068400000000EE -+:104E40000080000000000000000000000060000082 -+:104E50000000000B000010000060041100000315AA -+:104E6000000000000020041100000000000000000D -+:104E700000600811000001B20000225C0020441113 -+:104E800000000000000000030020481100000000A6 -+:104E90000000225600204411000000000000001B0A -+:104EA00000204811000000000000A1FC0020441177 -+:104EB0000000000000000001002048110000000078 -+:104EC0000001A1FDC02044110000000000000021ED -+:104ED00000201E2D000000000000001000221E27F0 -+:104EE00000000000000000240020222D000000002F -+:104EF0000000FFFF00282228000000000000000042 -+:104F000000294907000000000000000000204811AF -+:104F100000000000000000220020222D0000000000 -+:104F20000000FFFF00282228000000000000000011 -+:104F3000002949070000000000000000002048117F -+:104F4000000000000000002300201E2D00000000D3 -+:104F50000000001000221E270000000000000000DA -+:104F6000002949070000000000000000004048112F -+:104F70000000000000000000000000000000000031 -+:104F80000000000000000000000000000000000021 -+:104F90000000000000000000000000000000000011 -+:104FA0000000000000000000000000000000000001 -+:104FB00000000000000000000000000000000000F1 -+:104FC00000000000000000000000000000000000E1 -+:104FD00000000000000000000000000000000000D1 -+:104FE00000000000000000000000000000000000C1 -+:104FF00000000000000000000000000000000000B1 -+:1050000000000000000000000000000000000000A0 -+:105010000000000000000000000000000000000090 -+:105020000000000000000000000000000000000080 -+:105030000000000000000000000000000000000070 -+:105040000000000000000000000000000000000060 -+:105050000000000000000000000000000000000050 -+:105060000000000000000000000000000000000040 -+:105070000000000000000000000000000000000030 -+:105080000000000000000000000000000000000020 -+:105090000000000000000000000000000000000010 -+:1050A0000000000000000000000000000000000000 -+:1050B00000000000000000000000000000000000F0 -+:1050C00000000000000000000000000000000000E0 -+:1050D00000000000000000000000000000000000D0 -+:1050E00000000000000000000000000000000000C0 -+:1050F00000000000000000000000000000000000B0 -+:10510000000000000000000000000000000000009F -+:10511000000000000000000000000000000000008F -+:10512000000000000000000000000000000000007F -+:10513000000000000000000000000000000000006F -+:10514000000000000000000000000000000000005F -+:10515000000000000000000000000000000000004F -+:10516000000000000000000000000000000000003F -+:10517000000000000000000000000000000000002F -+:10518000000000000000000000000000000000001F -+:10519000000000000000000000000000000000000F -+:1051A00000000000000000000000000000000000FF -+:1051B00000000000000000000000000000000000EF -+:1051C00000000000000000000000000000000000DF -+:1051D00000000000000000000000000000000000CF -+:1051E00000000000000000000000000000000000BF -+:1051F00000000000000000000000000000000000AF -+:10520000000000000000000000000000000000009E -+:10521000000000000000000000000000000000008E -+:10522000000000000000000000000000000000007E -+:10523000000000000000000000000000000000006E -+:10524000000000000000000000000000000000005E -+:10525000000000000000000000000000000000004E -+:10526000000000000000000000000000000000003E -+:10527000000000000000000000000000000000002E -+:10528000000000000000000000000000000000001E -+:10529000000000000000000000000000000000000E -+:1052A00000000000000000000000000000000000FE -+:1052B000014204F505B302500000000001C301687B -+:1052C000043505B300000000022502090250015117 -+:1052D000000000000223024502A00241000000007D -+:1052E00003CD05B305B305B300000000063C063D41 -+:1052F000031F05B30000000005B305B803200340F9 -+:1053000000000000032A0282034203340000000070 -+:1053100005B305B305B305B30000000005B30544AC -+:1053200005B305B30000000003B205B304AE0344A7 -+:1053300000000000048D0443043305B300000000A6 -+:1053400004C305B3043704D000000000044304FA8A -+:10535000035103710000000005B305B305B305B3A5 -+:105360000000000005B305B305B305B3000000005D -+:1053700005B305B3063205BA0000000005B305B356 -+:10538000000705B30000000005B305B305B305B37E -+:105390000000000005B305B305B305B3000000002D -+:1053A00003EE03E303FE03FC00000000040404001A -+:1053B00004020406000000000412040E041A04167D -+:1053C000000000000422041E042A0426000000003D -+:1053D00005B305B3042E05B30000000005B305B303 -+:1053E00005B305B30000000005B305B305B305B36D -+:1053F00000000000000206680686000600000000AB -+:00000001FF -diff --git a/firmware/radeon/RV670_pfp.bin.ihex b/firmware/radeon/RV670_pfp.bin.ihex -new file mode 100644 -index 0000000..f55292c ---- /dev/null -+++ b/firmware/radeon/RV670_pfp.bin.ihex -@@ -0,0 +1,145 @@ -+:1000000000CA040000A00000007E828B007C038BED -+:10001000008001B8007C038B00D4401E00EE001E5F -+:1000200000CA040000A00000007E828B00C41838C3 -+:1000300000CA240000CA2800009581A800C41C3A08 -+:1000400000C3C00000CA080000CA0C00007C744B4A -+:1000500000C200050099C00000C41C3A007C744C2A -+:1000600000C0FFF000042C0400309002007D250049 -+:1000700000351402007D350B00255403007CD5802B -+:1000800000259C030095C00400D5001B007EDDC147 -+:10009000007D9D8000D6801B00D5801B00D4401EB3 -+:1000A00000D5401E00D6401E00D6801E00D4801E03 -+:1000B00000D4C01E009783D300D5C01E00CA08001C -+:1000C0000080001A00CA0C0000E4011E00D4001ECB -+:1000D0000080000C00C4183800E4013E00D4001E6B -+:1000E0000080000C00C4183800D4401E00EE001E32 -+:1000F00000CA040000A00000007E828B00E4011E04 -+:1001000000D4001E00D4401E00EE001E00CA0400F1 -+:1001100000A00000007E828B00E4013E00D4001E9F -+:1001200000D4401E00EE001E00CA040000A0000023 -+:10013000007E828B00CA180000D4401E00D5801EAD -+:100140000080005300D4007500D4401E00CA08008F -+:1001500000CA0C0000CA100000D4801900D4C018D6 -+:1001600000D5001700D4801E00D4C01E00D5001E8C -+:1001700000E2001E00CA040000A00000007E828B86 -+:1001800000CA080000D4806000D4401E0080000037 -+:1001900000D4801E00CA080000D4806100D4401E34 -+:1001A0000080000000D4801E00CA080000CA0C00B5 -+:1001B00000D4401E00D4801600D4C01600D4801E87 -+:1001C000008001B800D4C01E00C6084300CA0C005D -+:1001D00000CA10000094800400CA140000E420F358 -+:1001E00000D4201300D5606500D4E01C00D5201C8D -+:1001F00000D5601C008000000006200100C60843F6 -+:1002000000CA0C0000CA1000009483F700CA140052 -+:1002100000E420F30080007900D4201300C60843D6 -+:1002200000CA0C0000CA1000009883EF00CA140036 -+:1002300000D400640080008D0000000000C414326F -+:1002400000C6184300C4082F0095400500C40C30B8 -+:1002500000D4401E0080000000EE001E009583F5D3 -+:1002600000C4103100D4403300D5206500D4A01C58 -+:1002700000D4E01C00D5201C00E4015E00D4001E68 -+:10028000008000000006200100CA1800000A2001BA -+:1002900000D6007600C408360098800700C61045D6 -+:1002A0000095011000D4001F00D46062008000009F -+:1002B00000D4206200CC383500CC1433008401BB5C -+:1002C00000D4007200D5401E0080000000EE001E29 -+:1002D00000E2001A008401BB00E2001A00CC104BBF -+:1002E00000CC0447002C9401007D098B0098400548 -+:1002F000007D15CB00D4001A008001B800D4006D39 -+:100300000034440100CC0C480098403A00CC2C4A00 -+:100310000095800400CC0449008001B800D4001A84 -+:1003200000D4C01A00282801008400F000CC10037B -+:100330000098801B0004380C008400F000CC1003EF -+:100340000098801700043808008400F000CC1003E7 -+:100350000098801300043804008400F000CC1003DF -+:100360000098801400CC104C009A800900CC144DE9 -+:10037000009840DC00D4006D00CC184800D5001A6D -+:1003800000D5401A008000C900D5801A0096C0D55B -+:1003900000D4006D008001B800D4006E009AC00344 -+:1003A00000D4006D00D4006E0080000000EC007FDF -+:1003B000009AC0CC00D4006D008001B800D4006E5B -+:1003C00000CC140300CC180300CC1C03007D910367 -+:1003D000007DD583007D190C0035CC1F0035701FC2 -+:1003E000007CF0CB007CD08B00880000007E8E8BE0 -+:1003F0000095C00400D4006E008001B800D4001A3B -+:1004000000D4C01A00CC080300CC0C0300CC1003AD -+:1004100000CC140300CC180300CC1C0300CC240334 -+:1004200000CC28030035C41F0036B01F007C704B81 -+:100430000034F01F007C704B0035701F007C704B47 -+:10044000007D8881007DCCC1007E5101007E9541F8 -+:10045000007C9082007CD4C2007C848B009AC00314 -+:10046000007C8C8B002C88010098809E00D4006D4D -+:100470000098409C00D4006E00CC084C00CC0C4D81 -+:1004800000CC104800D4801A00D4C01A00800101AA -+:1004900000D5001A00CC083200D40032009482D972 -+:1004A00000CA0C0000D4401E0080000000D4001ED2 -+:1004B00000E4011E00D4001E00CA080000CA0C009F -+:1004C00000CA100000D4401E00CA140000D4801ED0 -+:1004D00000D4C01E00D5001E00D5401E00D54034FB -+:1004E0000080000000EE001E0028040400E2001A54 -+:1004F00000E2001A00D4401A00CA380000CC0803F9 -+:1005000000CC0C0300CC0C0300CC0C03009882BD83 -+:1005100000000000008401BB00D7A06F0080000035 -+:1005200000EE001F00CA040000C2FF0000CC083427 -+:1005300000C13FFF007C74CB007CC90B007D010F24 -+:10054000009902B0007C738B008401BB00D7A06FC0 -+:100550000080000000EE001F00CA080000281900FB -+:10056000007D898B009580140028140400CA0C00BB -+:1005700000CA100000CA1C0000CA240000E2001FCC -+:1005800000D4C01A00D5001A00D5401A00CC1803B8 -+:1005900000CC2C0300CC2C0300CC2C03007DA58BBD -+:1005A000007D9C4700984297000000000080016198 -+:1005B00000D4C01A00D4401E00D4801E0080000069 -+:1005C00000EE001E00E4011E00D4001E00D4401EF8 -+:1005D00000EE001E00CA040000A00000007E828B16 -+:1005E00000E4013E00D4001E00D4401E00EE001EB8 -+:1005F00000CA040000A00000007E828B00CA080030 -+:1006000000248C06000CCC060098C00600CC104ECE -+:100610000099000400D4007300E4011E00D4001E01 -+:1006200000D4401E00D4801E0080000000EE001E9A -+:1006300000CA080000CA0C000034D01800251001C0 -+:100640000095002100C17FFF00CA100000CA1400FD -+:1006500000CA180000D4801D00D4C01D007DB18BDD -+:1006600000C1420200C2C00100D5801D0034DC0E72 -+:10067000007D5D4C007F734C00D7401E00D5001EEE -+:1006800000D5401E00C1420000C2C00000099C010C -+:100690000031DC10007F5F4C007F734C00042802A7 -+:1006A000007D838000D5A86F00D5806600D7401EEE -+:1006B00000EC005E00C8240200C82402008001B8DB -+:1006C00000D6007600D4401E00D4801E00D4C01E88 -+:1006D0000080000000EE001E0080000000EE001F01 -+:1006E00000D4001F0080000000D4001F00D4001FB1 -+:1006F0000088000000D4001F00000000000000007F -+:1007000000000000000000000000000000000000E9 -+:1007100000000000000000000000000000000000D9 -+:1007200000000000000000000000000000000000C9 -+:1007300000000000000000000000000000000000B9 -+:1007400000000000000000000000000000000000A9 -+:100750000000000000000000000000000000000099 -+:100760000000000000000000000000000000000089 -+:100770000000000000000000000000000000000079 -+:100780000000000000000000000000000000000069 -+:100790000000000000000000000000000000000059 -+:1007A0000000000000000000000000000000000049 -+:1007B0000000000000000000000000000000000039 -+:1007C0000000000000000000000000000000000029 -+:1007D0000000000000000000000000000000000019 -+:1007E0000000000000000000000000000000000009 -+:1007F00000000000000000000000000000000000F9 -+:1008000000010171000201780003008F0004007FE5 -+:10081000000500030006003F000700320008012C1D -+:1008200000090046000A0036001001B6001700A2B9 -+:100830000022013A00230149002000B400240125D0 -+:100840000027004D0028006A002A0060002B00529B -+:10085000002F0065003200870034017F003C015604 -+:10086000003F00720041018C0044012E00550173CD -+:100870000056017A0060000B00610034006200380D -+:1008800000630038006400380065003800660038F6 -+:10089000006700380068003A00690041006A0048BB -+:1008A000006B0048006C0048006D0048006E004876 -+:1008B000006F00480000000600000006000000066F -+:1008C0000000000600000006000000060000000610 -+:1008D0000000000600000006000000060000000600 -+:1008E00000000006000000060000000600000006F0 -+:1008F00000000006000000060000000600000006E0 -+:00000001FF -diff --git a/firmware/radeon/RV710_me.bin.ihex b/firmware/radeon/RV710_me.bin.ihex -new file mode 100644 -index 0000000..5cdfe30 ---- /dev/null -+++ b/firmware/radeon/RV710_me.bin.ihex -@@ -0,0 +1,341 @@ -+:10000000CC0003EA04080003CC8000437C4080005D -+:10001000A0000000CC80006280000003D040007F80 -+:1000200080000003CC4000417C40C000C0160004AA -+:1000300030D03FFF7D15000CCC11000028D8001EE9 -+:100040003198000128DC001FC820000495C000067C -+:100050007C424000CC0000627E56800CCC2900001F -+:10006000C82400047E26000B958000067C42C00058 -+:10007000CC0000627ED7000CCC310000C82C0004FC -+:100080007E2E000CCC00006231103FFF8000000388 -+:10009000CE1100007C40C00080000003CC40004036 -+:1000A00080000003CC4122577C418000CC400045B9 -+:1000B000CC400048CC41225CCC41A1FC7C4080007B -+:1000C000A0000000CC800062CC400045CC4000483D -+:1000D0007C40C000CC41225CCC41A1FC7C40800033 -+:1000E000A0000000CC800062CC000045CC0000489D -+:1000F000CC41225CCC41A1FC7C408000A0000000EF -+:10010000CC800062040CA1FDC0120001CC000045AF -+:10011000CC0000487CD0C00CCC41225CCC41A1FC7E -+:10012000D04D00007C408000A0000000CC80006228 -+:1001300080000003CC41225D7C4080007C40C000F8 -+:10014000C02A00027C4100007D29000C309400018F -+:1001500030980006309C030029DC00087C42000037 -+:100160007C4240009540000FC02E000405F022584C -+:100170007F2F000CCC310000C8280004CCC12169BD -+:10018000CD01216ACE81216B0DB40002CC01216C1E -+:100190009740000E0DB400008000007DC834000AB6 -+:1001A0000DB40002974000090DB40000C02E0004F9 -+:1001B00005F022587F2F000CCC310000C828000425 -+:1001C0008000007DC834000A974000047E02800051 -+:1001D0008000007DC834000A0DB400049740FF8CF5 -+:1001E00000000000CE01216DCE41216EC828000321 -+:1001F000C834000A9B400004043C00058400026DE2 -+:10020000CC0000620DF400009740000BC82C03E600 -+:10021000CE81A2B7C03000067EF34028C030002057 -+:100220007F6B80207FB3C029CF81A2C480000003F0 -+:10023000CFC1A2D10DF400019740000BC82C03E7F9 -+:10024000CE81A2BBC03000067EF34028C030002023 -+:100250007F6B80207FB3C029CF81A2C580000003BF -+:10026000CFC1A2D20DF400029740000BC82C03E8C6 -+:10027000CE81A2BFC03000067EF34028C0300020EF -+:100280007F6B80207FB3C029CF81A2C6800000038E -+:10029000CFC1A2D3C82C03E9CE81A2C3C0300006CF -+:1002A0007EF34028C03000207F6B80207FB3C029C0 -+:1002B000CF81A2C780000003CFC1A2D48000000379 -+:1002C000CC4000427C40C0007C4100002914001D4D -+:1002D000315400019940000C31181000C81C001165 -+:1002E00095C00000C81C0011CCC12100CD01210126 -+:1002F000CCC12102CD012103041800048000037E3B -+:10030000CD81A2A4C02A00049580000836A821A3AC -+:10031000CC290000C8280004C81C00110DE40040CE -+:100320009640FFFFC81C0011CCC12170CD01217186 -+:10033000C820001296000000C82000128000037E32 -+:10034000CC0000647C40C0007C410000CC00004533 -+:10035000CC00004840D40003CD41225CCD01A1FC7B -+:10036000C01A0001041CA1FD7DD9C00C7C42000014 -+:1003700008CC00010624000106280002CE1D000062 -+:10038000CE5D000098C0FFFACE9D00007C4080004A -+:10039000A0000000CC8000627C40C00030D0000192 -+:1003A00028CC00017C414000950000067C41800083 -+:1003B000CD41216DCD81216E800000F4C81C000369 -+:1003C000C02200047E16000CCC210000C81C0004D2 -+:1003D0007C42400098C000047C4280008000000302 -+:1003E000CDE50000CE412169CE81216ACDC1216BCE -+:1003F00080000003CC01216C7C40C0007C410000E7 -+:100400007C4140007C4180007C41C00028A4000861 -+:10041000326400FF0E68003C9680000A7C020000F7 -+:100420007C4200001E300003CC00006A9B000003E9 -+:100430004220000504200040800001117C024000A1 -+:100440007E0240009A4000000A64000130EC001077 -+:100450009AC0000ACC000062C02A0004C82C002107 -+:100460007E92800CCC000041CC290000CEC000213F -+:1004700080000121C8300004CD01216DCD41216EE5 -+:10048000C83000037F1F000B30F4000727780001FD -+:100490009740002A07B801269F8000000000000056 -+:1004A000800001367F1B80048000013A7F1B80059D -+:1004B0008000013E7F1B8002800001427F1B800381 -+:1004C000800001467F1B80078000014A7F1B800659 -+:1004D0008000014F28A400089B80001928A4000870 -+:1004E0008000015F326400FF9B80001528A4000893 -+:1004F0008000015F326400FF9B80001128A4000887 -+:100500008000015F326400FF9B80000D28A400087A -+:100510008000015F326400FF9B80000928A400086E -+:100520008000015F326400FF9B80000528A4000862 -+:100530008000015F326400FF28A40008326400FFDD -+:100540000E68003C9A80FEB228EC00087C43400014 -+:100550007C4380007C43C00096C00007CC00006252 -+:10056000CF412169CF81216ACFC1216B8000000377 -+:10057000CC01216C80000003CFF50000CC00006BA3 -+:10058000840003810E68003C9A800004C82800158E -+:1005900080000003D040007F9680FFAB7E024000C9 -+:1005A0008400023BC00E0002CC00004180000239F2 -+:1005B000CCC1304A7C40C0007C410000C01E00011C -+:1005C00029240012C022000296400005C026000423 -+:1005D000C027FFFB7D25000BC02600007DD2800BCD -+:1005E0007E12C00B7D25000C7C4140007C418000C8 -+:1005F000CCC121699A80000ACD01216ACD41216BCD -+:1006000096C0FE83CD81216CC83000189700000091 -+:10061000C830001880000003CC000018840003815B -+:10062000CC00007FC8140013C8180014CD41216B02 -+:1006300096C0FE77CD81216C80000183C830001800 -+:10064000C80C000898C00000C80C00087C410000DD -+:1006500095000002000000007C414000C820000915 -+:10066000CC400043CE01A1F4CC400044C00E800039 -+:100670007C4240007C4280002AAC001F96C0FE6491 -+:10068000C035F000CE4003E232780003267C00083B -+:100690007FF7C00B7FFBC00C2A780018CFC003E3A4 -+:1006A000CF8003E426B000027F3F0000CF0003E5C7 -+:1006B0008000031F7C80C0007C40C00028D0000860 -+:1006C0003110000F9500000F2528000106A801B485 -+:1006D0009E80000000000000800001D5C0120800CC -+:1006E000800001E3C814000F800001EAC814001064 -+:1006F000800001F1CCC1A2A4800001FAC81400114D -+:1007000030D0003F0D2800159A8000120D28001EE1 -+:100710009A80001E0D2800209A8000230D24000FCF -+:100720000D2800107E6A800C9A8000260D2000049F -+:100730000D2400140D2800287E62400C7EA6800C3B -+:100740009A80002AC814001180000003CCC1A2A422 -+:10075000C01208007C4140007D0CC00CC012000893 -+:1007600029580003295C000C7C4200007DD1C00B9D -+:10077000262000147E1E400C7E4E800CCE81A2A44A -+:1007800080000003CD81A1FEC814000F0410210ECB -+:1007900095400000C814000FD051000080000003F5 -+:1007A000CCC1A2A4C8140010041021089540000078 -+:1007B000C8140010D051000080000003CCC1A2A4D6 -+:1007C000CCC1A2A404100001CD0000198400038153 -+:1007D000CC00007FC810001999000000C810001953 -+:1007E000800000047C40800004102100954000003F -+:1007F000C8140011D05100008000037ECCC1A2A417 -+:100800007C40C000CC40000D94C0FE01CC40000EE6 -+:100810007C4100009500000508CC0001C8140005CB -+:10082000994000140000000098C0FFFB7C410000CC -+:10083000800000047D008000C81400057C40C000DA -+:100840009940000CC818000C7C4100009580FDF018 -+:10085000C820000EC81C000D662000207E1E002C43 -+:10086000252400027E62402080000003CCE60000C8 -+:100870007C410000CC00006CCC00006DC818001F4B -+:10088000C81C001E659800207DD9C02C7CD4C00CEB -+:10089000CCDE000045DC0004C82800179680000F5D -+:1008A000C00E0001286800082AAC001632A800FF1C -+:1008B0000EB000497F2F000B9700000600000000DB -+:1008C000C81400057C40C000800002237C41000069 -+:1008D00080000226D040007F8400023BCC00004113 -+:1008E000CCC1304A94000000C83C001A043C00050A -+:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8 -+:100900007F7B400CCF41217CCFC1217DCC01217E5A -+:10091000C03A00040434217F7F7B400CCC350000BA -+:10092000C83C00042BFC001F0438002097C00005C1 -+:10093000CC0000629B8000000BB8000180000247E1 -+:10094000CC000071CC01A1F404380016C0360002BE -+:10095000CF81A2A488000000CF4120107C40C000BD -+:1009600028D0001C9500000504D40001CD4000658E -+:1009700080000003CD40006809540002800000039D -+:10098000CD4000668400026CC81803EA7C40C000B9 -+:100990009980FD9FC814001608D000019940002BD3 -+:1009A000CD0000687C408000A0000000CC80006288 -+:1009B000043C0005CFC1A2A4CC01A1F484000381B2 -+:1009C000CC00004688000000CC00007F8400027E3E -+:1009D000C81803EA7C40C0009980FD8DC814001639 -+:1009E00008D0000199400019CD0000687C408000CB -+:1009F000A0000000CC800062043C0022CFC1A2A471 -+:100A000084000381CC00004788000000CC00007FF8 -+:100A1000C81000169900000DCC400067800000044B -+:100A20007C408000C81803EA9980FD797C40C000B2 -+:100A300094C00003C810001699000004CCC00068E0 -+:100A4000800000047C4080008400023BC0148000D1 -+:100A5000CC000041CD41304AC01480009900000014 -+:100A6000C8100016800000047C408000C012000105 -+:100A70007C51400C80000003D05500007C40C00039 -+:100A80007C4100007C4140007C418000291C001F0B -+:100A9000CCC0004ACD00004B95C00003C01C8000B4 -+:100AA000CDC12010DD830000055C2000CC00006279 -+:100AB00080000003D81F41007C40C0007C41000042 -+:100AC0007C4140007C418000CCC0004CCD00004DFA -+:100AD000DD830000055CA00080000003D81F4100FA -+:100AE0007C40C0007C4100007C4140007C41800093 -+:100AF000CCC0004ECD00004FDD830000055CC0007F -+:100B000080000003D81F41007C40C0007C410000F1 -+:100B10007C4140007C418000CCC00050CD000051A1 -+:100B2000DD830000055CF8E080000003D81F410071 -+:100B30007C40C0007C4100007C4140007C41800042 -+:100B4000CCC00052CD000053DD830000055CF8806E -+:100B500080000003D81F41007C40C0007C410000A1 -+:100B60007C4140007C418000CCC00054CD00005549 -+:100B7000DD830000055CE00080000003D81F410019 -+:100B80007C40C0007C4100007C4140007C418000F2 -+:100B9000CCC00056CD000057DD830000055CF0009E -+:100BA00080000003D81F41007C40C0007C41000051 -+:100BB0007C4140007C418000CCC00058CD000059F1 -+:100BC000DD830000055CF3FC80000003D81F4100BA -+:100BD000D04320007C408000A0000000CC80006258 -+:100BE000D043A0007C408000A0000000CC800062C8 -+:100BF000D043C0007C408000A0000000CC80006298 -+:100C0000D043F8E07C408000A0000000CC8000626F -+:100C1000D043F8807C408000A0000000CC800062BF -+:100C2000D043E0007C408000A0000000CC80006247 -+:100C3000D043F0007C408000A0000000CC80006227 -+:100C4000D043F3FC7C408000A0000000CC80006218 -+:100C5000C81403E0CC430000CC430000CC430000A8 -+:100C60007D45C000CDC30000D04300007C40800023 -+:100C7000A0000000CC8000627C40C000C81003E2ED -+:100C8000C81403E5C81803E3C81C03E4CD81216937 -+:100C9000CDC1216ACCC1216BCC01216C04200004A0 -+:100CA0007DA180007D9640029640FCD9CD8003E373 -+:100CB00031280003C02DF000251800087DAD800B01 -+:100CC0007DA9800C80000003CD8003E3308CFFFF02 -+:100CD000D04D00007C408000A0000000CC8000626D -+:100CE000C8140020155800029580FFFFC81400208A -+:100CF000CC00006ECC4121807C40C000CCC1218D55 -+:100D0000CC41218128D0001F34588000CD81218C16 -+:100D10009500FCBFCC412182C81400209940FFFF00 -+:100D2000C8140020800000047C4080007C40C0008B -+:100D300028D0001831100001C01600809500000373 -+:100D4000C02A00047CD4C00CCCC1217CCC41217DC4 -+:100D5000CC41217E7C4180001DB0000336A0217F64 -+:100D60009B000003419C0005041C004099C000004A -+:100D700009DC0001CC210000C82400042A6C001FFB -+:100D8000419C00059AC0FFFACC80006280000004FC -+:100D90007C4080007C40C00004D403E68000000357 -+:100DA000CC5400008000037ECC4003EAC01C8000CD -+:100DB000044CA000CDC120107C410000C8140009E3 -+:100DC00004180000041C0008CD80007109DC00013B -+:100DD00005980001CD0D000099C0FFFCCC80006299 -+:100DE0008000037ECD400071C00E0100CC000041A8 -+:100DF000CCC1304AC83C007FCC00007F800000039B -+:100E0000CC00007FCC00007F88000000CC00007F79 -+:100E100000000000000000000000000000000000D2 -+:100E200000000000000000000000000000000000C2 -+:100E300000000000000000000000000000000000B2 -+:100E400000000000000000000000000000000000A2 -+:100E50000000000000000000000000000000000092 -+:100E60000000000000000000000000000000000082 -+:100E70000000000000000000000000000000000072 -+:100E80000000000000000000000000000000000062 -+:100E90000000000000000000000000000000000052 -+:100EA0000000000000000000000000000000000042 -+:100EB0000000000000000000000000000000000032 -+:100EC0000000000000000000000000000000000022 -+:100ED0000000000000000000000000000000000012 -+:100EE0000000000000000000000000000000000002 -+:100EF00000000000000000000000000000000000F2 -+:100F000000000000000000000000000000000000E1 -+:100F100000000000000000000000000000000000D1 -+:100F200000000000000000000000000000000000C1 -+:100F300000000000000000000000000000000000B1 -+:100F400000000000000000000000000000000000A1 -+:100F50000000000000000000000000000000000091 -+:100F60000000000000000000000000000000000081 -+:100F70000000000000000000000000000000000071 -+:100F80000000000000000000000000000000000061 -+:100F90000000000000000000000000000000000051 -+:100FA0000000000000000000000000000000000041 -+:100FB0000000000000000000000000000000000031 -+:100FC0000000000000000000000000000000000021 -+:100FD0000000000000000000000000000000000011 -+:100FE0000000000000000000000000000000000001 -+:100FF00000000000000000000000000000000000F1 -+:1010000000000000000000000000000000000000E0 -+:1010100000000000000000000000000000000000D0 -+:1010200000000000000000000000000000000000C0 -+:1010300000000000000000000000000000000000B0 -+:1010400000000000000000000000000000000000A0 -+:101050000000000000000000000000000000000090 -+:101060000000000000000000000000000000000080 -+:101070000000000000000000000000000000000070 -+:101080000000000000000000000000000000000060 -+:101090000000000000000000000000000000000050 -+:1010A0000000000000000000000000000000000040 -+:1010B0000000000000000000000000000000000030 -+:1010C0000000000000000000000000000000000020 -+:1010D0000000000000000000000000000000000010 -+:1010E0000000000000000000000000000000000000 -+:1010F00000000000000000000000000000000000F0 -+:1011000000000000000000000000000000000000DF -+:1011100000000000000000000000000000000000CF -+:1011200000000000000000000000000000000000BF -+:1011300000000000000000000000000000000000AF -+:10114000000000000000000000000000000000009F -+:10115000000000000000000000000000000000008F -+:10116000000000000000000000000000000000007F -+:10117000000000000000000000000000000000006F -+:10118000000000000000000000000000000000005F -+:10119000000000000000000000000000000000004F -+:1011A000000000000000000000000000000000003F -+:1011B000000000000000000000000000000000002F -+:1011C000000000000000000000000000000000001F -+:1011D000000000000000000000000000000000000F -+:1011E00000000000000000000000000000000000FF -+:1011F00000000000000000000000000000000000EF -+:1012000000000000000000000000000000000000DE -+:1012100000000000000000000000000000000000CE -+:1012200000000000000000000000000000000000BE -+:1012300000000000000000000000000000000000AE -+:10124000000000000000000000000000000000009E -+:10125000000000000000000000000000000000008E -+:10126000000000000000000000000000000000007E -+:10127000000000000000000000000000000000006E -+:10128000000000000000000000000000000000005E -+:10129000000000000000000000000000000000004E -+:1012A000000000000000000000000000000000003E -+:1012B000000000000000000000000000000000002E -+:1012C000000000000000000000000000000000001E -+:1012D000000000000000000000000000000000000E -+:1012E00000000000000000000000000000000000FE -+:1012F00000000000000000000000000000000000EE -+:1013000000000000000000000000000000000000DD -+:1013100000000000000000000000000000000000CD -+:1013200000000000000000000000000000000000BD -+:1013300000000000000000000000000000000000AD -+:10134000000000000000000000000000000000009D -+:10135000000000000000000000000000000000008D -+:10136000000000000000000000000000000000007D -+:10137000000000000000000000000000000000006D -+:10138000000000000000000000000000000000005D -+:10139000000000000000000000000000000000004D -+:1013A000000000000000000000000000000000003D -+:1013B000000000000000000000000000000000002D -+:1013C000000000000000000000000000000000001D -+:1013D000000000000000000000000000000000000D -+:1013E00000000000000000000000000000000000FD -+:1013F00000000000000000000000000000000000ED -+:101400000001033300100006001700080021000A45 -+:101410000027002A002800250029002B002A002888 -+:10142000002B002B002D003A002E0041002F004C15 -+:101430000034004E00360032003900B1003A00D1CD -+:10144000003B00E6003C00FE003D016D003F00AFA8 -+:10145000004103380043034B00440190004500FE67 -+:10146000004601AE004701AE004802000049020EEE -+:10147000004A0257004B028400520261005302737B -+:10148000005402890057029B0060029F006102AE77 -+:10149000006202B8006302C2006402CC006502D69A -+:1014A000006602E0006702EA006802F4006902F8E0 -+:1014B000006A02FC006B0300006C0304006D03086B -+:1014C000006E030C006F03100070031400720365BC -+:1014D0000074036B00790369007C031E000F037A1C -+:1014E000000F037A000F037A000F037A000F037ACC -+:1014F000000F037A000F037A000F037A000F037ABC -+:10150000000F037A000F037A000F037A000F037AAB -+:10151000000F037A000F037A000F037A000F037A9B -+:10152000000F037A000F037A000F037A000F037A8B -+:10153000000F037A000F037A000F037A000F037A7B -+:00000001FF -diff --git a/firmware/radeon/RV710_pfp.bin.ihex b/firmware/radeon/RV710_pfp.bin.ihex -new file mode 100644 -index 0000000..3d811ff ---- /dev/null -+++ b/firmware/radeon/RV710_pfp.bin.ihex -@@ -0,0 +1,213 @@ -+:100000007C408000A00000007E82800B8000000009 -+:10001000DC030000CC800040D04000407C408000E9 -+:10002000A00000007E82800BC818000E31980001ED -+:100030007C4240009580023A7C428000C81C001C33 -+:10004000C037C0007C40C0007C4100007CB4800B05 -+:10005000C036000399C00000C81C001C7CB4800C92 -+:1000600024D400027D654000CD400043CE80004393 -+:10007000CD000043CC800040CE400040CE80004008 -+:10008000CCC00040DC3A00009780FFDECD0000408D -+:100090007C40C000800000187C410000D400034078 -+:1000A000D4000FC0D4000FA2C818000E8000000CAE -+:1000B00031980002D40003C0D4000FC0D4000FA2B6 -+:1000C000C818000E288C000830CC000F3410000136 -+:1000D0007D0D00088000000C7D91800BCC800040DD -+:1000E000D04000407C408000A00000007E82800B59 -+:1000F000D4000340D4000FC0D4000FA2CC80004035 -+:10010000D04000407C408000A00000007E82800B38 -+:10011000D40003C0D4000FC0D4000FA2CC80004094 -+:10012000D04000407C408000A00000007E82800B18 -+:10013000CC4003F980000249CC4003F8C037FFFFF0 -+:100140007C414000CF41A29EC82003F8C81C03F99F -+:1001500066200020C81803FB7DE1C02C7D58C00834 -+:100160007CDCC02069100020C0360003CC000054A5 -+:100170007CB4800C80000069CC8000407C41800011 -+:10018000CD81A29ECC80004080000067CD800040E1 -+:10019000C019FFFFCC800040CD81A29E7C40C000F2 -+:1001A0007C4100007C414000CCC1A1FACD01A1F905 -+:1001B000CD41A29DCCC00040CD000040CD400040CC -+:1001C000CC4000407C408000A00000007E82800B7C -+:1001D000CC000054CC8000407C40C0007C4100003A -+:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35 -+:1001F000CCC00040CD000040CD400040D040004089 -+:100200007C408000A00000007E82800B7C40C0000B -+:1002100030D00001CCC1A29F95000003041400015E -+:1002200004140002CD4003FBCC800040800000009D -+:10023000CCC000407C40C000CC800040CCC1A2A219 -+:1002400080000000CCC000407C40C00028D4001FCB -+:10025000CC800040954000037C410000CCC000579A -+:100260002918001FCCC0004095800003CD0000403D -+:10027000CD00005880000249CC00007FC820001744 -+:10028000C83000229A0000060E280001C824001E73 -+:100290000A640001D4001240CE400040C036C000C5 -+:1002A0009680000737747900041C0001CF4000409D -+:1002B000CDC00040CF0003FA7C030000CA0C001040 -+:1002C0007C41000094C000047C414000D42002C462 -+:1002D000CDE000449B00000B7C418000CC00004B33 -+:1002E000CDA00049CD200041CD600041CDA000410E -+:1002F00006200001CE00005680000249CC00007F9D -+:10030000C8280020C82C0021CC0000637EEA4001F0 -+:10031000657400207F53402C269C00027DF5C02090 -+:1003200069F80020CE80004BCE600049CDE000414E -+:10033000CFA00041CE600041271C00027DF5C02007 -+:1003400069F800207DB24001CF00004BCE6000492B -+:10035000CDE00041CFA00041800000BCCE60004154 -+:10036000C8200017C83000229A0000060E2800019D -+:10037000C824001E0A640001D4001240CE40004090 -+:10038000CA0C00107C41000094C0000BC036C000B5 -+:100390009680000737747900041C0001CF400040AC -+:1003A000CDC00040CF0003FA7C030000800000B500 -+:1003B0007C414000CC000048800000EE00000000BE -+:1003C000C8200017C81C00230E24000299C0001585 -+:1003D0007C4180000A200001CE000056D400044079 -+:1003E000CC000040C036C000CA140013964000077D -+:1003F00037747900CF400040CC000040C83003FA89 -+:1004000080000103CF000022CC000022954001466D -+:10041000CC00007FCCA0004680000000CC2000462D -+:1004200080000249CC000064C8200017C810001FDB -+:100430009600000509100001D4000440CD000040E2 -+:10044000CD000022CC800040D0400040C80C0025E8 -+:1004500094C0FEECC8100008CD000040D4000FC0CE -+:1004600080000000D4000FA27C40C0007C4100004E -+:10047000CCC003FDCD0003FCCCC00042CD00004247 -+:100480002914001F29180010319800073B5C000157 -+:100490007D76000B998000057D5E400BCC0000420C -+:1004A00080000249CC00004D29980001292C000849 -+:1004B0009980003D32EC0001960000042930000CC8 -+:1004C00080000249CC00004204140010CD400042DC -+:1004D00033300001342800018400015DC81400039A -+:1004E0009B40001B0438000C8400015DC81400030D -+:1004F0009B400017043800088400015DC814000305 -+:100500009B400013043800048400015DC8140003FC -+:100510009B400015C80C03FD9A800009C81003FC1D -+:100520009B000101CC00004D04140010CCC000421F -+:10053000CD00004280000135CD40004296C000FA57 -+:10054000CC00004D80000249CC00004E9AC0000350 -+:10055000CC00004DCC00004EDF8300008000000086 -+:10056000D80301FF9AC000F0CC00004D8000024982 -+:10057000CC00004EC8180003C81C0003C8200003AC -+:100580007D5D40037DA1C0037D5D400C2A10001FEE -+:10059000299C001F7D1D000B7D17400B880000006B -+:1005A0007E92800B96400004CC00004E80000249F1 -+:1005B000CC00004204380008CF800042C808000385 -+:1005C000C80C0003C8100003C8140003C8180003B7 -+:1005D000C81C0003C8240003C828000329FC001F0E -+:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61 -+:1005F0002970001F7FF3C00B7D8880017DCCC00176 -+:100600007E5100017E9540017C9080027CD4C00226 -+:100610007CBC800B9AC000037C8F400B38B4000177 -+:100620009B4000C1CC00004D9BC000BFCC00004EE1 -+:10063000C80C03FDC81003FCCCC000428000016E52 -+:10064000CD000042D4000340D4000FC0D4000FA25C -+:10065000CC800040CC400040CC400040CC4000402A -+:100660007C40C000CCC00040CCC0000D8000000029 -+:10067000D04000407C40C0007C4100006514002058 -+:100680007D4D402C245800027D5980207C41C000C3 -+:10069000CD80004269980020CD800042CDC000424C -+:1006A000C023C00005E400027CA0800B266400107B -+:1006B0007CA4800CCC800040CDC00040CCC0004069 -+:1006C00095C0000ECD00004009DC0001C8280003E1 -+:1006D00096800008CE800040C834001D974000007E -+:1006E000C834001D26A800088400024CCC2B000052 -+:1006F00099C0FFF709DC0001DC3A00009780000494 -+:100700007C418000800001A225980002A00000002A -+:100710007D808000C818001D7C40C00064D00008A7 -+:1007200095800000C818001DCC130000CC8000404C -+:10073000CCC0004080000000CC400040C810001F2A -+:100740007C40C000CC8000407CD1400CCD400040BB -+:100750000518000180000000CD8000227C40C00010 -+:10076000645000208400024CCC0000617CD0C02C7E -+:10077000C8200017C8D60000994000087C438000BC -+:10078000DF830000CFA0004F8400024CCC00006249 -+:1007900080000000D040007F80000249CC00006251 -+:1007A0008400024CCC000061C82000177C40C000CF -+:1007B000C036FF00C810000DC0303FFF7CF5400B75 -+:1007C0007D51800B7D81800F998000087CF3800B28 -+:1007D000DF830000CFA0004F8400024CCC000062F9 -+:1007E00080000000D040007F80000249CC00006201 -+:1007F0008400024C7C40C00028DC000895C0001931 -+:1008000030DC00107C41000099C0000464540020DA -+:1008100080000208C91D00007D15002CC91E0000C3 -+:100820007C4200007C4240007C4180007DE5C00BA2 -+:100830007DE280079A80000E41AC00059AC000005E -+:100840000AEC000130DC001099C000040000000038 -+:100850008000020BC91D00008000020BC91E0000B1 -+:10086000CC800040CCC00040D0400040C80C0025E7 -+:1008700094C0FDE4C8100008CD000040D4000FC0B3 -+:1008800080000000D4000FA2D4000340D4000FC0A9 -+:10089000D4000FA2CC800040D04000407C408000BB -+:1008A000A00000007E82800BD40003C0D4000FC0E3 -+:1008B000D4000FA2CC800040D04000407C4080009B -+:1008C000A00000007E82800B7C40C00030D000067B -+:1008D0000D10000699000007C81400159940000586 -+:1008E000CC000052D4000340D4000FC0D4000FA2AB -+:1008F000CC800040CCC0004080000000D0400040D0 -+:100900007C40C000CC4D0000DC3A00009780FDBD6B -+:1009100004CC000180000242CC4D000080000000A9 -+:10092000D040007FCC00007F80000000CC00007F22 -+:10093000CC00007F88000000CC00007F0000000099 -+:1009400000000000000000000000000000000000A7 -+:100950000000000000000000000000000000000097 -+:100960000000000000000000000000000000000087 -+:100970000000000000000000000000000000000077 -+:100980000000000000000000000000000000000067 -+:100990000000000000000000000000000000000057 -+:1009A0000000000000000000000000000000000047 -+:1009B0000000000000000000000000000000000037 -+:1009C0000000000000000000000000000000000027 -+:1009D0000000000000000000000000000000000017 -+:1009E0000000000000000000000000000000000007 -+:1009F00000000000000000000000000000000000F7 -+:100A000000000000000000000000000000000000E6 -+:100A100000000000000000000000000000000000D6 -+:100A200000000000000000000000000000000000C6 -+:100A300000000000000000000000000000000000B6 -+:100A400000000000000000000000000000000000A6 -+:100A50000000000000000000000000000000000096 -+:100A60000000000000000000000000000000000086 -+:100A70000000000000000000000000000000000076 -+:100A80000000000000000000000000000000000066 -+:100A90000000000000000000000000000000000056 -+:100AA0000000000000000000000000000000000046 -+:100AB0000000000000000000000000000000000036 -+:100AC0000000000000000000000000000000000026 -+:100AD0000000000000000000000000000000000016 -+:100AE0000000000000000000000000000000000006 -+:100AF00000000000000000000000000000000000F6 -+:100B000000000000000000000000000000000000E5 -+:100B100000000000000000000000000000000000D5 -+:100B200000000000000000000000000000000000C5 -+:100B300000000000000000000000000000000000B5 -+:100B400000000000000000000000000000000000A5 -+:100B50000000000000000000000000000000000095 -+:100B60000000000000000000000000000000000085 -+:100B70000000000000000000000000000000000075 -+:100B80000000000000000000000000000000000065 -+:100B90000000000000000000000000000000000055 -+:100BA0000000000000000000000000000000000045 -+:100BB0000000000000000000000000000000000035 -+:100BC0000000000000000000000000000000000025 -+:100BD0000000000000000000000000000000000015 -+:100BE0000000000000000000000000000000000005 -+:100BF00000000000000000000000000000000000F5 -+:100C0000000302220004022A0005009F00020003E4 -+:100C10000006003C0007002700080191000900447D -+:100C2000000A002D00100247001700F0002201D733 -+:100C3000002301E80026004C0027005F0020011A75 -+:100C4000002800920029004F002A0083002B006436 -+:100C5000002F008D003200D80034023200360074BC -+:100C60000039010A003C01FC003F009F00410005E3 -+:100C7000004401940048019D004901C5004A01CF8C -+:100C8000005502250056022D0060000A0061002A6E -+:100C90000062003000630030006400300065003006 -+:100CA0000066003000670030006800370069003FD0 -+:100CB000006A0047006B0047006C0047006D00476A -+:100CC000006E0047006F0047007000470073024746 -+:100CD000007B024000000005000000050000000548 -+:100CE00000000005000000050000000500000005F0 -+:100CF00000000005000000050000000500000005E0 -+:100D000000000005000000050000000500000005CF -+:100D100000000005000000050000000500000005BF -+:100D200000000005000000050000000500000005AF -+:100D3000000000050000000500000005000000059F -+:00000001FF -diff --git a/firmware/radeon/RV730_me.bin.ihex b/firmware/radeon/RV730_me.bin.ihex -new file mode 100644 -index 0000000..390c18e ---- /dev/null -+++ b/firmware/radeon/RV730_me.bin.ihex -@@ -0,0 +1,341 @@ -+:10000000CC0003EA7C408000A0000000CC800062AD -+:1000100080000001D040007F80000001CC40004102 -+:100020007C40C000C016000430D03FFF7D15000C9E -+:10003000CC11000028D8001E3198000128DC001FD8 -+:10004000C820000495C000067C424000CC0000623D -+:100050007E56800CCC290000C82400047E26000BAC -+:10006000958000067C42C000CC0000627ED7000C68 -+:10007000CC310000C82C00047E2E000CCC000062A5 -+:1000800031103FFF80000001CE1100007C40C00015 -+:1000900080000001CC40004080000001CC4122578C -+:1000A0007C418000CC400045CC400048CC41225CE3 -+:1000B000CC41A1FC7C408000A0000000CC8000620C -+:1000C000CC400045CC4000487C40C000CC41225C84 -+:1000D000CC41A1FC7C408000A0000000CC800062EC -+:1000E000CC000045CC000048CC41225CCC41A1FCB6 -+:1000F0007C408000A0000000CC800062040CA1FDC8 -+:10010000C0120001CC000045CC0000487CD0C00CDF -+:10011000CC41225CCC41A1FCD04D00007C40800051 -+:10012000A0000000CC80006280000001CC41225D74 -+:100130007C4080007C40C000C02A00027C4100005E -+:100140007D29000C3094000130980006309C03009B -+:1001500029DC00087C4200007C4240009540000FF2 -+:10016000C02E000405F022587F2F000CCC31000077 -+:10017000C8280004CCC12169CD01216ACE81216B40 -+:100180000DB40002CC01216C9740000E0DB40000AC -+:100190008000007BC834000A0DB4000297400009BB -+:1001A0000DB40000C02E000405F022587F2F000C73 -+:1001B000CC310000C82800048000007BC834000A4D -+:1001C000974000047E0280008000007BC834000A53 -+:1001D0000DB400049740FF8C00000000CE01216D9B -+:1001E000CE41216EC8280003C834000A9B40000499 -+:1001F000043C00058400026BCC0000620DF400009A -+:100200009740000BC82C03E6CE81A2B7C030000691 -+:100210007EF34028C03000207F6B80207FB3C02950 -+:10022000CF81A2C480000001CFC1A2D10DF4000192 -+:100230009740000BC82C03E7CE81A2BBC03000065C -+:100240007EF34028C03000207F6B80207FB3C02920 -+:10025000CF81A2C580000001CFC1A2D20DF400025F -+:100260009740000BC82C03E8CE81A2BFC030000627 -+:100270007EF34028C03000207F6B80207FB3C029F0 -+:10028000CF81A2C680000001CFC1A2D3C82C03E950 -+:10029000CE81A2C3C03000067EF34028C0300020CB -+:1002A0007F6B80207FB3C029CF81A2C7800000016F -+:1002B000CFC1A2D480000001CC4000427C40C000ED -+:1002C0007C4100002914001D315400019940000CAC -+:1002D00031181000C81C001195C00000C81C001186 -+:1002E000CCC12100CD012101CCC12102CD012103CE -+:1002F000041800048000037CCD81A2A4C02A00045D -+:100300009580000836A821A3CC290000C828000445 -+:10031000C81C00110DE400409640FFFFC81C0011EE -+:10032000CCC12170CD012171C820001296000000BF -+:10033000C82000128000037CCC0000647C40C00018 -+:100340007C410000CC000045CC00004840D40003B4 -+:10035000CD41225CCD01A1FCC01A0001041CA1FD0D -+:100360007DD9C00C7C42000008CC000106240001AD -+:1003700006280002CE1D0000CE5D000098C0FFFAE6 -+:10038000CE9D00007C408000A0000000CC80006278 -+:100390007C40C00030D0000128CC00017C414000EE -+:1003A000950000067C418000CD41216DCD81216EFC -+:1003B000800000F2C81C0003C02200047E16000C5E -+:1003C000CC210000C81C00047C42400098C00004FE -+:1003D0007C42800080000001CDE50000CE41216913 -+:1003E000CE81216ACDC1216B80000001CC01216C3E -+:1003F0007C40C0007C4100007C4140007C4180008A -+:100400007C41C00028A40008326400FF0E68003C54 -+:100410009680000A7C0200007C4200001E3000032F -+:10042000CC00006A9B00000342200005042000402D -+:100430008000010F7C0240007E0240009A400000D4 -+:100440000A64000130EC00109AC0000ACC0000627F -+:10045000C02A0004C82C00217E92800CCC000041F0 -+:10046000CC290000CEC000218000011FC83000044C -+:10047000CD01216DCD41216EC83000037F1F000BDF -+:1004800030F40007277800019740002A07B80124BC -+:100490009F80000000000000800001347F1B80046A -+:1004A000800001387F1B80058000013C7F1B80029B -+:1004B000800001407F1B8003800001447F1B800778 -+:1004C000800001487F1B80068000014D28A40008A1 -+:1004D0009B80001928A400088000015D326400FFA1 -+:1004E0009B80001528A400088000015D326400FF95 -+:1004F0009B80001128A400088000015D326400FF89 -+:100500009B80000D28A400088000015D326400FF7C -+:100510009B80000928A400088000015D326400FF70 -+:100520009B80000528A400088000015D326400FF64 -+:1005300028A40008326400FF0E68003C9A80FEB2D6 -+:1005400028EC00087C4340007C4380007C43C000D2 -+:1005500096C00007CC000062CF412169CF81216A9B -+:10056000CFC1216B80000001CC01216C8000000113 -+:10057000CFF50000CC00006B8400037F0E68003CC8 -+:100580009A800004C828001580000001D040007F38 -+:100590009680FFAB7E02400084000239C00E00024C -+:1005A000CC00004180000237CCC1304A7C40C00002 -+:1005B0007C410000C01E000129240012C02200025C -+:1005C00096400005C0260004C027FFFB7D25000BD8 -+:1005D000C02600007DD2800B7E12C00B7D25000C52 -+:1005E0007C4140007C418000CCC121699A80000A96 -+:1005F000CD01216ACD41216B96C0FE83CD81216C56 -+:10060000C830001897000000C830001880000001B2 -+:10061000CC0000188400037FCC00007FC8140013B6 -+:10062000C8180014CD41216B96C0FE77CD81216C96 -+:1006300080000181C8300018C80C000898C0000074 -+:10064000C80C00087C41000095000002000000007A -+:100650007C414000C8200009CC400043CE01A1F4F9 -+:10066000CC400044C00E80007C4240007C428000B0 -+:100670002AAC001F96C0FE64C035F000CE4003E2F5 -+:1006800032780003267C00087FF7C00B7FFBC00C8C -+:100690002A780018CFC003E3CF8003E426B000021D -+:1006A0007F3F0000CF0003E58000031D7C80C00079 -+:1006B0007C40C00028D000083110000F9500000FCA -+:1006C0002528000106A801B29E800000000000005D -+:1006D000800001D3C0120800800001E1C814000F9F -+:1006E000800001E8C8140010800001EFCCC1A2A472 -+:1006F000800001F8C814001130D0003F0D2800150B -+:100700009A8000120D28001E9A80001E0D280020DD -+:100710009A8000230D24000F0D2800107E6A800CA3 -+:100720009A8000260D2000040D2400140D280028B6 -+:100730007E62400C7EA6800C9A80002AC8140011AC -+:1007400080000001CCC1A2A4C01208007C4140007E -+:100750007D0CC00CC012000829580003295C000C55 -+:100760007C4200007DD1C00B262000147E1E400C70 -+:100770007E4E800CCE81A2A480000001CD81A1FE1E -+:10078000C814000F0410210E95400000C814000F7B -+:10079000D051000080000001CCC1A2A4C8140010F8 -+:1007A0000410210895400000C8140010D05100002A -+:1007B00080000001CCC1A2A4CCC1A2A404100001FD -+:1007C000CD0000198400037FCC00007FC810001901 -+:1007D00099000000C8100019800000027C408000D1 -+:1007E0000410210095400000C8140011D0510000F1 -+:1007F0008000037CCCC1A2A47C40C000CC40000D92 -+:1008000094C0FE01CC40000E7C4100009500000524 -+:1008100008CC0001C8140005994000140000000035 -+:1008200098C0FFFB7C410000800000027D0080003A -+:10083000C81400057C40C0009940000CC818000C8A -+:100840007C4100009580FDF0C820000EC81C000D02 -+:10085000662000207E1E002C252400027E6240209F -+:1008600080000001CCE600007C410000CC00006C60 -+:10087000CC00006DC818001FC81C001E6598002021 -+:100880007DD9C02C7CD4C00CCCDE000045DC00043B -+:10089000C82800179680000FC00E000128680008C5 -+:1008A0002AAC001632A800FF0EB000497F2F000BC3 -+:1008B0009700000600000000C81400057C40C0003E -+:1008C000800002217C41000080000224D040007F93 -+:1008D00084000239CC000041CCC1304A94000000B1 -+:1008E000C83C001A043C0005CFC1A2A4C0361F902A -+:1008F000C0387FFF7C03C0107F7B400CCF41217C40 -+:10090000CFC1217DCC01217EC03A00040434217F77 -+:100910007F7B400CCC350000C83C00042BFC001F42 -+:100920000438002097C00005CC0000629B800000C6 -+:100930000BB8000180000245CC000071CC01A1F48D -+:1009400004380016C0360002CF81A2A4880000003F -+:10095000CF4120107C40C00028D0001C950000052D -+:1009600004D40001CD40006580000001CD40006846 -+:100970000954000280000001CD4000668400026A34 -+:10098000C81803EA7C40C0009980FD9FC814001677 -+:1009900008D000019940002BCD0000687C40800009 -+:1009A000A0000000CC800062043C0005CFC1A2A4DE -+:1009B000CC01A1F48400037FCC0000468800000035 -+:1009C000CC00007F8400027CC81803EA7C40C00091 -+:1009D0009980FD8DC814001608D0000199400019B7 -+:1009E000CD0000687C408000A0000000CC80006248 -+:1009F000043C0022CFC1A2A48400037FCC000047A6 -+:100A000088000000CC00007FC81000169900000D7F -+:100A1000CC400067800000027C408000C81803EAD8 -+:100A20009980FD797C40C00094C00003C810001676 -+:100A300099000004CCC00068800000027C40800067 -+:100A400084000239C0148000CC000041CD41304AFE -+:100A5000C014800099000000C81000168000000239 -+:100A60007C408000C01200017C51400C80000001DD -+:100A7000D05500007C40C0007C4100007C4140001B -+:100A80007C418000291C001FCCC0004ACD00004BD7 -+:100A900095C00003C01C8000CDC12010DD83000084 -+:100AA000055C2000CC00006280000001D81F4100DE -+:100AB0007C40C0007C4100007C4140007C418000C3 -+:100AC000CCC0004CCD00004DDD830000055CA000D3 -+:100AD00080000001D81F41007C40C0007C41000024 -+:100AE0007C4140007C418000CCC0004ECD00004FD6 -+:100AF000DD830000055CC00080000001D81F4100BC -+:100B00007C40C0007C4100007C4140007C41800072 -+:100B1000CCC00050CD000051DD830000055CF8E042 -+:100B200080000001D81F41007C40C0007C410000D3 -+:100B30007C4140007C418000CCC00052CD0000537D -+:100B4000DD830000055CF88080000001D81F4100B3 -+:100B50007C40C0007C4100007C4140007C41800022 -+:100B6000CCC00054CD000055DD830000055CE000E2 -+:100B700080000001D81F41007C40C0007C41000083 -+:100B80007C4140007C418000CCC00056CD00005725 -+:100B9000DD830000055CF00080000001D81F4100EB -+:100BA0007C40C0007C4100007C4140007C418000D2 -+:100BB000CCC00058CD000059DD830000055CF3FC7B -+:100BC00080000001D81F4100D04320007C408000FD -+:100BD000A0000000CC800062D043A0007C408000D8 -+:100BE000A0000000CC800062D043C0007C408000A8 -+:100BF000A0000000CC800062D043F8E07C40800080 -+:100C0000A0000000CC800062D043F8807C408000CF -+:100C1000A0000000CC800062D043E0007C40800057 -+:100C2000A0000000CC800062D043F0007C40800037 -+:100C3000A0000000CC800062D043F3FC7C40800028 -+:100C4000A0000000CC800062C81403E0CC43000088 -+:100C5000CC430000CC4300007D45C000CDC3000064 -+:100C6000D04300007C408000A0000000CC800062E7 -+:100C70007C40C000C81003E2C81403E5C81803E3B1 -+:100C8000C81C03E4CD812169CDC1216ACCC1216B8F -+:100C9000CC01216C042000047DA180007D964002DF -+:100CA0009640FCD9CD8003E331280003C02DF0002D -+:100CB000251800087DAD800B7DA9800C8000000107 -+:100CC000CD8003E3308CFFFFD04D00007C408000DE -+:100CD000A0000000CC800062C8140020155800025B -+:100CE0009580FFFFC8140020CC00006ECC4121800D -+:100CF0007C40C000CCC1218DCC41218128D0001F77 -+:100D000034588000CD81218C9500FCBFCC412182DC -+:100D1000C81400209940FFFFC81400208000000282 -+:100D20007C4080007C40C00028D0001831100001B9 -+:100D3000C016008095000003C02A00047CD4C00CBB -+:100D4000CCC1217CCC41217DCC41217E7C418000E5 -+:100D50001DB0000336A0217F9B000003419C0005CD -+:100D6000041C004099C0000009DC0001CC210000F7 -+:100D7000C82400042A6C001F419C00059AC0FFFA99 -+:100D8000CC800062800000027C4080007C40C0007B -+:100D900004D403E680000001CC5400008000037CF2 -+:100DA000CC4003EAC01C8000044CA000CDC1201040 -+:100DB0007C410000C814000904180000041C00084D -+:100DC000CD80007109DC000105980001CD0D000007 -+:100DD00099C0FFFCCC8000628000037CCD40007194 -+:100DE000C00E0100CC000041CCC1304AC83C007F9D -+:100DF000CC00007F80000001CC00007FCC00007F91 -+:100E000088000000CC00007F00000000000000000F -+:100E100000000000000000000000000000000000D2 -+:100E200000000000000000000000000000000000C2 -+:100E300000000000000000000000000000000000B2 -+:100E400000000000000000000000000000000000A2 -+:100E50000000000000000000000000000000000092 -+:100E60000000000000000000000000000000000082 -+:100E70000000000000000000000000000000000072 -+:100E80000000000000000000000000000000000062 -+:100E90000000000000000000000000000000000052 -+:100EA0000000000000000000000000000000000042 -+:100EB0000000000000000000000000000000000032 -+:100EC0000000000000000000000000000000000022 -+:100ED0000000000000000000000000000000000012 -+:100EE0000000000000000000000000000000000002 -+:100EF00000000000000000000000000000000000F2 -+:100F000000000000000000000000000000000000E1 -+:100F100000000000000000000000000000000000D1 -+:100F200000000000000000000000000000000000C1 -+:100F300000000000000000000000000000000000B1 -+:100F400000000000000000000000000000000000A1 -+:100F50000000000000000000000000000000000091 -+:100F60000000000000000000000000000000000081 -+:100F70000000000000000000000000000000000071 -+:100F80000000000000000000000000000000000061 -+:100F90000000000000000000000000000000000051 -+:100FA0000000000000000000000000000000000041 -+:100FB0000000000000000000000000000000000031 -+:100FC0000000000000000000000000000000000021 -+:100FD0000000000000000000000000000000000011 -+:100FE0000000000000000000000000000000000001 -+:100FF00000000000000000000000000000000000F1 -+:1010000000000000000000000000000000000000E0 -+:1010100000000000000000000000000000000000D0 -+:1010200000000000000000000000000000000000C0 -+:1010300000000000000000000000000000000000B0 -+:1010400000000000000000000000000000000000A0 -+:101050000000000000000000000000000000000090 -+:101060000000000000000000000000000000000080 -+:101070000000000000000000000000000000000070 -+:101080000000000000000000000000000000000060 -+:101090000000000000000000000000000000000050 -+:1010A0000000000000000000000000000000000040 -+:1010B0000000000000000000000000000000000030 -+:1010C0000000000000000000000000000000000020 -+:1010D0000000000000000000000000000000000010 -+:1010E0000000000000000000000000000000000000 -+:1010F00000000000000000000000000000000000F0 -+:1011000000000000000000000000000000000000DF -+:1011100000000000000000000000000000000000CF -+:1011200000000000000000000000000000000000BF -+:1011300000000000000000000000000000000000AF -+:10114000000000000000000000000000000000009F -+:10115000000000000000000000000000000000008F -+:10116000000000000000000000000000000000007F -+:10117000000000000000000000000000000000006F -+:10118000000000000000000000000000000000005F -+:10119000000000000000000000000000000000004F -+:1011A000000000000000000000000000000000003F -+:1011B000000000000000000000000000000000002F -+:1011C000000000000000000000000000000000001F -+:1011D000000000000000000000000000000000000F -+:1011E00000000000000000000000000000000000FF -+:1011F00000000000000000000000000000000000EF -+:1012000000000000000000000000000000000000DE -+:1012100000000000000000000000000000000000CE -+:1012200000000000000000000000000000000000BE -+:1012300000000000000000000000000000000000AE -+:10124000000000000000000000000000000000009E -+:10125000000000000000000000000000000000008E -+:10126000000000000000000000000000000000007E -+:10127000000000000000000000000000000000006E -+:10128000000000000000000000000000000000005E -+:10129000000000000000000000000000000000004E -+:1012A000000000000000000000000000000000003E -+:1012B000000000000000000000000000000000002E -+:1012C000000000000000000000000000000000001E -+:1012D000000000000000000000000000000000000E -+:1012E00000000000000000000000000000000000FE -+:1012F00000000000000000000000000000000000EE -+:1013000000000000000000000000000000000000DD -+:1013100000000000000000000000000000000000CD -+:1013200000000000000000000000000000000000BD -+:1013300000000000000000000000000000000000AD -+:10134000000000000000000000000000000000009D -+:10135000000000000000000000000000000000008D -+:10136000000000000000000000000000000000007D -+:10137000000000000000000000000000000000006D -+:10138000000000000000000000000000000000005D -+:10139000000000000000000000000000000000004D -+:1013A000000000000000000000000000000000003D -+:1013B000000000000000000000000000000000002D -+:1013C000000000000000000000000000000000001D -+:1013D000000000000000000000000000000000000D -+:1013E00000000000000000000000000000000000FD -+:1013F00000000000000000000000000000000000ED -+:10140000000103310010000400170006002100084D -+:10141000002700280028002300290029002A002690 -+:10142000002B0029002D0038002E003F002F004A1D -+:101430000034004C00360030003900AF003A00CFD5 -+:10144000003B00E4003C00FC003D016B003F00ADB0 -+:1014500000410336004303490044018E004500FC6F -+:10146000004601AC004701AC004801FE0049020CF7 -+:10147000004A0255004B02820052025F0053027183 -+:1014800000540287005702990060029D006102AC7F -+:10149000006202B6006302C0006402CA006502D4A2 -+:1014A000006602DE006702E8006802F2006902F6E8 -+:1014B000006A02FA006B02FE006C0302006D030674 -+:1014C000006E030A006F030E0070031200720363C4 -+:1014D0000074036900790367007C031C000F037824 -+:1014E000000F0378000F0378000F0378000F0378D4 -+:1014F000000F0378000F0378000F0378000F0378C4 -+:10150000000F0378000F0378000F0378000F0378B3 -+:10151000000F0378000F0378000F0378000F0378A3 -+:10152000000F0378000F0378000F0378000F037893 -+:10153000000F0378000F0378000F0378000F037883 -+:00000001FF -diff --git a/firmware/radeon/RV730_pfp.bin.ihex b/firmware/radeon/RV730_pfp.bin.ihex -new file mode 100644 -index 0000000..3d811ff ---- /dev/null -+++ b/firmware/radeon/RV730_pfp.bin.ihex -@@ -0,0 +1,213 @@ -+:100000007C408000A00000007E82800B8000000009 -+:10001000DC030000CC800040D04000407C408000E9 -+:10002000A00000007E82800BC818000E31980001ED -+:100030007C4240009580023A7C428000C81C001C33 -+:10004000C037C0007C40C0007C4100007CB4800B05 -+:10005000C036000399C00000C81C001C7CB4800C92 -+:1000600024D400027D654000CD400043CE80004393 -+:10007000CD000043CC800040CE400040CE80004008 -+:10008000CCC00040DC3A00009780FFDECD0000408D -+:100090007C40C000800000187C410000D400034078 -+:1000A000D4000FC0D4000FA2C818000E8000000CAE -+:1000B00031980002D40003C0D4000FC0D4000FA2B6 -+:1000C000C818000E288C000830CC000F3410000136 -+:1000D0007D0D00088000000C7D91800BCC800040DD -+:1000E000D04000407C408000A00000007E82800B59 -+:1000F000D4000340D4000FC0D4000FA2CC80004035 -+:10010000D04000407C408000A00000007E82800B38 -+:10011000D40003C0D4000FC0D4000FA2CC80004094 -+:10012000D04000407C408000A00000007E82800B18 -+:10013000CC4003F980000249CC4003F8C037FFFFF0 -+:100140007C414000CF41A29EC82003F8C81C03F99F -+:1001500066200020C81803FB7DE1C02C7D58C00834 -+:100160007CDCC02069100020C0360003CC000054A5 -+:100170007CB4800C80000069CC8000407C41800011 -+:10018000CD81A29ECC80004080000067CD800040E1 -+:10019000C019FFFFCC800040CD81A29E7C40C000F2 -+:1001A0007C4100007C414000CCC1A1FACD01A1F905 -+:1001B000CD41A29DCCC00040CD000040CD400040CC -+:1001C000CC4000407C408000A00000007E82800B7C -+:1001D000CC000054CC8000407C40C0007C4100003A -+:1001E0007C414000CCC1A1FACD01A1F9CD41A29D35 -+:1001F000CCC00040CD000040CD400040D040004089 -+:100200007C408000A00000007E82800B7C40C0000B -+:1002100030D00001CCC1A29F95000003041400015E -+:1002200004140002CD4003FBCC800040800000009D -+:10023000CCC000407C40C000CC800040CCC1A2A219 -+:1002400080000000CCC000407C40C00028D4001FCB -+:10025000CC800040954000037C410000CCC000579A -+:100260002918001FCCC0004095800003CD0000403D -+:10027000CD00005880000249CC00007FC820001744 -+:10028000C83000229A0000060E280001C824001E73 -+:100290000A640001D4001240CE400040C036C000C5 -+:1002A0009680000737747900041C0001CF4000409D -+:1002B000CDC00040CF0003FA7C030000CA0C001040 -+:1002C0007C41000094C000047C414000D42002C462 -+:1002D000CDE000449B00000B7C418000CC00004B33 -+:1002E000CDA00049CD200041CD600041CDA000410E -+:1002F00006200001CE00005680000249CC00007F9D -+:10030000C8280020C82C0021CC0000637EEA4001F0 -+:10031000657400207F53402C269C00027DF5C02090 -+:1003200069F80020CE80004BCE600049CDE000414E -+:10033000CFA00041CE600041271C00027DF5C02007 -+:1003400069F800207DB24001CF00004BCE6000492B -+:10035000CDE00041CFA00041800000BCCE60004154 -+:10036000C8200017C83000229A0000060E2800019D -+:10037000C824001E0A640001D4001240CE40004090 -+:10038000CA0C00107C41000094C0000BC036C000B5 -+:100390009680000737747900041C0001CF400040AC -+:1003A000CDC00040CF0003FA7C030000800000B500 -+:1003B0007C414000CC000048800000EE00000000BE -+:1003C000C8200017C81C00230E24000299C0001585 -+:1003D0007C4180000A200001CE000056D400044079 -+:1003E000CC000040C036C000CA140013964000077D -+:1003F00037747900CF400040CC000040C83003FA89 -+:1004000080000103CF000022CC000022954001466D -+:10041000CC00007FCCA0004680000000CC2000462D -+:1004200080000249CC000064C8200017C810001FDB -+:100430009600000509100001D4000440CD000040E2 -+:10044000CD000022CC800040D0400040C80C0025E8 -+:1004500094C0FEECC8100008CD000040D4000FC0CE -+:1004600080000000D4000FA27C40C0007C4100004E -+:10047000CCC003FDCD0003FCCCC00042CD00004247 -+:100480002914001F29180010319800073B5C000157 -+:100490007D76000B998000057D5E400BCC0000420C -+:1004A00080000249CC00004D29980001292C000849 -+:1004B0009980003D32EC0001960000042930000CC8 -+:1004C00080000249CC00004204140010CD400042DC -+:1004D00033300001342800018400015DC81400039A -+:1004E0009B40001B0438000C8400015DC81400030D -+:1004F0009B400017043800088400015DC814000305 -+:100500009B400013043800048400015DC8140003FC -+:100510009B400015C80C03FD9A800009C81003FC1D -+:100520009B000101CC00004D04140010CCC000421F -+:10053000CD00004280000135CD40004296C000FA57 -+:10054000CC00004D80000249CC00004E9AC0000350 -+:10055000CC00004DCC00004EDF8300008000000086 -+:10056000D80301FF9AC000F0CC00004D8000024982 -+:10057000CC00004EC8180003C81C0003C8200003AC -+:100580007D5D40037DA1C0037D5D400C2A10001FEE -+:10059000299C001F7D1D000B7D17400B880000006B -+:1005A0007E92800B96400004CC00004E80000249F1 -+:1005B000CC00004204380008CF800042C808000385 -+:1005C000C80C0003C8100003C8140003C8180003B7 -+:1005D000C81C0003C8240003C828000329FC001F0E -+:1005E0002AB0001F7FF3C00B28F0001F7FF3C00B61 -+:1005F0002970001F7FF3C00B7D8880017DCCC00176 -+:100600007E5100017E9540017C9080027CD4C00226 -+:100610007CBC800B9AC000037C8F400B38B4000177 -+:100620009B4000C1CC00004D9BC000BFCC00004EE1 -+:10063000C80C03FDC81003FCCCC000428000016E52 -+:10064000CD000042D4000340D4000FC0D4000FA25C -+:10065000CC800040CC400040CC400040CC4000402A -+:100660007C40C000CCC00040CCC0000D8000000029 -+:10067000D04000407C40C0007C4100006514002058 -+:100680007D4D402C245800027D5980207C41C000C3 -+:10069000CD80004269980020CD800042CDC000424C -+:1006A000C023C00005E400027CA0800B266400107B -+:1006B0007CA4800CCC800040CDC00040CCC0004069 -+:1006C00095C0000ECD00004009DC0001C8280003E1 -+:1006D00096800008CE800040C834001D974000007E -+:1006E000C834001D26A800088400024CCC2B000052 -+:1006F00099C0FFF709DC0001DC3A00009780000494 -+:100700007C418000800001A225980002A00000002A -+:100710007D808000C818001D7C40C00064D00008A7 -+:1007200095800000C818001DCC130000CC8000404C -+:10073000CCC0004080000000CC400040C810001F2A -+:100740007C40C000CC8000407CD1400CCD400040BB -+:100750000518000180000000CD8000227C40C00010 -+:10076000645000208400024CCC0000617CD0C02C7E -+:10077000C8200017C8D60000994000087C438000BC -+:10078000DF830000CFA0004F8400024CCC00006249 -+:1007900080000000D040007F80000249CC00006251 -+:1007A0008400024CCC000061C82000177C40C000CF -+:1007B000C036FF00C810000DC0303FFF7CF5400B75 -+:1007C0007D51800B7D81800F998000087CF3800B28 -+:1007D000DF830000CFA0004F8400024CCC000062F9 -+:1007E00080000000D040007F80000249CC00006201 -+:1007F0008400024C7C40C00028DC000895C0001931 -+:1008000030DC00107C41000099C0000464540020DA -+:1008100080000208C91D00007D15002CC91E0000C3 -+:100820007C4200007C4240007C4180007DE5C00BA2 -+:100830007DE280079A80000E41AC00059AC000005E -+:100840000AEC000130DC001099C000040000000038 -+:100850008000020BC91D00008000020BC91E0000B1 -+:10086000CC800040CCC00040D0400040C80C0025E7 -+:1008700094C0FDE4C8100008CD000040D4000FC0B3 -+:1008800080000000D4000FA2D4000340D4000FC0A9 -+:10089000D4000FA2CC800040D04000407C408000BB -+:1008A000A00000007E82800BD40003C0D4000FC0E3 -+:1008B000D4000FA2CC800040D04000407C4080009B -+:1008C000A00000007E82800B7C40C00030D000067B -+:1008D0000D10000699000007C81400159940000586 -+:1008E000CC000052D4000340D4000FC0D4000FA2AB -+:1008F000CC800040CCC0004080000000D0400040D0 -+:100900007C40C000CC4D0000DC3A00009780FDBD6B -+:1009100004CC000180000242CC4D000080000000A9 -+:10092000D040007FCC00007F80000000CC00007F22 -+:10093000CC00007F88000000CC00007F0000000099 -+:1009400000000000000000000000000000000000A7 -+:100950000000000000000000000000000000000097 -+:100960000000000000000000000000000000000087 -+:100970000000000000000000000000000000000077 -+:100980000000000000000000000000000000000067 -+:100990000000000000000000000000000000000057 -+:1009A0000000000000000000000000000000000047 -+:1009B0000000000000000000000000000000000037 -+:1009C0000000000000000000000000000000000027 -+:1009D0000000000000000000000000000000000017 -+:1009E0000000000000000000000000000000000007 -+:1009F00000000000000000000000000000000000F7 -+:100A000000000000000000000000000000000000E6 -+:100A100000000000000000000000000000000000D6 -+:100A200000000000000000000000000000000000C6 -+:100A300000000000000000000000000000000000B6 -+:100A400000000000000000000000000000000000A6 -+:100A50000000000000000000000000000000000096 -+:100A60000000000000000000000000000000000086 -+:100A70000000000000000000000000000000000076 -+:100A80000000000000000000000000000000000066 -+:100A90000000000000000000000000000000000056 -+:100AA0000000000000000000000000000000000046 -+:100AB0000000000000000000000000000000000036 -+:100AC0000000000000000000000000000000000026 -+:100AD0000000000000000000000000000000000016 -+:100AE0000000000000000000000000000000000006 -+:100AF00000000000000000000000000000000000F6 -+:100B000000000000000000000000000000000000E5 -+:100B100000000000000000000000000000000000D5 -+:100B200000000000000000000000000000000000C5 -+:100B300000000000000000000000000000000000B5 -+:100B400000000000000000000000000000000000A5 -+:100B50000000000000000000000000000000000095 -+:100B60000000000000000000000000000000000085 -+:100B70000000000000000000000000000000000075 -+:100B80000000000000000000000000000000000065 -+:100B90000000000000000000000000000000000055 -+:100BA0000000000000000000000000000000000045 -+:100BB0000000000000000000000000000000000035 -+:100BC0000000000000000000000000000000000025 -+:100BD0000000000000000000000000000000000015 -+:100BE0000000000000000000000000000000000005 -+:100BF00000000000000000000000000000000000F5 -+:100C0000000302220004022A0005009F00020003E4 -+:100C10000006003C0007002700080191000900447D -+:100C2000000A002D00100247001700F0002201D733 -+:100C3000002301E80026004C0027005F0020011A75 -+:100C4000002800920029004F002A0083002B006436 -+:100C5000002F008D003200D80034023200360074BC -+:100C60000039010A003C01FC003F009F00410005E3 -+:100C7000004401940048019D004901C5004A01CF8C -+:100C8000005502250056022D0060000A0061002A6E -+:100C90000062003000630030006400300065003006 -+:100CA0000066003000670030006800370069003FD0 -+:100CB000006A0047006B0047006C0047006D00476A -+:100CC000006E0047006F0047007000470073024746 -+:100CD000007B024000000005000000050000000548 -+:100CE00000000005000000050000000500000005F0 -+:100CF00000000005000000050000000500000005E0 -+:100D000000000005000000050000000500000005CF -+:100D100000000005000000050000000500000005BF -+:100D200000000005000000050000000500000005AF -+:100D3000000000050000000500000005000000059F -+:00000001FF -diff --git a/firmware/radeon/RV770_me.bin.ihex b/firmware/radeon/RV770_me.bin.ihex -new file mode 100644 -index 0000000..a0e1699 ---- /dev/null -+++ b/firmware/radeon/RV770_me.bin.ihex -@@ -0,0 +1,341 @@ -+:10000000CC0003EA7C408000A0000000CC800062AD -+:1000100080000001D040007F80000001CC40004102 -+:100020007C40C000C016000430D03FFF7D15000C9E -+:10003000CC11000028D8001E3198000128DC001FD8 -+:10004000C820000495C000067C424000CC0000623D -+:100050007E56800CCC290000C82400047E26000BAC -+:10006000958000067C42C000CC0000627ED7000C68 -+:10007000CC310000C82C00047E2E000CCC000062A5 -+:1000800031103FFF80000001CE1100007C40C00015 -+:1000900080000001CC40004080000001CC4122578C -+:1000A0007C418000CC400045CC400048CC41225CE3 -+:1000B000CC41A1FC7C408000A0000000CC8000620C -+:1000C000CC400045CC4000487C40C000CC41225C84 -+:1000D000CC41A1FC7C408000A0000000CC800062EC -+:1000E000CC000045CC000048CC41225CCC41A1FCB6 -+:1000F0007C408000A0000000CC800062040CA1FDC8 -+:10010000C0120001CC000045CC0000487CD0C00CDF -+:10011000CC41225CCC41A1FCD04D00007C40800051 -+:10012000A0000000CC80006280000001CC41225D74 -+:100130007C4080007C40C000C02A00027C4100005E -+:100140007D29000C3094000130980006309C03009B -+:1001500029DC00087C4200007C4240009540000FF2 -+:10016000C02E000405F022587F2F000CCC31000077 -+:10017000C8280004CCC12169CD01216ACE81216B40 -+:100180000DB40002CC01216C9740000E0DB40000AC -+:100190008000007BC834000A0DB4000297400009BB -+:1001A0000DB40000C02E000405F022587F2F000C73 -+:1001B000CC310000C82800048000007BC834000A4D -+:1001C000974000047E0280008000007BC834000A53 -+:1001D0000DB400049740FF8C00000000CE01216D9B -+:1001E000CE41216EC8280003C834000A9B40000499 -+:1001F000043C00058400026DCC0000620DF4000098 -+:100200009740000BC82C03E6CE81A2B7C030000691 -+:100210007EF34028C03000207F6B80207FB3C02950 -+:10022000CF81A2C480000001CFC1A2D10DF4000192 -+:100230009740000BC82C03E7CE81A2BBC03000065C -+:100240007EF34028C03000207F6B80207FB3C02920 -+:10025000CF81A2C580000001CFC1A2D20DF400025F -+:100260009740000BC82C03E8CE81A2BFC030000627 -+:100270007EF34028C03000207F6B80207FB3C029F0 -+:10028000CF81A2C680000001CFC1A2D3C82C03E950 -+:10029000CE81A2C3C03000067EF34028C0300020CB -+:1002A0007F6B80207FB3C029CF81A2C7800000016F -+:1002B000CFC1A2D480000001CC4000427C40C000ED -+:1002C0007C4100002914001D315400019940000DAB -+:1002D00031181000C81C001109DC000195C0FFFF97 -+:1002E000C81C0011CCC12100CD012101CCC12102CB -+:1002F000CD012103041800048000039FCD81A2A436 -+:10030000C02A00049580000836A821A3CC2900004B -+:10031000C8280004C81C00110DE400409640FFFFEF -+:10032000C81C0011CCC12170CD012171C820001260 -+:1003300096000000C82000128000039FCC000064DB -+:100340007C40C0007C410000CC000045CC0000484F -+:1003500040D40003CD41225CCD01A1FCC01A0001B4 -+:10036000041CA1FD7DD9C00C7C42000008CC00011A -+:100370000624000106280002CE1D0000CE5D00000C -+:1003800098C0FFFACE9D00007C408000A0000000D5 -+:10039000CC8000627C40C00030D0000128CC00013D -+:1003A0007C414000950000067C418000CD41216DDC -+:1003B000CD81216E800000F3C81C0003C022000420 -+:1003C0007E16000CCC210000C81C00047C424000BA -+:1003D00098C000047C42800080000001CDE5000050 -+:1003E000CE412169CE81216ACDC1216B80000001FF -+:1003F000CC01216C7C40C0007C4100007C4140006D -+:100400007C4180007C41C00028A40008326400FFC9 -+:100410000E68003C9680000A7C0200007C420000CE -+:100420001E300003CC00006A9B0000034220000540 -+:1004300004200040800001107C0240007E02400049 -+:100440009A4000000A64000130EC00109AC0000AD3 -+:10045000CC000062C02A0004C82C00217E92800CCF -+:10046000CC000041CC290000CEC00021800001203A -+:10047000C8300004CD01216DCD41216EC83000038C -+:100480007F1F000B30F40007277800019740002AF7 -+:1004900007B801259F8000000000000080000135A2 -+:1004A0007F1B8004800001397F1B80058000013D97 -+:1004B0007F1B8002800001417F1B8003800001457B -+:1004C0007F1B8007800001497F1B80068000014E52 -+:1004D00028A400089B80001928A400088000015E61 -+:1004E000326400FF9B80001528A400088000015E94 -+:1004F000326400FF9B80001128A400088000015E88 -+:10050000326400FF9B80000D28A400088000015E7B -+:10051000326400FF9B80000928A400088000015E6F -+:10052000326400FF9B80000528A400088000015E63 -+:10053000326400FF28A40008326400FF0E68003C0B -+:100540009A80FEB128EC00087C4340007C43800088 -+:100550007C43C00096C00007CC000062CF412169F7 -+:10056000CF81216ACFC1216B80000001CC01216CB9 -+:1005700080000001CFF50000CC00006B840003A2D6 -+:100580000E68003C9A800004C82800158000000115 -+:10059000D040007F9680FFAB7E0240008400023B8B -+:1005A000C00E0002CC00004180000239CCC1304AAC -+:1005B0007C40C0007C410000C01E000129240012C4 -+:1005C000C022000296400005C0260004C027FFFBA1 -+:1005D0007D25000BC02600007DD2800B7E12C00B53 -+:1005E0007D25000C7C4140007C418000CCC121690C -+:1005F0009A80000ACD01216ACD41216B96C0FE820E -+:10060000CD81216CC830001897000000C830001858 -+:1006100080000001CC000018840003A2CC00007F01 -+:10062000C8140013C8180014CD41216B96C0FE7683 -+:10063000CD81216C80000182C8300018C80C0008F0 -+:1006400098C00000C80C00087C4100009500000222 -+:10065000000000007C414000C8200009CC4000435D -+:10066000CE01A1F4CC400044C00E80007C4240008A -+:100670007C4280002AAC001F96C0FE63C035F000AB -+:10068000CE4003E232780003267C00087FF7C00BDF -+:100690007FFBC00C2A780018CFC003E3CF8003E4AF -+:1006A00026B000027F3F0000CF0003E58000031F5B -+:1006B0007C80C0007C40C00028D000083110000FB2 -+:1006C0009500000F2528000106A801B39E800000B8 -+:1006D00000000000800001D4C0120800800001E288 -+:1006E000C814000F800001E9C8140010800001F058 -+:1006F000CCC1A2A4800001F9C814001130D0003F81 -+:100700000D2800159A8000120D28001E9A80001EE8 -+:100710000D2800209A8000230D24000F0D280010C2 -+:100720007E6A800C9A8000260D2000040D2400149F -+:100730000D2800287E62400C7EA6800C9A80002A3C -+:10074000C814001180000001CCC1A2A4C01208008E -+:100750007C4140007D0CC00CC012000829580003E9 -+:10076000295C000C7C4200007DD1C00B26200014C7 -+:100770007E1E400C7E4E800CCE81A2A48000000123 -+:10078000CD81A1FEC814000F0410210E9540000079 -+:10079000C814000FD051000080000001CCC1A2A4F9 -+:1007A000C81400100410210895400000C81400105F -+:1007B000D051000080000001CCC1A2A4CCC1A2A4F1 -+:1007C00004100001CD000019840003A2CC00007FBA -+:1007D000C810001999000000C8100019800000021C -+:1007E0007C40800004102100095400019540FFFF67 -+:1007F000C8140011D05100008000039FCCC1A2A4F6 -+:100800007C40C000CC40000D94C0FDFFCC40000EE9 -+:100810007C4100009500000508CC0001C8140005CB -+:10082000994000140000000098C0FFFB7C410000CC -+:10083000800000027D008000C81400057C40C000DC -+:100840009940000CC818000C7C4100009580FDEE1A -+:10085000C820000EC81C000D662000207E1E002C43 -+:10086000252400027E62402080000001CCE60000CA -+:100870007C410000CC00006CCC00006DC818001F4B -+:10088000C81C001E659800207DD9C02C7CD4C00CEB -+:10089000CCDE000045DC0004C82800179680000F5D -+:1008A000C00E0001286800082AAC001632A800FF1C -+:1008B0000EB000497F2F000B9700000600000000DB -+:1008C000C81400057C40C000800002237C41000069 -+:1008D00080000226D040007F8400023BCC00004113 -+:1008E000CCC1304A94000000C83C001A043C00050A -+:1008F000CFC1A2A4C0361F90C0387FFF7C03C010B8 -+:100900007F7B400CCF41217CCFC1217DCC01217E5A -+:10091000C03A00040434217F7F7B400CCC350000BA -+:10092000C83C00042BFC001F0438002097C00005C1 -+:10093000CC0000629B8000000BB8000180000247E1 -+:10094000CC000071CC01A1F404380016C0360002BE -+:10095000CF81A2A488000000CF4120107C40C000BD -+:1009600028D0001C9500000504D40001CD4000658E -+:1009700080000001CD4000680954000280000001A1 -+:10098000CD4000668400026CC81803EA7C40C000B9 -+:100990009980FD9DC814001608D000019940002BD5 -+:1009A000CD0000687C408000A0000000CC80006288 -+:1009B000043C0005CFC1A2A4CC01A1F4840003A291 -+:1009C000CC00004688000000CC00007F8400027E3E -+:1009D000C81803EA7C40C0009980FD8BC81400163B -+:1009E00008D0000199400019CD0000687C408000CB -+:1009F000A0000000CC800062043C0022CFC1A2A471 -+:100A0000840003A2CC00004788000000CC00007FD7 -+:100A1000C81000169900000DCC400067800000024D -+:100A20007C408000C81803EA9980FD777C40C000B4 -+:100A300094C00003C810001699000004CCC00068E0 -+:100A4000800000027C4080008400023BC0148000D3 -+:100A5000CC000041CD41304AC01480009900000014 -+:100A6000C8100016800000027C408000C012000107 -+:100A70007C51400C80000001D05500007C40C0003B -+:100A80007C4100007C4140007C418000291C001F0B -+:100A9000CCC0004ACD00004B95C00003C01C8000B4 -+:100AA000CDC12010DD830000055C2000CC00006279 -+:100AB00080000001D81F41007C40C0007C41000044 -+:100AC0007C4140007C418000CCC0004CCD00004DFA -+:100AD000DD830000055CA00080000001D81F4100FC -+:100AE0007C40C0007C4100007C4140007C41800093 -+:100AF000CCC0004ECD00004FDD830000055CC0007F -+:100B000080000001D81F41007C40C0007C410000F3 -+:100B10007C4140007C418000CCC00050CD000051A1 -+:100B2000DD830000055CF8E080000001D81F410073 -+:100B30007C40C0007C4100007C4140007C41800042 -+:100B4000CCC00052CD000053DD830000055CF8806E -+:100B500080000001D81F41007C40C0007C410000A3 -+:100B60007C4140007C418000CCC00054CD00005549 -+:100B7000DD830000055CE00080000001D81F41001B -+:100B80007C40C0007C4100007C4140007C418000F2 -+:100B9000CCC00056CD000057DD830000055CF0009E -+:100BA00080000001D81F41007C40C0007C41000053 -+:100BB0007C4140007C418000CCC00058CD000059F1 -+:100BC000DD830000055CF3FC80000001D81F4100BC -+:100BD000D04320007C408000A0000000CC80006258 -+:100BE000D043A0007C408000A0000000CC800062C8 -+:100BF000D043C0007C408000A0000000CC80006298 -+:100C0000D043F8E07C408000A0000000CC8000626F -+:100C1000D043F8807C408000A0000000CC800062BF -+:100C2000D043E0007C408000A0000000CC80006247 -+:100C3000D043F0007C408000A0000000CC80006227 -+:100C4000D043F3FC7C408000A0000000CC80006218 -+:100C5000C81403E0CC430000CC430000CC430000A8 -+:100C60007D45C000CDC30000D04300007C40800023 -+:100C7000A0000000CC8000627C40C000C81003E2ED -+:100C8000C81403E5C81803E3C81C03E4CD81216937 -+:100C9000CDC1216ACCC1216BCC01216C04200004A0 -+:100CA0007DA180007D9640029640FCD7CD8003E375 -+:100CB00031280003C02DF000251800087DAD800B01 -+:100CC0007DA9800C80000001CD8003E3308CFFFF04 -+:100CD000D04D00007C408000A0000000CC8000626D -+:100CE0007C40C0007C4100002924001832640001CF -+:100CF0009A400013C8140020155800029580FFFF89 -+:100D0000C8140020CC00006ECCC12180CD01218D03 -+:100D1000CC4121812914001F34588000CD81218CC1 -+:100D20009540FCB9CC412182C81400209940FFFFB6 -+:100D3000C8140020800000027C4080007C414000FC -+:100D40007C4180007C41C00065B400207F57402C6E -+:100D5000D437810047740004D437810047740004FD -+:100D6000D43781004774000409DC0004D4378100C3 -+:100D700099C0FFF8477400042924001FC0380019E7 -+:100D80009640FCA1C03E0004CF8121F837E021F954 -+:100D9000CC210000C82000042A20001832200001C5 -+:100DA0009A00FFFBCF8121F8800000027C40800088 -+:100DB0007C40C00028D0001831100001C01600800F -+:100DC00095000003C02A00047CD4C00CCCC1217C57 -+:100DD000CC41217DCC41217E7C4180001DB00003AF -+:100DE00036A0217F9B000003419C0005041C0040AD -+:100DF00099C0000009DC0001CC210000C8240004D7 -+:100E00002A6C001F419C00059AC0FFFACC8000624A -+:100E1000800000027C4080007C40C00004D403E6D7 -+:100E200080000001CC5400008000039FCC4003EA06 -+:100E3000C01C8000044CA000CDC120107C410000EB -+:100E4000C814000904180000041C0008CD800071BB -+:100E500009DC000105980001CD0D000099C0FFFCE0 -+:100E6000CC8000628000039FCD400071C00E010065 -+:100E7000CC000041CCC1304AC83C007FCC00007F90 -+:100E800080000001CC00007FCC00007F88000000C3 -+:100E9000CC00007F00000000000000000000000007 -+:100EA0000000000000000000000000000000000042 -+:100EB0000000000000000000000000000000000032 -+:100EC0000000000000000000000000000000000022 -+:100ED0000000000000000000000000000000000012 -+:100EE0000000000000000000000000000000000002 -+:100EF00000000000000000000000000000000000F2 -+:100F000000000000000000000000000000000000E1 -+:100F100000000000000000000000000000000000D1 -+:100F200000000000000000000000000000000000C1 -+:100F300000000000000000000000000000000000B1 -+:100F400000000000000000000000000000000000A1 -+:100F50000000000000000000000000000000000091 -+:100F60000000000000000000000000000000000081 -+:100F70000000000000000000000000000000000071 -+:100F80000000000000000000000000000000000061 -+:100F90000000000000000000000000000000000051 -+:100FA0000000000000000000000000000000000041 -+:100FB0000000000000000000000000000000000031 -+:100FC0000000000000000000000000000000000021 -+:100FD0000000000000000000000000000000000011 -+:100FE0000000000000000000000000000000000001 -+:100FF00000000000000000000000000000000000F1 -+:1010000000000000000000000000000000000000E0 -+:1010100000000000000000000000000000000000D0 -+:1010200000000000000000000000000000000000C0 -+:1010300000000000000000000000000000000000B0 -+:1010400000000000000000000000000000000000A0 -+:101050000000000000000000000000000000000090 -+:101060000000000000000000000000000000000080 -+:101070000000000000000000000000000000000070 -+:101080000000000000000000000000000000000060 -+:101090000000000000000000000000000000000050 -+:1010A0000000000000000000000000000000000040 -+:1010B0000000000000000000000000000000000030 -+:1010C0000000000000000000000000000000000020 -+:1010D0000000000000000000000000000000000010 -+:1010E0000000000000000000000000000000000000 -+:1010F00000000000000000000000000000000000F0 -+:1011000000000000000000000000000000000000DF -+:1011100000000000000000000000000000000000CF -+:1011200000000000000000000000000000000000BF -+:1011300000000000000000000000000000000000AF -+:10114000000000000000000000000000000000009F -+:10115000000000000000000000000000000000008F -+:10116000000000000000000000000000000000007F -+:10117000000000000000000000000000000000006F -+:10118000000000000000000000000000000000005F -+:10119000000000000000000000000000000000004F -+:1011A000000000000000000000000000000000003F -+:1011B000000000000000000000000000000000002F -+:1011C000000000000000000000000000000000001F -+:1011D000000000000000000000000000000000000F -+:1011E00000000000000000000000000000000000FF -+:1011F00000000000000000000000000000000000EF -+:1012000000000000000000000000000000000000DE -+:1012100000000000000000000000000000000000CE -+:1012200000000000000000000000000000000000BE -+:1012300000000000000000000000000000000000AE -+:10124000000000000000000000000000000000009E -+:10125000000000000000000000000000000000008E -+:10126000000000000000000000000000000000007E -+:10127000000000000000000000000000000000006E -+:10128000000000000000000000000000000000005E -+:10129000000000000000000000000000000000004E -+:1012A000000000000000000000000000000000003E -+:1012B000000000000000000000000000000000002E -+:1012C000000000000000000000000000000000001E -+:1012D000000000000000000000000000000000000E -+:1012E00000000000000000000000000000000000FE -+:1012F00000000000000000000000000000000000EE -+:1013000000000000000000000000000000000000DD -+:1013100000000000000000000000000000000000CD -+:1013200000000000000000000000000000000000BD -+:1013300000000000000000000000000000000000AD -+:10134000000000000000000000000000000000009D -+:10135000000000000000000000000000000000008D -+:10136000000000000000000000000000000000007D -+:10137000000000000000000000000000000000006D -+:10138000000000000000000000000000000000005D -+:10139000000000000000000000000000000000004D -+:1013A000000000000000000000000000000000003D -+:1013B000000000000000000000000000000000002D -+:1013C000000000000000000000000000000000001D -+:1013D000000000000000000000000000000000000D -+:1013E00000000000000000000000000000000000FD -+:1013F00000000000000000000000000000000000ED -+:10140000000103330010000400170006002100084B -+:10141000002700280028002300290029002A002690 -+:10142000002B0029002D0038002E003F002F004A1D -+:101430000034004C00360030003900AF003A00D0D4 -+:10144000003B00E5003C00FD003D016C003F00ADAD -+:10145000004103380043036C0044018F004500FD48 -+:10146000004601AD004701AD004802000049020EF0 -+:10147000004A0257004B028400520261005302737B -+:10148000005402890057029B0060029F006102AE77 -+:10149000006202B8006302C2006402CC006502D69A -+:1014A000006602E0006702EA006802F4006902F8E0 -+:1014B000006A02FC006B0300006C0304006D03086B -+:1014C000006E030C006F031000700314007203869B -+:1014D0000074038C0079038A007C031E000F039BB9 -+:1014E000000F039B000F039B000F039B000F039B48 -+:1014F000000F039B000F039B000F039B000F039B38 -+:10150000000F039B000F039B000F039B000F039B27 -+:10151000000F039B000F039B000F039B000F039B17 -+:10152000000F039B000F039B000F039B000F039B07 -+:10153000000F039B000F039B000F039B000F039BF7 -+:00000001FF -diff --git a/firmware/radeon/RV770_pfp.bin.ihex b/firmware/radeon/RV770_pfp.bin.ihex -new file mode 100644 -index 0000000..a2d1619 ---- /dev/null -+++ b/firmware/radeon/RV770_pfp.bin.ihex -@@ -0,0 +1,213 @@ -+:100000007C408000A00000007E82800B8000000009 -+:10001000DC030000CC800040D04000407C408000E9 -+:10002000A00000007E82800BC818000E31980001ED -+:100030007C424000958002527C428000C81C001C1B -+:10004000C037C0007C40C0007C4100007CB4800B05 -+:10005000C036000399C00000C81C001C7CB4800C92 -+:1000600024D400027D654000CD400043CE80004393 -+:10007000CD000043CC800040CE400040CE80004008 -+:10008000CCC00040DC3A00009780FFDECD0000408D -+:100090007C40C000800000187C410000D400034078 -+:1000A000D4000FC0D4000FA2C818000E8000000CAE -+:1000B00031980002D40003C0D4000FC0D4000FA2B6 -+:1000C000C818000E288C000830CC000F3410000136 -+:1000D0007D0D00088000000C7D91800BCC800040DD -+:1000E000D04000407C408000A00000007E82800B59 -+:1000F000D4000340D4000FC0D4000FA2CC80004035 -+:10010000D04000407C408000A00000007E82800B38 -+:10011000D40003C0D4000FC0D4000FA2CC80004094 -+:10012000D04000407C408000A00000007E82800B18 -+:10013000CC4003F980000261CC4003F8C82003F8EA -+:10014000C81C03F9C81803FBC037FFFF7C414000FF -+:10015000CF41A29E662000207DE1C02C7D58C008C2 -+:100160007CDCC02068D00020C0360003CC000054E6 -+:100170007CB4800C8000006ACC8000407C41800010 -+:10018000CD81A29ECC800040CD80004080000068E0 -+:10019000CC000054C019FFFFCC800040CD81A29E4E -+:1001A0007C40C0007C4100007C414000CCC1A1FAF1 -+:1001B000CD01A1F9CD41A29DCCC00040CD000040B1 -+:1001C000CD400040CC4000407C408000A0000000BA -+:1001D0007E82800BCC000054CC8000407C40C0006C -+:1001E0007C4100007C414000CCC1A1FACD01A1F9C5 -+:1001F000CD41A29DCCC00040CD000040CD4000408C -+:10020000D04000407C408000A00000007E82800B37 -+:100210007C40C00030D00001CCC1A29F95000003FB -+:100220000414000104140002CD4003FBCC80004004 -+:1002300080000000CCC000407C40C000CC8000406A -+:10024000CCC1A2A280000000CCC000407C40C00015 -+:1002500028D4001FCC800040954000037C41000062 -+:10026000CCC000572918001FCCC000409580000367 -+:10027000CD000040CD00005880000261CC00007F1E -+:10028000C8200017C83000229A0000060E2800017E -+:10029000C824001E0A640001D4001240CE40004071 -+:1002A000C036C0009680000737747900041C000136 -+:1002B000CF400040CDC00040CF0003FA7C030000D7 -+:1002C000CA0C00107C41000094C000047C41400036 -+:1002D000D42002C4CDE000449B00000B7C41800090 -+:1002E000CC00004BCDA00049CD200041CD600041A5 -+:1002F000CDA0004106200001CE0000568000026122 -+:10030000CC00007FC8280020C82C0021CC0000634E -+:100310007EEA4001657400207F53402C269C000239 -+:100320007DF5C02069F80020CE80004BCE600049EA -+:10033000CDE00041CFA00041CE600041271C00026B -+:100340007DF5C02069F800207DB24001CF00004B50 -+:10035000CE600049CDE00041CFA00041800000BD4B -+:10036000CE600041C8200017C83000229A00000665 -+:100370000E280001C824001E0A640001D4001240A7 -+:10038000CE400040CA0C00107C41000094C0000B1D -+:10039000C036C0009680000737747900041C000145 -+:1003A000CF400040CDC00040CF0003FA7C030000E6 -+:1003B000800000B67C414000CC000048800000EF87 -+:1003C00000000000C8200017C81C00230E240002F3 -+:1003D00099C000157C4180000A200001CE00005623 -+:1003E000D4000440CC000040C036C000CA14001342 -+:1003F0009640000737747900CF400040CC000040A1 -+:10040000C83003FA80000104CF000022CC00002293 -+:100410009540015DCC00007FCCA00046800000002C -+:10042000CC20004680000261CC000064C820001788 -+:10043000C810001F9600000509100001D4000440F8 -+:10044000CD000040CD000022CC800040D0400040D4 -+:10045000C80C002594C0FEEBC8100008CD00004079 -+:10046000D4000FC080000000D4000FA27C40C00068 -+:100470007C410000CCC003FDCD0003FCCCC0004299 -+:10048000CD0000422914001F2918001031980007E0 -+:100490003B5C00017D76000B998000057D5E400B82 -+:1004A000CC00004280000261CC00004D2998000180 -+:1004B000292C00089980003D32EC000196000004D0 -+:1004C0002930000C80000261CC00004204140010AE -+:1004D000CD40004233300001342800018400015E29 -+:1004E000C81400039B40001B0438000C8400015E0C -+:1004F000C81400039B400017043800088400015E04 -+:10050000C81400039B400013043800048400015EFB -+:10051000C81400039B400015C80C03FD9A80000915 -+:10052000C81003FC9B000118CC00004D04140010FF -+:10053000CCC00042CD00004280000136CD400042D8 -+:1005400096C00111CC00004D80000261CC00004E2D -+:100550009AC00003CC00004DCC00004EDF830000A9 -+:1005600080000000D80301FF9AC00107CC00004DB5 -+:1005700080000261CC00004EC8180003C81C0003B4 -+:10058000C82000037D5D40037DA1C0037D5D400C5C -+:100590002A10001F299C001F7D1D000B7D17400B9A -+:1005A000880000007E92800B96400004CC00004E34 -+:1005B00080000261CC00004204380008CF80004275 -+:1005C000C8080003C80C0003C8100003C8140003C7 -+:1005D000C8180003C81C0003C8240003C82800036F -+:1005E00029FC001F2AB0001F7FF3C00B28F0001F5A -+:1005F0007FF3C00B2970001F7FF3C00B7D88800143 -+:100600007DCCC0017E5100017E9540017C9080022E -+:100610007CD4C0027CBC800B9AC000037C8F400B52 -+:1006200038B400019B4000D8CC00004D9BC000D6E0 -+:10063000CC00004EC80C03FDC81003FCCCC0004227 -+:100640008000016FCD000042D4000340D4000FC0F1 -+:10065000D4000FA2CC800040CC400040CC400040F1 -+:10066000CC4000407C40C000CCC00040CCC0000D5D -+:1006700080000000D04000407C40C0007C41000071 -+:10068000651400207D4D402C245800027D598020A7 -+:100690007C41C000CD80004269980020CD8000429E -+:1006A000CDC00042C023C00005E400027CA0800B46 -+:1006B000266400107CA4800CCC800040CDC000409B -+:1006C000CCC0004095C0000ECD00004009DC000108 -+:1006D000C828000396800008CE800040C834001D62 -+:1006E00097400000C834001D26A80008840002645A -+:1006F000CC2B000099C0FFF709DC0001DC3A0000B8 -+:10070000978000047C418000800001A325980002AE -+:10071000A00000007D808000C818001D7C40C00043 -+:1007200064D0000895800000C818001DCC1300009C -+:10073000CC800040CCC0004080000000CC40004095 -+:10074000C810001F7C40C000CC8000407CD1400C11 -+:10075000CD4000400518000180000000CD8000223F -+:100760007C40C0006450002084000264CC00006122 -+:100770007CD0C02CC8200017C8D6000099400008C3 -+:100780007C438000DF830000CFA0004F8400026420 -+:10079000CC00006280000000D040007F8000026139 -+:1007A000CC00006284000264CC000061C820001705 -+:1007B0007C40C000C036FF00C810000DC0303FFFB5 -+:1007C0007CF5400B7D51800B7D81800F9980000866 -+:1007D0007CF3800BDF830000CFA0004F8400026415 -+:1007E000CC00006280000000D040007F80000261E9 -+:1007F000CC000062840002647C40C00028DC000859 -+:1008000095C0001930DC00107C41000099C0000444 -+:100810006454002080000209C91D00007D15002CD1 -+:10082000C91E00007C4200007C4240007C418000E8 -+:100830007DE5C00B7DE280079A80000E41AC00058B -+:100840009AC000000AEC000130DC001099C00004DE -+:10085000000000008000020CC91D00008000020C96 -+:10086000C91E0000CC800040CCC00040D0400040F9 -+:10087000C80C002594C0FDE3C8100008CD0000405E -+:10088000D4000FC080000000D4000FA2D4000340A9 -+:10089000D4000FC0D4000FA2CC800040D040004054 -+:1008A0007C408000A00000007E82800BD40003C04A -+:1008B000D4000FC0D4000FA2CC800040D040004034 -+:1008C0007C408000A00000007E82800B7C40C00045 -+:1008D00030D000060D10000699000007C81400155E -+:1008E00099400005CC000052D4000340D4000FC052 -+:1008F000D4000FA2CC800040CCC00040800000009B -+:10090000D04000407C40C000CC4D0000DC3A0000EC -+:100910009780FDBC04CC000180000243CC4D000058 -+:100920007C40C0007C410000292400183264000192 -+:100930009640000FCC8000407C4140007C4180000C -+:100940007C41C000CCC00043CD00004331DC7FFFC0 -+:10095000CDC00043CCC00040CD000040CD400040A1 -+:10096000CD80004080000000CDC00040CCC00040E1 -+:10097000CD00004080000000D0400040800000001A -+:10098000D040007FCC00007F80000000CC00007FC2 -+:10099000CC00007F88000000CC00007F0000000039 -+:1009A0000000000000000000000000000000000047 -+:1009B0000000000000000000000000000000000037 -+:1009C0000000000000000000000000000000000027 -+:1009D0000000000000000000000000000000000017 -+:1009E0000000000000000000000000000000000007 -+:1009F00000000000000000000000000000000000F7 -+:100A000000000000000000000000000000000000E6 -+:100A100000000000000000000000000000000000D6 -+:100A200000000000000000000000000000000000C6 -+:100A300000000000000000000000000000000000B6 -+:100A400000000000000000000000000000000000A6 -+:100A50000000000000000000000000000000000096 -+:100A60000000000000000000000000000000000086 -+:100A70000000000000000000000000000000000076 -+:100A80000000000000000000000000000000000066 -+:100A90000000000000000000000000000000000056 -+:100AA0000000000000000000000000000000000046 -+:100AB0000000000000000000000000000000000036 -+:100AC0000000000000000000000000000000000026 -+:100AD0000000000000000000000000000000000016 -+:100AE0000000000000000000000000000000000006 -+:100AF00000000000000000000000000000000000F6 -+:100B000000000000000000000000000000000000E5 -+:100B100000000000000000000000000000000000D5 -+:100B200000000000000000000000000000000000C5 -+:100B300000000000000000000000000000000000B5 -+:100B400000000000000000000000000000000000A5 -+:100B50000000000000000000000000000000000095 -+:100B60000000000000000000000000000000000085 -+:100B70000000000000000000000000000000000075 -+:100B80000000000000000000000000000000000065 -+:100B90000000000000000000000000000000000055 -+:100BA0000000000000000000000000000000000045 -+:100BB0000000000000000000000000000000000035 -+:100BC0000000000000000000000000000000000025 -+:100BD0000000000000000000000000000000000015 -+:100BE0000000000000000000000000000000000005 -+:100BF00000000000000000000000000000000000F5 -+:100C0000000302230004022B000500A000020003E1 -+:100C10000006003C0007002700080192000900447C -+:100C2000000A002D0010025F001700F1002201D819 -+:100C3000002301E90026004C0027005F0020011B73 -+:100C4000002800930029004F002A0084002B006533 -+:100C5000002F008E003200D90034023300360075B8 -+:100C60000039010B003C01FD003F00A0004102489B -+:100C7000004401950048019E004901C6004A01D088 -+:100C8000005502260056022E0060000A0061002A6C -+:100C90000062003000630030006400300065003006 -+:100CA0000066003000670030006800370069003FD0 -+:100CB000006A0047006B0047006C0047006D00476A -+:100CC000006E0047006F0047007000470073025F2E -+:100CD000007B024100000005000000050000000547 -+:100CE00000000005000000050000000500000005F0 -+:100CF00000000005000000050000000500000005E0 -+:100D000000000005000000050000000500000005CF -+:100D100000000005000000050000000500000005BF -+:100D200000000005000000050000000500000005AF -+:100D3000000000050000000500000005000000059F -+:00000001FF -diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 45b67d9..eeefb63 100644 ---- a/include/drm/drmP.h -+++ b/include/drm/drmP.h -@@ -88,7 +88,37 @@ struct drm_device; - #define DRM_UT_CORE 0x01 - #define DRM_UT_DRIVER 0x02 - #define DRM_UT_KMS 0x04 --#define DRM_UT_MODE 0x08 -+/* -+ * Three debug levels are defined. -+ * drm_core, drm_driver, drm_kms -+ * drm_core level can be used in the generic drm code. For example: -+ * drm_ioctl, drm_mm, drm_memory -+ * The macro definiton of DRM_DEBUG is used. -+ * DRM_DEBUG(fmt, args...) -+ * The debug info by using the DRM_DEBUG can be obtained by adding -+ * the boot option of "drm.debug=1". -+ * -+ * drm_driver level can be used in the specific drm driver. It is used -+ * to add the debug info related with the drm driver. For example: -+ * i915_drv, i915_dma, i915_gem, radeon_drv, -+ * The macro definition of DRM_DEBUG_DRIVER can be used. -+ * DRM_DEBUG_DRIVER(fmt, args...) -+ * The debug info by using the DRM_DEBUG_DRIVER can be obtained by -+ * adding the boot option of "drm.debug=0x02" -+ * -+ * drm_kms level can be used in the KMS code related with specific drm driver. -+ * It is used to add the debug info related with KMS mode. For example: -+ * the connector/crtc , -+ * The macro definition of DRM_DEBUG_KMS can be used. -+ * DRM_DEBUG_KMS(fmt, args...) -+ * The debug info by using the DRM_DEBUG_KMS can be obtained by -+ * adding the boot option of "drm.debug=0x04" -+ * -+ * If we add the boot option of "drm.debug=0x06", we can get the debug info by -+ * using the DRM_DEBUG_KMS and DRM_DEBUG_DRIVER. -+ * If we add the boot option of "drm.debug=0x05", we can get the debug info by -+ * using the DRM_DEBUG_KMS and DRM_DEBUG. -+ */ - - extern void drm_ut_debug_printk(unsigned int request_level, - const char *prefix, -@@ -174,19 +204,14 @@ extern void drm_ut_debug_printk(unsigned int request_level, - __func__, fmt, ##args); \ - } while (0) - --#define DRM_DEBUG_DRIVER(prefix, fmt, args...) \ -+#define DRM_DEBUG_DRIVER(fmt, args...) \ - do { \ -- drm_ut_debug_printk(DRM_UT_DRIVER, prefix, \ -+ drm_ut_debug_printk(DRM_UT_DRIVER, DRM_NAME, \ - __func__, fmt, ##args); \ - } while (0) --#define DRM_DEBUG_KMS(prefix, fmt, args...) \ -- do { \ -- drm_ut_debug_printk(DRM_UT_KMS, prefix, \ -- __func__, fmt, ##args); \ -- } while (0) --#define DRM_DEBUG_MODE(prefix, fmt, args...) \ -+#define DRM_DEBUG_KMS(fmt, args...) \ - do { \ -- drm_ut_debug_printk(DRM_UT_MODE, prefix, \ -+ drm_ut_debug_printk(DRM_UT_KMS, DRM_NAME, \ - __func__, fmt, ##args); \ - } while (0) - #define DRM_LOG(fmt, args...) \ -@@ -210,9 +235,8 @@ extern void drm_ut_debug_printk(unsigned int request_level, - NULL, fmt, ##args); \ - } while (0) - #else --#define DRM_DEBUG_DRIVER(prefix, fmt, args...) do { } while (0) --#define DRM_DEBUG_KMS(prefix, fmt, args...) do { } while (0) --#define DRM_DEBUG_MODE(prefix, fmt, args...) do { } while (0) -+#define DRM_DEBUG_DRIVER(fmt, args...) do { } while (0) -+#define DRM_DEBUG_KMS(fmt, args...) do { } while (0) - #define DRM_DEBUG(fmt, arg...) do { } while (0) - #define DRM_LOG(fmt, arg...) do { } while (0) - #define DRM_LOG_KMS(fmt, args...) do { } while (0) -@@ -1417,7 +1441,7 @@ drm_gem_object_unreference(struct drm_gem_object *obj) - - int drm_gem_handle_create(struct drm_file *file_priv, - struct drm_gem_object *obj, -- int *handlep); -+ u32 *handlep); - - static inline void - drm_gem_object_handle_reference(struct drm_gem_object *obj) -@@ -1443,7 +1467,7 @@ drm_gem_object_handle_unreference(struct drm_gem_object *obj) - - struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev, - struct drm_file *filp, -- int handle); -+ u32 handle); - int drm_gem_close_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv); - int drm_gem_flink_ioctl(struct drm_device *dev, void *data, -diff --git a/include/drm/drm_cache.h b/include/drm/drm_cache.h -new file mode 100644 -index 0000000..7bfb063 ---- /dev/null -+++ b/include/drm/drm_cache.h -@@ -0,0 +1,38 @@ -+/************************************************************************** -+ * -+ * Copyright 2009 Red Hat Inc. -+ * All Rights Reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sub license, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial portions -+ * of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, -+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -+ * USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ * -+ **************************************************************************/ -+/* -+ * Authors: -+ * Dave Airlie -+ */ -+ -+#ifndef _DRM_CACHE_H_ -+#define _DRM_CACHE_H_ -+ -+void drm_clflush_pages(struct page *pages[], unsigned long num_pages); -+ -+#endif -diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h -index 7300fb8..ae1e9e1 100644 ---- a/include/drm/drm_crtc.h -+++ b/include/drm/drm_crtc.h -@@ -259,6 +259,8 @@ struct drm_framebuffer { - void *fbdev; - u32 pseudo_palette[17]; - struct list_head filp_head; -+ /* if you are using the helper */ -+ void *helper_private; - }; - - struct drm_property_blob { -@@ -572,6 +574,12 @@ struct drm_mode_config { - struct drm_property *tv_right_margin_property; - struct drm_property *tv_top_margin_property; - struct drm_property *tv_bottom_margin_property; -+ struct drm_property *tv_brightness_property; -+ struct drm_property *tv_contrast_property; -+ struct drm_property *tv_flicker_reduction_property; -+ struct drm_property *tv_overscan_property; -+ struct drm_property *tv_saturation_property; -+ struct drm_property *tv_hue_property; - - /* Optional properties */ - struct drm_property *scaling_mode_property; -@@ -736,4 +744,12 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, - extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, - void *data, struct drm_file *file_priv); - extern bool drm_detect_hdmi_monitor(struct edid *edid); -+extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, -+ int hdisplay, int vdisplay, int vrefresh, -+ bool reduced, bool interlaced); -+extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, -+ int hdisplay, int vdisplay, int vrefresh, -+ bool interlaced, int margins); -+extern int drm_add_modes_noedid(struct drm_connector *connector, -+ int hdisplay, int vdisplay); - #endif /* __DRM_CRTC_H__ */ -diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h -index 6769ff6..4c8daca 100644 ---- a/include/drm/drm_crtc_helper.h -+++ b/include/drm/drm_crtc_helper.h -@@ -79,6 +79,8 @@ struct drm_encoder_helper_funcs { - /* detect for DAC style encoders */ - enum drm_connector_status (*detect)(struct drm_encoder *encoder, - struct drm_connector *connector); -+ /* disable encoder when not in use - more explicit than dpms off */ -+ void (*disable)(struct drm_encoder *encoder); - }; - - struct drm_connector_helper_funcs { -@@ -98,6 +100,7 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, - int x, int y, - struct drm_framebuffer *old_fb); - extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); -+extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder); - - extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode); - -diff --git a/include/drm/drm_encoder_slave.h b/include/drm/drm_encoder_slave.h -new file mode 100644 -index 0000000..2f65633 ---- /dev/null -+++ b/include/drm/drm_encoder_slave.h -@@ -0,0 +1,162 @@ -+/* -+ * Copyright (C) 2009 Francisco Jerez. -+ * All Rights Reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the -+ * next paragraph) shall be included in all copies or substantial -+ * portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ */ -+ -+#ifndef __DRM_ENCODER_SLAVE_H__ -+#define __DRM_ENCODER_SLAVE_H__ -+ -+#include "drmP.h" -+#include "drm_crtc.h" -+ -+/** -+ * struct drm_encoder_slave_funcs - Entry points exposed by a slave encoder driver -+ * @set_config: Initialize any encoder-specific modesetting parameters. -+ * The meaning of the @params parameter is implementation -+ * dependent. It will usually be a structure with DVO port -+ * data format settings or timings. It's not required for -+ * the new parameters to take effect until the next mode -+ * is set. -+ * -+ * Most of its members are analogous to the function pointers in -+ * &drm_encoder_helper_funcs and they can optionally be used to -+ * initialize the latter. Connector-like methods (e.g. @get_modes and -+ * @set_property) will typically be wrapped around and only be called -+ * if the encoder is the currently selected one for the connector. -+ */ -+struct drm_encoder_slave_funcs { -+ void (*set_config)(struct drm_encoder *encoder, -+ void *params); -+ -+ void (*destroy)(struct drm_encoder *encoder); -+ void (*dpms)(struct drm_encoder *encoder, int mode); -+ void (*save)(struct drm_encoder *encoder); -+ void (*restore)(struct drm_encoder *encoder); -+ bool (*mode_fixup)(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode); -+ int (*mode_valid)(struct drm_encoder *encoder, -+ struct drm_display_mode *mode); -+ void (*mode_set)(struct drm_encoder *encoder, -+ struct drm_display_mode *mode, -+ struct drm_display_mode *adjusted_mode); -+ -+ enum drm_connector_status (*detect)(struct drm_encoder *encoder, -+ struct drm_connector *connector); -+ int (*get_modes)(struct drm_encoder *encoder, -+ struct drm_connector *connector); -+ int (*create_resources)(struct drm_encoder *encoder, -+ struct drm_connector *connector); -+ int (*set_property)(struct drm_encoder *encoder, -+ struct drm_connector *connector, -+ struct drm_property *property, -+ uint64_t val); -+ -+}; -+ -+/** -+ * struct drm_encoder_slave - Slave encoder struct -+ * @base: DRM encoder object. -+ * @slave_funcs: Slave encoder callbacks. -+ * @slave_priv: Slave encoder private data. -+ * @bus_priv: Bus specific data. -+ * -+ * A &drm_encoder_slave has two sets of callbacks, @slave_funcs and the -+ * ones in @base. The former are never actually called by the common -+ * CRTC code, it's just a convenience for splitting the encoder -+ * functions in an upper, GPU-specific layer and a (hopefully) -+ * GPU-agnostic lower layer: It's the GPU driver responsibility to -+ * call the slave methods when appropriate. -+ * -+ * drm_i2c_encoder_init() provides a way to get an implementation of -+ * this. -+ */ -+struct drm_encoder_slave { -+ struct drm_encoder base; -+ -+ struct drm_encoder_slave_funcs *slave_funcs; -+ void *slave_priv; -+ void *bus_priv; -+}; -+#define to_encoder_slave(x) container_of((x), struct drm_encoder_slave, base) -+ -+int drm_i2c_encoder_init(struct drm_device *dev, -+ struct drm_encoder_slave *encoder, -+ struct i2c_adapter *adap, -+ const struct i2c_board_info *info); -+ -+ -+/** -+ * struct drm_i2c_encoder_driver -+ * -+ * Describes a device driver for an encoder connected to the GPU -+ * through an I2C bus. In addition to the entry points in @i2c_driver -+ * an @encoder_init function should be provided. It will be called to -+ * give the driver an opportunity to allocate any per-encoder data -+ * structures and to initialize the @slave_funcs and (optionally) -+ * @slave_priv members of @encoder. -+ */ -+struct drm_i2c_encoder_driver { -+ struct i2c_driver i2c_driver; -+ -+ int (*encoder_init)(struct i2c_client *client, -+ struct drm_device *dev, -+ struct drm_encoder_slave *encoder); -+ -+}; -+#define to_drm_i2c_encoder_driver(x) container_of((x), \ -+ struct drm_i2c_encoder_driver, \ -+ i2c_driver) -+ -+/** -+ * drm_i2c_encoder_get_client - Get the I2C client corresponding to an encoder -+ */ -+static inline struct i2c_client *drm_i2c_encoder_get_client(struct drm_encoder *encoder) -+{ -+ return (struct i2c_client *)to_encoder_slave(encoder)->bus_priv; -+} -+ -+/** -+ * drm_i2c_encoder_register - Register an I2C encoder driver -+ * @owner: Module containing the driver. -+ * @driver: Driver to be registered. -+ */ -+static inline int drm_i2c_encoder_register(struct module *owner, -+ struct drm_i2c_encoder_driver *driver) -+{ -+ return i2c_register_driver(owner, &driver->i2c_driver); -+} -+ -+/** -+ * drm_i2c_encoder_unregister - Unregister an I2C encoder driver -+ * @driver: Driver to be unregistered. -+ */ -+static inline void drm_i2c_encoder_unregister(struct drm_i2c_encoder_driver *driver) -+{ -+ i2c_del_driver(&driver->i2c_driver); -+} -+ -+void drm_i2c_encoder_destroy(struct drm_encoder *encoder); -+ -+#endif -diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h -new file mode 100644 -index 0000000..88fffbd ---- /dev/null -+++ b/include/drm/drm_fb_helper.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (c) 2006-2009 Red Hat Inc. -+ * Copyright (c) 2006-2008 Intel Corporation -+ * Copyright (c) 2007 Dave Airlie -+ * -+ * DRM framebuffer helper functions -+ * -+ * Permission to use, copy, modify, distribute, and sell this software and its -+ * documentation for any purpose is hereby granted without fee, provided that -+ * the above copyright notice appear in all copies and that both that copyright -+ * notice and this permission notice appear in supporting documentation, and -+ * that the name of the copyright holders not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. The copyright holders make no representations -+ * about the suitability of this software for any purpose. It is provided "as -+ * is" without express or implied warranty. -+ * -+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -+ * OF THIS SOFTWARE. -+ * -+ * Authors: -+ * Dave Airlie -+ * Jesse Barnes -+ */ -+#ifndef DRM_FB_HELPER_H -+#define DRM_FB_HELPER_H -+ -+struct drm_fb_helper_crtc { -+ uint32_t crtc_id; -+ struct drm_mode_set mode_set; -+}; -+ -+struct drm_fb_helper_funcs { -+ void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, -+ u16 blue, int regno); -+}; -+ -+struct drm_fb_helper { -+ struct drm_framebuffer *fb; -+ struct drm_device *dev; -+ struct drm_display_mode *mode; -+ int crtc_count; -+ struct drm_fb_helper_crtc *crtc_info; -+ struct drm_fb_helper_funcs *funcs; -+ int conn_limit; -+ struct list_head kernel_fb_list; -+}; -+ -+int drm_fb_helper_single_fb_probe(struct drm_device *dev, -+ int (*fb_create)(struct drm_device *dev, -+ uint32_t fb_width, -+ uint32_t fb_height, -+ uint32_t surface_width, -+ uint32_t surface_height, -+ struct drm_framebuffer **fb_ptr)); -+int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, -+ int max_conn); -+void drm_fb_helper_free(struct drm_fb_helper *helper); -+int drm_fb_helper_blank(int blank, struct fb_info *info); -+int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, -+ struct fb_info *info); -+int drm_fb_helper_set_par(struct fb_info *info); -+int drm_fb_helper_check_var(struct fb_var_screeninfo *var, -+ struct fb_info *info); -+int drm_fb_helper_setcolreg(unsigned regno, -+ unsigned red, -+ unsigned green, -+ unsigned blue, -+ unsigned transp, -+ struct fb_info *info); -+ -+void drm_fb_helper_restore(void); -+void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, -+ uint32_t fb_width, uint32_t fb_height); -+void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); -+ -+#endif -diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h -index f833207..62329f9 100644 ---- a/include/drm/drm_mm.h -+++ b/include/drm/drm_mm.h -@@ -37,6 +37,9 @@ - * Generic range manager structs - */ - #include -+#ifdef CONFIG_DEBUG_FS -+#include -+#endif - - struct drm_mm_node { - struct list_head fl_entry; -@@ -96,4 +99,8 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) - return block->mm; - } - -+#ifdef CONFIG_DEBUG_FS -+int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm); -+#endif -+ - #endif -diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h -index ae304cc..1f90841 100644 ---- a/include/drm/drm_mode.h -+++ b/include/drm/drm_mode.h -@@ -68,10 +68,11 @@ - #define DRM_MODE_DPMS_OFF 3 - - /* Scaling mode options */ --#define DRM_MODE_SCALE_NON_GPU 0 --#define DRM_MODE_SCALE_FULLSCREEN 1 --#define DRM_MODE_SCALE_NO_SCALE 2 --#define DRM_MODE_SCALE_ASPECT 3 -+#define DRM_MODE_SCALE_NONE 0 /* Unmodified timing (display or -+ software can still scale) */ -+#define DRM_MODE_SCALE_FULLSCREEN 1 /* Full screen, ignore aspect */ -+#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */ -+#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */ - - /* Dithering mode options */ - #define DRM_MODE_DITHERING_OFF 0 -@@ -141,6 +142,7 @@ struct drm_mode_get_encoder { - #define DRM_MODE_SUBCONNECTOR_Composite 5 - #define DRM_MODE_SUBCONNECTOR_SVIDEO 6 - #define DRM_MODE_SUBCONNECTOR_Component 8 -+#define DRM_MODE_SUBCONNECTOR_SCART 9 - - #define DRM_MODE_CONNECTOR_Unknown 0 - #define DRM_MODE_CONNECTOR_VGA 1 -@@ -155,6 +157,7 @@ struct drm_mode_get_encoder { - #define DRM_MODE_CONNECTOR_DisplayPort 10 - #define DRM_MODE_CONNECTOR_HDMIA 11 - #define DRM_MODE_CONNECTOR_HDMIB 12 -+#define DRM_MODE_CONNECTOR_TV 13 - - struct drm_mode_get_connector { - -diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h -new file mode 100644 -index 0000000..1d8e033 ---- /dev/null -+++ b/include/drm/drm_sysfs.h -@@ -0,0 +1,12 @@ -+#ifndef _DRM_SYSFS_H_ -+#define _DRM_SYSFS_H_ -+ -+/** -+ * This minimalistic include file is intended for users (read TTM) that -+ * don't want to include the full drmP.h file. -+ */ -+ -+extern int drm_class_device_register(struct device *dev); -+extern void drm_class_device_unregister(struct device *dev); -+ -+#endif -diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h -index cd22ab4..4911461 100644 ---- a/include/drm/ttm/ttm_bo_api.h -+++ b/include/drm/ttm/ttm_bo_api.h -@@ -155,6 +155,7 @@ struct ttm_buffer_object { - * Members constant at init. - */ - -+ struct ttm_bo_global *glob; - struct ttm_bo_device *bdev; - unsigned long buffer_start; - enum ttm_bo_type type; -@@ -245,14 +246,15 @@ struct ttm_buffer_object { - * premapped region. - */ - -+#define TTM_BO_MAP_IOMEM_MASK 0x80 - struct ttm_bo_kmap_obj { - void *virtual; - struct page *page; - enum { -- ttm_bo_map_iomap, -- ttm_bo_map_vmap, -- ttm_bo_map_kmap, -- ttm_bo_map_premapped, -+ ttm_bo_map_iomap = 1 | TTM_BO_MAP_IOMEM_MASK, -+ ttm_bo_map_vmap = 2, -+ ttm_bo_map_kmap = 3, -+ ttm_bo_map_premapped = 4 | TTM_BO_MAP_IOMEM_MASK, - } bo_kmap_type; - }; - -@@ -522,8 +524,7 @@ extern int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type); - static inline void *ttm_kmap_obj_virtual(struct ttm_bo_kmap_obj *map, - bool *is_iomem) - { -- *is_iomem = (map->bo_kmap_type == ttm_bo_map_iomap || -- map->bo_kmap_type == ttm_bo_map_premapped); -+ *is_iomem = !!(map->bo_kmap_type & TTM_BO_MAP_IOMEM_MASK); - return map->virtual; - } - -diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h -index a68829d..e8cd6d2 100644 ---- a/include/drm/ttm/ttm_bo_driver.h -+++ b/include/drm/ttm/ttm_bo_driver.h -@@ -32,6 +32,7 @@ - - #include "ttm/ttm_bo_api.h" - #include "ttm/ttm_memory.h" -+#include "ttm/ttm_module.h" - #include "drm_mm.h" - #include "linux/workqueue.h" - #include "linux/fs.h" -@@ -161,7 +162,7 @@ struct ttm_tt { - long last_lomem_page; - uint32_t page_flags; - unsigned long num_pages; -- struct ttm_bo_device *bdev; -+ struct ttm_bo_global *glob; - struct ttm_backend *be; - struct task_struct *tsk; - unsigned long start; -@@ -364,24 +365,73 @@ struct ttm_bo_driver { - void (*fault_reserve_notify)(struct ttm_buffer_object *bo); - }; - --#define TTM_NUM_MEM_TYPES 8 -+/** -+ * struct ttm_bo_global_ref - Argument to initialize a struct ttm_bo_global. -+ */ -+ -+struct ttm_bo_global_ref { -+ struct ttm_global_reference ref; -+ struct ttm_mem_global *mem_glob; -+}; - --#define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs -- idling before CPU mapping */ --#define TTM_BO_PRIV_FLAG_MAX 1 - /** -- * struct ttm_bo_device - Buffer object driver device-specific data. -+ * struct ttm_bo_global - Buffer object driver global data. - * - * @mem_glob: Pointer to a struct ttm_mem_global object for accounting. -- * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. -- * @count: Current number of buffer object. -- * @pages: Current number of pinned pages. - * @dummy_read_page: Pointer to a dummy page used for mapping requests - * of unpopulated pages. -- * @shrink: A shrink callback object used for buffre object swap. -+ * @shrink: A shrink callback object used for buffer object swap. - * @ttm_bo_extra_size: Extra size (sizeof(struct ttm_buffer_object) excluded) - * used by a buffer object. This is excluding page arrays and backing pages. - * @ttm_bo_size: This is @ttm_bo_extra_size + sizeof(struct ttm_buffer_object). -+ * @device_list_mutex: Mutex protecting the device list. -+ * This mutex is held while traversing the device list for pm options. -+ * @lru_lock: Spinlock protecting the bo subsystem lru lists. -+ * @device_list: List of buffer object devices. -+ * @swap_lru: Lru list of buffer objects used for swapping. -+ */ -+ -+struct ttm_bo_global { -+ -+ /** -+ * Constant after init. -+ */ -+ -+ struct kobject kobj; -+ struct ttm_mem_global *mem_glob; -+ struct page *dummy_read_page; -+ struct ttm_mem_shrink shrink; -+ size_t ttm_bo_extra_size; -+ size_t ttm_bo_size; -+ struct mutex device_list_mutex; -+ spinlock_t lru_lock; -+ -+ /** -+ * Protected by device_list_mutex. -+ */ -+ struct list_head device_list; -+ -+ /** -+ * Protected by the lru_lock. -+ */ -+ struct list_head swap_lru; -+ -+ /** -+ * Internal protection. -+ */ -+ atomic_t bo_count; -+}; -+ -+ -+#define TTM_NUM_MEM_TYPES 8 -+ -+#define TTM_BO_PRIV_FLAG_MOVING 0 /* Buffer object is moving and needs -+ idling before CPU mapping */ -+#define TTM_BO_PRIV_FLAG_MAX 1 -+/** -+ * struct ttm_bo_device - Buffer object driver device-specific data. -+ * -+ * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. - * @man: An array of mem_type_managers. - * @addr_space_mm: Range manager for the device address space. - * lru_lock: Spinlock that protects the buffer+device lru lists and -@@ -399,32 +449,21 @@ struct ttm_bo_device { - /* - * Constant after bo device init / atomic. - */ -- -- struct ttm_mem_global *mem_glob; -+ struct list_head device_list; -+ struct ttm_bo_global *glob; - struct ttm_bo_driver *driver; -- struct page *dummy_read_page; -- struct ttm_mem_shrink shrink; -- -- size_t ttm_bo_extra_size; -- size_t ttm_bo_size; -- - rwlock_t vm_lock; -+ struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; - /* - * Protected by the vm lock. - */ -- struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; - struct rb_root addr_space_rb; - struct drm_mm addr_space_mm; - - /* -- * Might want to change this to one lock per manager. -- */ -- spinlock_t lru_lock; -- /* -- * Protected by the lru lock. -+ * Protected by the global:lru lock. - */ - struct list_head ddestroy; -- struct list_head swap_lru; - - /* - * Protected by load / firstopen / lastclose /unload sync. -@@ -640,6 +679,9 @@ extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, - unsigned long *bus_offset, - unsigned long *bus_size); - -+extern void ttm_bo_global_release(struct ttm_global_reference *ref); -+extern int ttm_bo_global_init(struct ttm_global_reference *ref); -+ - extern int ttm_bo_device_release(struct ttm_bo_device *bdev); - - /** -@@ -657,7 +699,7 @@ extern int ttm_bo_device_release(struct ttm_bo_device *bdev); - * !0: Failure. - */ - extern int ttm_bo_device_init(struct ttm_bo_device *bdev, -- struct ttm_mem_global *mem_glob, -+ struct ttm_bo_global *glob, - struct ttm_bo_driver *driver, - uint64_t file_page_offset, bool need_dma32); - -diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h -index d8b8f04..6983a7c 100644 ---- a/include/drm/ttm/ttm_memory.h -+++ b/include/drm/ttm/ttm_memory.h -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - /** - * struct ttm_mem_shrink - callback to shrink TTM memory usage. -@@ -60,34 +61,33 @@ struct ttm_mem_shrink { - * @queue: Wait queue for processes suspended waiting for memory. - * @lock: Lock to protect the @shrink - and the memory accounting members, - * that is, essentially the whole structure with some exceptions. -- * @emer_memory: Lowmem memory limit available for root. -- * @max_memory: Lowmem memory limit available for non-root. -- * @swap_limit: Lowmem memory limit where the shrink workqueue kicks in. -- * @used_memory: Currently used lowmem memory. -- * @used_total_memory: Currently used total (lowmem + highmem) memory. -- * @total_memory_swap_limit: Total memory limit where the shrink workqueue -- * kicks in. -- * @max_total_memory: Total memory available to non-root processes. -- * @emer_total_memory: Total memory available to root processes. -+ * @zones: Array of pointers to accounting zones. -+ * @num_zones: Number of populated entries in the @zones array. -+ * @zone_kernel: Pointer to the kernel zone. -+ * @zone_highmem: Pointer to the highmem zone if there is one. -+ * @zone_dma32: Pointer to the dma32 zone if there is one. - * - * Note that this structure is not per device. It should be global for all - * graphics devices. - */ - -+#define TTM_MEM_MAX_ZONES 2 -+struct ttm_mem_zone; - struct ttm_mem_global { -+ struct kobject kobj; - struct ttm_mem_shrink *shrink; - struct workqueue_struct *swap_queue; - struct work_struct work; - wait_queue_head_t queue; - spinlock_t lock; -- uint64_t emer_memory; -- uint64_t max_memory; -- uint64_t swap_limit; -- uint64_t used_memory; -- uint64_t used_total_memory; -- uint64_t total_memory_swap_limit; -- uint64_t max_total_memory; -- uint64_t emer_total_memory; -+ struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES]; -+ unsigned int num_zones; -+ struct ttm_mem_zone *zone_kernel; -+#ifdef CONFIG_HIGHMEM -+ struct ttm_mem_zone *zone_highmem; -+#else -+ struct ttm_mem_zone *zone_dma32; -+#endif - }; - - /** -@@ -146,8 +146,13 @@ static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob, - extern int ttm_mem_global_init(struct ttm_mem_global *glob); - extern void ttm_mem_global_release(struct ttm_mem_global *glob); - extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory, -- bool no_wait, bool interruptible, bool himem); -+ bool no_wait, bool interruptible); - extern void ttm_mem_global_free(struct ttm_mem_global *glob, -- uint64_t amount, bool himem); -+ uint64_t amount); -+extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, -+ struct page *page, -+ bool no_wait, bool interruptible); -+extern void ttm_mem_global_free_page(struct ttm_mem_global *glob, -+ struct page *page); - extern size_t ttm_round_pot(size_t size); - #endif -diff --git a/include/drm/ttm/ttm_module.h b/include/drm/ttm/ttm_module.h -index d1d4338..cf416ae 100644 ---- a/include/drm/ttm/ttm_module.h -+++ b/include/drm/ttm/ttm_module.h -@@ -32,6 +32,7 @@ - #define _TTM_MODULE_H_ - - #include -+struct kobject; - - #define TTM_PFX "[TTM] " - -@@ -54,5 +55,6 @@ extern void ttm_global_init(void); - extern void ttm_global_release(void); - extern int ttm_global_item_ref(struct ttm_global_reference *ref); - extern void ttm_global_item_unref(struct ttm_global_reference *ref); -+extern struct kobject *ttm_get_kobj(void); - - #endif /* _TTM_MODULE_H_ */ diff --git a/packages/linux/patches/0001-patch-v2.6.31-next-20090924.diff b/packages/linux/patches/0001-patch-v2.6.31-next-20090925.diff similarity index 95% rename from packages/linux/patches/0001-patch-v2.6.31-next-20090924.diff rename to packages/linux/patches/0001-patch-v2.6.31-next-20090925.diff index e7113e60aa..2561f40f10 100644 --- a/packages/linux/patches/0001-patch-v2.6.31-next-20090924.diff +++ b/packages/linux/patches/0001-patch-v2.6.31-next-20090925.diff @@ -39502,7 +39502,7 @@ index 0000000..074f4be + } +} diff --git a/Documentation/auxdisplay/cfag12864b-example.c b/Documentation/auxdisplay/cfag12864b-example.c -index 2caeea5..1d2c010 100644 +index 2caeea5..e7823ff 100644 --- a/Documentation/auxdisplay/cfag12864b-example.c +++ b/Documentation/auxdisplay/cfag12864b-example.c @@ -62,7 +62,7 @@ unsigned char cfag12864b_buffer[CFAG12864B_SIZE]; @@ -39595,7 +39595,11 @@ index 2caeea5..1d2c010 100644 { memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE); } -@@ -198,7 +198,7 @@ void cfag12864b_blit(void) +@@ -194,11 +194,10 @@ void cfag12864b_blit(void) + */ + + #include +-#include #define EXAMPLES 6 @@ -40967,6 +40971,135 @@ index 0000000..34916a4 +The images can be downloaded from: + +git.infradead.org/users/dwmw2/linux-firmware.git/libertas/ +diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt +index 6eb1a97..455d4e6 100644 +--- a/Documentation/cgroups/cgroups.txt ++++ b/Documentation/cgroups/cgroups.txt +@@ -408,6 +408,26 @@ You can attach the current shell task by echoing 0: + + # echo 0 > tasks + ++2.3 Mounting hierarchies by name ++-------------------------------- ++ ++Passing the name= option when mounting a cgroups hierarchy ++associates the given name with the hierarchy. This can be used when ++mounting a pre-existing hierarchy, in order to refer to it by name ++rather than by its set of active subsystems. Each hierarchy is either ++nameless, or has a unique name. ++ ++The name should match [\w.-]+ ++ ++When passing a name= option for a new hierarchy, you need to ++specify subsystems manually; the legacy behaviour of mounting all ++subsystems when none are explicitly specified is not supported when ++you give a subsystem a name. ++ ++The name of the subsystem appears as part of the hierarchy description ++in /proc/mounts and /proc//cgroups. ++ ++ + 3. Kernel API + ============= + +@@ -501,7 +521,7 @@ rmdir() will fail with it. From this behavior, pre_destroy() can be + called multiple times against a cgroup. + + int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, +- struct task_struct *task) ++ struct task_struct *task, bool threadgroup) + (cgroup_mutex held by caller) + + Called prior to moving a task into a cgroup; if the subsystem +@@ -509,14 +529,20 @@ returns an error, this will abort the attach operation. If a NULL + task is passed, then a successful result indicates that *any* + unspecified task can be moved into the cgroup. Note that this isn't + called on a fork. If this method returns 0 (success) then this should +-remain valid while the caller holds cgroup_mutex. ++remain valid while the caller holds cgroup_mutex. If threadgroup is ++true, then a successful result indicates that all threads in the given ++thread's threadgroup can be moved together. + + void attach(struct cgroup_subsys *ss, struct cgroup *cgrp, +- struct cgroup *old_cgrp, struct task_struct *task) ++ struct cgroup *old_cgrp, struct task_struct *task, ++ bool threadgroup) + (cgroup_mutex held by caller) + + Called after the task has been attached to the cgroup, to allow any + post-attachment activity that requires memory allocations or blocking. ++If threadgroup is true, the subsystem should take care of all threads ++in the specified thread's threadgroup. Currently does not support any ++subsystem that might need the old_cgrp for every thread in the group. + + void fork(struct cgroup_subsy *ss, struct task_struct *task) + +diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt +index 23d1262..b871f25 100644 +--- a/Documentation/cgroups/memory.txt ++++ b/Documentation/cgroups/memory.txt +@@ -179,6 +179,9 @@ The reclaim algorithm has not been modified for cgroups, except that + pages that are selected for reclaiming come from the per cgroup LRU + list. + ++NOTE: Reclaim does not work for the root cgroup, since we cannot set any ++limits on the root cgroup. ++ + 2. Locking + + The memory controller uses the following hierarchy +@@ -210,6 +213,7 @@ We can alter the memory limit: + NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo, + mega or gigabytes. + NOTE: We can write "-1" to reset the *.limit_in_bytes(unlimited). ++NOTE: We cannot set limits on the root cgroup any more. + + # cat /cgroups/0/memory.limit_in_bytes + 4194304 +@@ -375,7 +379,42 @@ cgroups created below it. + + NOTE2: This feature can be enabled/disabled per subtree. + +-7. TODO ++7. Soft limits ++ ++Soft limits allow for greater sharing of memory. The idea behind soft limits ++is to allow control groups to use as much of the memory as needed, provided ++ ++a. There is no memory contention ++b. They do not exceed their hard limit ++ ++When the system detects memory contention or low memory control groups ++are pushed back to their soft limits. If the soft limit of each control ++group is very high, they are pushed back as much as possible to make ++sure that one control group does not starve the others of memory. ++ ++Please note that soft limits is a best effort feature, it comes with ++no guarantees, but it does its best to make sure that when memory is ++heavily contended for, memory is allocated based on the soft limit ++hints/setup. Currently soft limit based reclaim is setup such that ++it gets invoked from balance_pgdat (kswapd). ++ ++7.1 Interface ++ ++Soft limits can be setup by using the following commands (in this example we ++assume a soft limit of 256 megabytes) ++ ++# echo 256M > memory.soft_limit_in_bytes ++ ++If we want to change this to 1G, we can at any time use ++ ++# echo 1G > memory.soft_limit_in_bytes ++ ++NOTE1: Soft limits take effect over a long period of time, since they involve ++ reclaiming memory for balancing between memory cgroups ++NOTE2: It is recommended to set the soft limit always below the hard limit, ++ otherwise the hard limit will take precedence. ++ ++8. TODO + + 1. Add support for accounting huge pages (as a separate controller) + 2. Make per-cgroup scanner reclaim not-shared pages first diff --git a/Documentation/connector/Makefile b/Documentation/connector/Makefile index 8df1a72..d98e4df 100644 --- a/Documentation/connector/Makefile @@ -42735,6 +42868,369 @@ index b843743..0d15ebc 100644 Then concatenate the output files out1 and out2 and get the right result. Yes, it is a thoroughly useless module, but the point is to show +diff --git a/Documentation/filesystems/sharedsubtree.txt b/Documentation/filesystems/sharedsubtree.txt +index 7365400..23a1810 100644 +--- a/Documentation/filesystems/sharedsubtree.txt ++++ b/Documentation/filesystems/sharedsubtree.txt +@@ -4,7 +4,7 @@ Shared Subtrees + Contents: + 1) Overview + 2) Features +- 3) smount command ++ 3) Setting mount states + 4) Use-case + 5) Detailed semantics + 6) Quiz +@@ -41,14 +41,14 @@ replicas continue to be exactly same. + + Here is an example: + +- Lets say /mnt has a mount that is shared. ++ Let's say /mnt has a mount that is shared. + mount --make-shared /mnt + +- note: mount command does not yet support the --make-shared flag. +- I have included a small C program which does the same by executing +- 'smount /mnt shared' ++ Note: mount(8) command now supports the --make-shared flag, ++ so the sample 'smount' program is no longer needed and has been ++ removed. + +- #mount --bind /mnt /tmp ++ # mount --bind /mnt /tmp + The above command replicates the mount at /mnt to the mountpoint /tmp + and the contents of both the mounts remain identical. + +@@ -58,8 +58,8 @@ replicas continue to be exactly same. + #ls /tmp + a b c + +- Now lets say we mount a device at /tmp/a +- #mount /dev/sd0 /tmp/a ++ Now let's say we mount a device at /tmp/a ++ # mount /dev/sd0 /tmp/a + + #ls /tmp/a + t1 t2 t2 +@@ -80,21 +80,20 @@ replicas continue to be exactly same. + + Here is an example: + +- Lets say /mnt has a mount which is shared. +- #mount --make-shared /mnt ++ Let's say /mnt has a mount which is shared. ++ # mount --make-shared /mnt + +- Lets bind mount /mnt to /tmp +- #mount --bind /mnt /tmp ++ Let's bind mount /mnt to /tmp ++ # mount --bind /mnt /tmp + + the new mount at /tmp becomes a shared mount and it is a replica of + the mount at /mnt. + +- Now lets make the mount at /tmp; a slave of /mnt +- #mount --make-slave /tmp +- [or smount /tmp slave] ++ Now let's make the mount at /tmp; a slave of /mnt ++ # mount --make-slave /tmp + +- lets mount /dev/sd0 on /mnt/a +- #mount /dev/sd0 /mnt/a ++ let's mount /dev/sd0 on /mnt/a ++ # mount /dev/sd0 /mnt/a + + #ls /mnt/a + t1 t2 t3 +@@ -104,9 +103,9 @@ replicas continue to be exactly same. + + Note the mount event has propagated to the mount at /tmp + +- However lets see what happens if we mount something on the mount at /tmp ++ However let's see what happens if we mount something on the mount at /tmp + +- #mount /dev/sd1 /tmp/b ++ # mount /dev/sd1 /tmp/b + + #ls /tmp/b + s1 s2 s3 +@@ -124,12 +123,11 @@ replicas continue to be exactly same. + + 2d) A unbindable mount is a unbindable private mount + +- lets say we have a mount at /mnt and we make is unbindable ++ let's say we have a mount at /mnt and we make is unbindable + +- #mount --make-unbindable /mnt +- [ smount /mnt unbindable ] ++ # mount --make-unbindable /mnt + +- Lets try to bind mount this mount somewhere else. ++ Let's try to bind mount this mount somewhere else. + # mount --bind /mnt /tmp + mount: wrong fs type, bad option, bad superblock on /mnt, + or too many mounted file systems +@@ -137,149 +135,15 @@ replicas continue to be exactly same. + Binding a unbindable mount is a invalid operation. + + +-3) smount command ++3) Setting mount states + +- Currently the mount command is not aware of shared subtree features. +- Work is in progress to add the support in mount ( util-linux package ). +- Till then use the following program. ++ The mount command (util-linux package) can be used to set mount ++ states: + +- ------------------------------------------------------------------------ +- // +- //this code was developed my Miklos Szeredi +- //and modified by Ram Pai +- // sample usage: +- // smount /tmp shared +- // +- #include +- #include +- #include +- #include +- #include +- #include +- +- #ifndef MS_REC +- #define MS_REC 0x4000 /* 16384: Recursive loopback */ +- #endif +- +- #ifndef MS_SHARED +- #define MS_SHARED 1<<20 /* Shared */ +- #endif +- +- #ifndef MS_PRIVATE +- #define MS_PRIVATE 1<<18 /* Private */ +- #endif +- +- #ifndef MS_SLAVE +- #define MS_SLAVE 1<<19 /* Slave */ +- #endif +- +- #ifndef MS_UNBINDABLE +- #define MS_UNBINDABLE 1<<17 /* Unbindable */ +- #endif +- +- int main(int argc, char *argv[]) +- { +- int type; +- if(argc != 3) { +- fprintf(stderr, "usage: %s dir " +- "\n" , argv[0]); +- return 1; +- } +- +- fprintf(stdout, "%s %s %s\n", argv[0], argv[1], argv[2]); +- +- if (strcmp(argv[2],"rshared")==0) +- type=(MS_SHARED|MS_REC); +- else if (strcmp(argv[2],"rslave")==0) +- type=(MS_SLAVE|MS_REC); +- else if (strcmp(argv[2],"rprivate")==0) +- type=(MS_PRIVATE|MS_REC); +- else if (strcmp(argv[2],"runbindable")==0) +- type=(MS_UNBINDABLE|MS_REC); +- else if (strcmp(argv[2],"shared")==0) +- type=MS_SHARED; +- else if (strcmp(argv[2],"slave")==0) +- type=MS_SLAVE; +- else if (strcmp(argv[2],"private")==0) +- type=MS_PRIVATE; +- else if (strcmp(argv[2],"unbindable")==0) +- type=MS_UNBINDABLE; +- else { +- fprintf(stderr, "invalid operation: %s\n", argv[2]); +- return 1; +- } +- setfsuid(getuid()); +- +- if(mount("", argv[1], "dontcare", type, "") == -1) { +- perror("mount"); +- return 1; +- } +- return 0; +- } +- ----------------------------------------------------------------------- +- +- Copy the above code snippet into smount.c +- gcc -o smount smount.c +- +- +- (i) To mark all the mounts under /mnt as shared execute the following +- command: +- +- smount /mnt rshared +- the corresponding syntax planned for mount command is +- mount --make-rshared /mnt +- +- just to mark a mount /mnt as shared, execute the following +- command: +- smount /mnt shared +- the corresponding syntax planned for mount command is +- mount --make-shared /mnt +- +- (ii) To mark all the shared mounts under /mnt as slave execute the +- following +- +- command: +- smount /mnt rslave +- the corresponding syntax planned for mount command is +- mount --make-rslave /mnt +- +- just to mark a mount /mnt as slave, execute the following +- command: +- smount /mnt slave +- the corresponding syntax planned for mount command is +- mount --make-slave /mnt +- +- (iii) To mark all the mounts under /mnt as private execute the +- following command: +- +- smount /mnt rprivate +- the corresponding syntax planned for mount command is +- mount --make-rprivate /mnt +- +- just to mark a mount /mnt as private, execute the following +- command: +- smount /mnt private +- the corresponding syntax planned for mount command is +- mount --make-private /mnt +- +- NOTE: by default all the mounts are created as private. But if +- you want to change some shared/slave/unbindable mount as +- private at a later point in time, this command can help. +- +- (iv) To mark all the mounts under /mnt as unbindable execute the +- following +- +- command: +- smount /mnt runbindable +- the corresponding syntax planned for mount command is +- mount --make-runbindable /mnt +- +- just to mark a mount /mnt as unbindable, execute the following +- command: +- smount /mnt unbindable +- the corresponding syntax planned for mount command is +- mount --make-unbindable /mnt ++ mount --make-shared mountpoint ++ mount --make-slave mountpoint ++ mount --make-private mountpoint ++ mount --make-unbindable mountpoint + + + 4) Use cases +@@ -350,7 +214,7 @@ replicas continue to be exactly same. + mount --rbind / /view/v3 + mount --rbind / /view/v4 + +- and if /usr has a versioning filesystem mounted, than that ++ and if /usr has a versioning filesystem mounted, then that + mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and + /view/v4/usr too + +@@ -390,7 +254,7 @@ replicas continue to be exactly same. + + For example: + mount --make-shared /mnt +- mount --bin /mnt /tmp ++ mount --bind /mnt /tmp + + The mount at /mnt and that at /tmp are both shared and belong + to the same peer group. Anything mounted or unmounted under +@@ -558,7 +422,7 @@ replicas continue to be exactly same. + then the subtree under the unbindable mount is pruned in the new + location. + +- eg: lets say we have the following mount tree. ++ eg: let's say we have the following mount tree. + + A + / \ +@@ -566,7 +430,7 @@ replicas continue to be exactly same. + / \ / \ + D E F G + +- Lets say all the mount except the mount C in the tree are ++ Let's say all the mount except the mount C in the tree are + of a type other than unbindable. + + If this tree is rbound to say Z +@@ -683,13 +547,13 @@ replicas continue to be exactly same. + 'b' on mounts that receive propagation from mount 'B' and does not have + sub-mounts within them are unmounted. + +- Example: Lets say 'B1', 'B2', 'B3' are shared mounts that propagate to ++ Example: Let's say 'B1', 'B2', 'B3' are shared mounts that propagate to + each other. + +- lets say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount ++ let's say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount + 'B1', 'B2' and 'B3' respectively. + +- lets say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on ++ let's say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on + mount 'B1', 'B2' and 'B3' respectively. + + if 'C1' is unmounted, all the mounts that are most-recently-mounted on +@@ -710,7 +574,7 @@ replicas continue to be exactly same. + A cloned namespace contains all the mounts as that of the parent + namespace. + +- Lets say 'A' and 'B' are the corresponding mounts in the parent and the ++ Let's say 'A' and 'B' are the corresponding mounts in the parent and the + child namespace. + + If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to +@@ -759,11 +623,11 @@ replicas continue to be exactly same. + mount --make-slave /mnt + + At this point we have the first mount at /tmp and +- its root dentry is 1. Lets call this mount 'A' ++ its root dentry is 1. Let's call this mount 'A' + And then we have a second mount at /tmp1 with root +- dentry 2. Lets call this mount 'B' ++ dentry 2. Let's call this mount 'B' + Next we have a third mount at /mnt with root dentry +- mnt. Lets call this mount 'C' ++ mnt. Let's call this mount 'C' + + 'B' is the slave of 'A' and 'C' is a slave of 'B' + A -> B -> C +@@ -794,7 +658,7 @@ replicas continue to be exactly same. + + Q3 Why is unbindable mount needed? + +- Lets say we want to replicate the mount tree at multiple ++ Let's say we want to replicate the mount tree at multiple + locations within the same subtree. + + if one rbind mounts a tree within the same subtree 'n' times +@@ -803,7 +667,7 @@ replicas continue to be exactly same. + mounts. Here is a example. + + step 1: +- lets say the root tree has just two directories with ++ let's say the root tree has just two directories with + one vfsmount. + root + / \ +@@ -875,7 +739,7 @@ replicas continue to be exactly same. + Unclonable mounts come in handy here. + + step 1: +- lets say the root tree has just two directories with ++ let's say the root tree has just two directories with + one vfsmount. + root + / \ diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index b58b84b..eed520f 100644 --- a/Documentation/filesystems/vfat.txt @@ -44877,7 +45373,7 @@ index 0000000..f40a1f0 +SINIT ACM for a system is documented in the SINIT-guide.txt file +that is on the tboot SourceForge site under the SINIT ACM downloads. diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt -index dbea4f9..aafca0a 100644 +index dbea4f9..9473749 100644 --- a/Documentation/ioctl/ioctl-number.txt +++ b/Documentation/ioctl/ioctl-number.txt @@ -121,6 +121,7 @@ Code Seq# Include File Comments @@ -44888,7 +45384,15 @@ index dbea4f9..aafca0a 100644 'd' 00-FF linux/char/drm/drm/h conflict! 'd' F0-FF linux/digi1.h 'e' all linux/digi1.h conflict! -@@ -192,7 +193,7 @@ Code Seq# Include File Comments +@@ -134,6 +135,7 @@ Code Seq# Include File Comments + + 'l' 40-7F linux/udf_fs_i.h in development: + ++'m' 00-09 linux/mmtimer.h + 'm' all linux/mtio.h conflict! + 'm' all linux/soundcard.h conflict! + 'm' all linux/synclink.h conflict! +@@ -192,7 +194,7 @@ Code Seq# Include File Comments 0xAD 00 Netfilter device in development: 0xAE all linux/kvm.h Kernel-based Virtual Machine @@ -46374,10 +46878,41 @@ index 0000000..c1c5be8 + http://sourceforge.net/projects/acpi4asus + diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt -index e2ddcde..6d03487 100644 +index e2ddcde..aafcaa6 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt -@@ -219,7 +219,7 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file: +@@ -199,18 +199,22 @@ kind to allow it (and it often doesn't!). + + Not all bits in the mask can be modified. Not all bits that can be + modified do anything. Not all hot keys can be individually controlled +-by the mask. Some models do not support the mask at all, and in those +-models, hot keys cannot be controlled individually. The behaviour of +-the mask is, therefore, highly dependent on the ThinkPad model. ++by the mask. Some models do not support the mask at all. The behaviour ++of the mask is, therefore, highly dependent on the ThinkPad model. ++ ++The driver will filter out any unmasked hotkeys, so even if the firmware ++doesn't allow disabling an specific hotkey, the driver will not report ++events for unmasked hotkeys. + + Note that unmasking some keys prevents their default behavior. For + example, if Fn+F5 is unmasked, that key will no longer enable/disable +-Bluetooth by itself. ++Bluetooth by itself in firmware. + +-Note also that not all Fn key combinations are supported through ACPI. +-For example, on the X40, the brightness, volume and "Access IBM" buttons +-do not generate ACPI events even with this driver. They *can* be used +-through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/ ++Note also that not all Fn key combinations are supported through ACPI ++depending on the ThinkPad model and firmware version. On those ++ThinkPads, it is still possible to support some extra hotkeys by ++polling the "CMOS NVRAM" at least 10 times per second. The driver ++attempts to enables this functionality automatically when required. + + procfs notes: + +@@ -219,7 +223,7 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file: echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys ... any other 8-hex-digit mask ... @@ -46386,7 +46921,7 @@ index e2ddcde..6d03487 100644 The following commands have been deprecated and will cause the kernel to log a warning: -@@ -240,9 +240,13 @@ sysfs notes: +@@ -240,9 +244,13 @@ sysfs notes: Returns 0. hotkey_bios_mask: @@ -46401,6 +46936,84 @@ index e2ddcde..6d03487 100644 hotkey_enable: DEPRECATED, WILL BE REMOVED SOON. +@@ -251,18 +259,11 @@ sysfs notes: + 1: does nothing + + hotkey_mask: +- bit mask to enable driver-handling (and depending on ++ bit mask to enable reporting (and depending on + the firmware, ACPI event generation) for each hot key + (see above). Returns the current status of the hot keys + mask, and allows one to modify it. + +- Note: when NVRAM polling is active, the firmware mask +- will be different from the value returned by +- hotkey_mask. The driver will retain enabled bits for +- hotkeys that are under NVRAM polling even if the +- firmware refuses them, and will not set these bits on +- the firmware hot key mask. +- + hotkey_all_mask: + bit mask that should enable event reporting for all + supported hot keys, when echoed to hotkey_mask above. +@@ -275,7 +276,8 @@ sysfs notes: + bit mask that should enable event reporting for all + supported hot keys, except those which are always + handled by the firmware anyway. Echo it to +- hotkey_mask above, to use. ++ hotkey_mask above, to use. This is the default mask ++ used by the driver. + + hotkey_source_mask: + bit mask that selects which hot keys will the driver +@@ -283,9 +285,10 @@ sysfs notes: + based on the capabilities reported by the ACPI firmware, + but it can be overridden at runtime. + +- Hot keys whose bits are set in both hotkey_source_mask +- and also on hotkey_mask are polled for in NVRAM. Only a +- few hot keys are available through CMOS NVRAM polling. ++ Hot keys whose bits are set in hotkey_source_mask are ++ polled for in NVRAM, and reported as hotkey events if ++ enabled in hotkey_mask. Only a few hot keys are ++ available through CMOS NVRAM polling. + + Warning: when in NVRAM mode, the volume up/down/mute + keys are synthesized according to changes in the mixer, +@@ -521,6 +524,7 @@ compatibility purposes when hotkey_report_mode is set to 1. + 0x2305 System is waking up from suspend to eject bay + 0x2404 System is waking up from hibernation to undock + 0x2405 System is waking up from hibernation to eject bay ++0x5010 Brightness level changed/control event + + The above events are never propagated by the driver. + +@@ -528,7 +532,6 @@ The above events are never propagated by the driver. + 0x4003 Undocked (see 0x2x04), can sleep again + 0x500B Tablet pen inserted into its storage bay + 0x500C Tablet pen removed from its storage bay +-0x5010 Brightness level changed (newer Lenovo BIOSes) + + The above events are propagated by the driver. + +@@ -617,6 +620,8 @@ For Lenovo models *with* ACPI backlight control: + 2. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, + and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process + these keys on userspace somehow (e.g. by calling xbacklight). ++ The driver will do this automatically if it detects that ACPI video ++ has been disabled. + + + Bluetooth +@@ -1455,3 +1460,8 @@ Sysfs interface changelog: + 0x020400: Marker for 16 LEDs support. Also, LEDs that are known + to not exist in a given model are not registered with + the LED sysfs class anymore. ++ ++0x020500: Updated hotkey driver, hotkey_mask is always available ++ and it is always able to disable hot keys. Very old ++ thinkpads are properly supported. hotkey_bios_mask ++ is deprecated and marked for removal. diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt index 6399557..8fd5ca2 100644 --- a/Documentation/leds-class.txt @@ -48070,19 +48683,50 @@ index c1a5aad..10abd37 100644 { while (1) { static const struct option lopts[] = { +diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt +index 1458448..6268250 100644 +--- a/Documentation/sysctl/fs.txt ++++ b/Documentation/sysctl/fs.txt +@@ -96,13 +96,16 @@ handles that the Linux kernel will allocate. When you get lots + of error messages about running out of file handles, you might + want to increase this limit. + +-The three values in file-nr denote the number of allocated +-file handles, the number of unused file handles and the maximum +-number of file handles. When the allocated file handles come +-close to the maximum, but the number of unused file handles is +-significantly greater than 0, you've encountered a peak in your +-usage of file handles and you don't need to increase the maximum. +- ++Historically, the three values in file-nr denoted the number of ++allocated file handles, the number of allocated but unused file ++handles, and the maximum number of file handles. Linux 2.6 always ++reports 0 as the number of free file handles -- this is not an ++error, it just means that the number of allocated file handles ++exactly matches the number of used file handles. ++ ++Attempts to allocate more file descriptors than file-max are ++reported with printk, look for "VFS: file-max limit ++reached". + ============================================================== + + nr_open: diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt -index 322a00b..b3d8b49 100644 +index 322a00b..a028b92 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt -@@ -19,6 +19,7 @@ Currently, these files might (depending on your configuration) +@@ -19,8 +19,10 @@ Currently, these files might (depending on your configuration) show up in /proc/sys/kernel: - acpi_video_flags - acct +- callhome [ S390 only ] - auto_msgmni - core_pattern ++- core_pipe_limit - core_uses_pid -@@ -91,6 +92,21 @@ valid for 30 seconds. + - ctrl-alt-del + - dentry-state +@@ -91,6 +93,21 @@ valid for 30 seconds. ============================================================== @@ -48104,7 +48748,35 @@ index 322a00b..b3d8b49 100644 core_pattern: core_pattern is used to specify a core dumpfile pattern name. -@@ -297,31 +313,43 @@ send before ratelimiting kicks in. +@@ -119,6 +136,27 @@ core_pattern is used to specify a core dumpfile pattern name. + + ============================================================== + ++core_pipe_limit: ++ ++This sysctl is only applicable when core_pattern is configured to pipe core ++files to user space helper a (when the first character of core_pattern is a '|', ++see above). When collecting cores via a pipe to an application, it is ++occasionally usefull for the collecting application to gather data about the ++crashing process from its /proc/pid directory. In order to do this safely, the ++kernel must wait for the collecting process to exit, so as not to remove the ++crashing processes proc files prematurely. This in turn creates the possibility ++that a misbehaving userspace collecting process can block the reaping of a ++crashed process simply by never exiting. This sysctl defends against that. It ++defines how many concurrent crashing processes may be piped to user space ++applications in parallel. If this value is exceeded, then those crashing ++processes above that value are noted via the kernel log and their cores are ++skipped. 0 is a special value, indicating that unlimited processes may be ++captured in parallel, but that no waiting will take place (i.e. the collecting ++process is not guaranteed access to /proc//). This value defaults ++to 0. ++ ++============================================================== ++ + core_uses_pid: + + The default coredump filename is "core". By setting +@@ -297,31 +335,43 @@ send before ratelimiting kicks in. ============================================================== @@ -48134,13 +48806,13 @@ index 322a00b..b3d8b49 100644 + loaded to random addresses. Also for PIE-linked binaries, the + location of code start is randomized. This is the default if the + CONFIG_COMPAT_BRK option is enabled. -+ -+2 - Additionally enable heap randomization. This is the default if -+ CONFIG_COMPAT_BRK is disabled. - With heap randomization, the situation is a little bit more - complicated. - There a few legacy applications out there (such as some ancient ++2 - Additionally enable heap randomization. This is the default if ++ CONFIG_COMPAT_BRK is disabled. ++ + There are a few legacy applications out there (such as some ancient versions of libc.so.5 from 1996) that assume that brk area starts - just after the end of the code+bss. These applications break when @@ -52045,6 +52717,13 @@ index 05769cf..c8ded17 100644 long i, tot = 0; for (i=0;i + */ + ++#define _LARGEFILE64_SOURCE + #include + #include + #include +@@ -13,12 +14,33 @@ + #include + #include + #include ++#include + #include + #include + #include + + + /* ++ * pagemap kernel ABI bits ++ */ ++ ++#define PM_ENTRY_BYTES sizeof(uint64_t) ++#define PM_STATUS_BITS 3 ++#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS) ++#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET) ++#define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK) ++#define PM_PSHIFT_BITS 6 ++#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS) ++#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET) ++#define PM_PSHIFT(x) (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK) ++#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1) ++#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK) ++ ++#define PM_PRESENT PM_STATUS(4LL) ++#define PM_SWAP PM_STATUS(2LL) ++ ++ ++/* + * kernel page flags + */ + +@@ -126,6 +148,14 @@ static int nr_addr_ranges; + static unsigned long opt_offset[MAX_ADDR_RANGES]; + static unsigned long opt_size[MAX_ADDR_RANGES]; + ++#define MAX_VMAS 10240 ++static int nr_vmas; ++static unsigned long pg_start[MAX_VMAS]; ++static unsigned long pg_end[MAX_VMAS]; ++static unsigned long voffset; ++ ++static int pagemap_fd; ++ + #define MAX_BIT_FILTERS 64 + static int nr_bit_filters; + static uint64_t opt_mask[MAX_BIT_FILTERS]; +@@ -135,7 +165,6 @@ static int page_size; + + #define PAGES_BATCH (64 << 10) /* 64k pages */ + static int kpageflags_fd; +-static uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH]; + + #define HASH_SHIFT 13 + #define HASH_SIZE (1 << HASH_SHIFT) +@@ -158,12 +187,17 @@ static uint64_t page_flags[HASH_SIZE]; type __min2 = (y); \ __min1 < __min2 ? __min1 : __min2; }) -unsigned long pages2mb(unsigned long pages) ++#define max_t(type, x, y) ({ \ ++ type __max1 = (x); \ ++ type __max2 = (y); \ ++ __max1 > __max2 ? __max1 : __max2; }) ++ +static unsigned long pages2mb(unsigned long pages) { return (pages * page_size) >> 20; @@ -52502,7 +53264,7 @@ index 0833f44..3eda8ea 100644 { va_list ap; -@@ -178,7 +178,7 @@ void fatal(const char *x, ...) +@@ -178,7 +212,7 @@ void fatal(const char *x, ...) * page flag names */ @@ -52511,7 +53273,7 @@ index 0833f44..3eda8ea 100644 { static char buf[65]; int present; -@@ -197,7 +197,7 @@ char *page_flag_name(uint64_t flags) +@@ -197,7 +231,7 @@ char *page_flag_name(uint64_t flags) return buf; } @@ -52520,7 +53282,7 @@ index 0833f44..3eda8ea 100644 { static char buf[1024]; int i, n; -@@ -221,7 +221,7 @@ char *page_flag_longname(uint64_t flags) +@@ -221,32 +255,40 @@ char *page_flag_longname(uint64_t flags) * page list and summary */ @@ -52528,15 +53290,39 @@ index 0833f44..3eda8ea 100644 +static void show_page_range(unsigned long offset, uint64_t flags) { static uint64_t flags0; ++ static unsigned long voff; static unsigned long index; -@@ -241,12 +241,12 @@ void show_page_range(unsigned long offset, uint64_t flags) + static unsigned long count; + +- if (flags == flags0 && offset == index + count) { ++ if (flags == flags0 && offset == index + count && ++ (!opt_pid || voffset == voff + count)) { + count++; + return; + } + +- if (count) +- printf("%lu\t%lu\t%s\n", ++ if (count) { ++ if (opt_pid) ++ printf("%lx\t", voff); ++ printf("%lx\t%lx\t%s\n", + index, count, page_flag_name(flags0)); ++ } + + flags0 = flags; + index = offset; ++ voff = voffset; count = 1; } -void show_page(unsigned long offset, uint64_t flags) +static void show_page(unsigned long offset, uint64_t flags) { - printf("%lu\t%s\n", offset, page_flag_name(flags)); +- printf("%lu\t%s\n", offset, page_flag_name(flags)); ++ if (opt_pid) ++ printf("%lx\t", voffset); ++ printf("%lx\t%s\n", offset, page_flag_name(flags)); } -void show_summary(void) @@ -52544,7 +53330,7 @@ index 0833f44..3eda8ea 100644 { int i; -@@ -272,7 +272,7 @@ void show_summary(void) +@@ -272,7 +314,7 @@ void show_summary(void) * page flag filters */ @@ -52553,7 +53339,7 @@ index 0833f44..3eda8ea 100644 { int i; -@@ -289,7 +289,7 @@ int bit_mask_ok(uint64_t flags) +@@ -289,7 +331,7 @@ int bit_mask_ok(uint64_t flags) return 1; } @@ -52562,7 +53348,7 @@ index 0833f44..3eda8ea 100644 { /* SLOB/SLUB overload several page flags */ if (flags & BIT(SLAB)) { -@@ -308,7 +308,7 @@ uint64_t expand_overloaded_flags(uint64_t flags) +@@ -308,7 +350,7 @@ uint64_t expand_overloaded_flags(uint64_t flags) return flags; } @@ -52571,7 +53357,7 @@ index 0833f44..3eda8ea 100644 { /* hide flags intended only for kernel hacker */ flags &= ~KPF_HACKERS_BITS; -@@ -325,7 +325,7 @@ uint64_t well_known_flags(uint64_t flags) +@@ -325,7 +367,7 @@ uint64_t well_known_flags(uint64_t flags) * page frame walker */ @@ -52580,7 +53366,7 @@ index 0833f44..3eda8ea 100644 { int k = HASH_KEY(flags); int i; -@@ -352,7 +352,7 @@ int hash_slot(uint64_t flags) +@@ -352,7 +394,7 @@ int hash_slot(uint64_t flags) exit(EXIT_FAILURE); } @@ -52589,7 +53375,7 @@ index 0833f44..3eda8ea 100644 { flags = expand_overloaded_flags(flags); -@@ -371,7 +371,7 @@ void add_page(unsigned long offset, uint64_t flags) +@@ -371,7 +413,7 @@ void add_page(unsigned long offset, uint64_t flags) total_pages++; } @@ -52598,16 +53384,116 @@ index 0833f44..3eda8ea 100644 { unsigned long batch; unsigned long n; -@@ -404,7 +404,7 @@ void walk_pfn(unsigned long index, unsigned long count) +@@ -383,6 +425,8 @@ void walk_pfn(unsigned long index, unsigned long count) + lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET); + + while (count) { ++ uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH]; ++ + batch = min_t(unsigned long, count, PAGES_BATCH); + n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES); + if (n == 0) +@@ -404,7 +448,82 @@ void walk_pfn(unsigned long index, unsigned long count) } } -void walk_addr_ranges(void) ++ ++#define PAGEMAP_BATCH 4096 ++static unsigned long task_pfn(unsigned long pgoff) ++{ ++ static uint64_t buf[PAGEMAP_BATCH]; ++ static unsigned long start; ++ static long count; ++ uint64_t pfn; ++ ++ if (pgoff < start || pgoff >= start + count) { ++ if (lseek64(pagemap_fd, ++ (uint64_t)pgoff * PM_ENTRY_BYTES, ++ SEEK_SET) < 0) { ++ perror("pagemap seek"); ++ exit(EXIT_FAILURE); ++ } ++ count = read(pagemap_fd, buf, sizeof(buf)); ++ if (count == 0) ++ return 0; ++ if (count < 0) { ++ perror("pagemap read"); ++ exit(EXIT_FAILURE); ++ } ++ if (count % PM_ENTRY_BYTES) { ++ fatal("pagemap read not aligned.\n"); ++ exit(EXIT_FAILURE); ++ } ++ count /= PM_ENTRY_BYTES; ++ start = pgoff; ++ } ++ ++ pfn = buf[pgoff - start]; ++ if (pfn & PM_PRESENT) ++ pfn = PM_PFRAME(pfn); ++ else ++ pfn = 0; ++ ++ return pfn; ++} ++ ++static void walk_task(unsigned long index, unsigned long count) ++{ ++ int i = 0; ++ const unsigned long end = index + count; ++ ++ while (index < end) { ++ ++ while (pg_end[i] <= index) ++ if (++i >= nr_vmas) ++ return; ++ if (pg_start[i] >= end) ++ return; ++ ++ voffset = max_t(unsigned long, pg_start[i], index); ++ index = min_t(unsigned long, pg_end[i], end); ++ ++ assert(voffset < index); ++ for (; voffset < index; voffset++) { ++ unsigned long pfn = task_pfn(voffset); ++ if (pfn) ++ walk_pfn(pfn, 1); ++ } ++ } ++} ++ ++static void add_addr_range(unsigned long offset, unsigned long size) ++{ ++ if (nr_addr_ranges >= MAX_ADDR_RANGES) ++ fatal("too many addr ranges\n"); ++ ++ opt_offset[nr_addr_ranges] = offset; ++ opt_size[nr_addr_ranges] = min_t(unsigned long, size, ULONG_MAX-offset); ++ nr_addr_ranges++; ++} ++ +static void walk_addr_ranges(void) { int i; -@@ -428,7 +428,7 @@ void walk_addr_ranges(void) +@@ -415,10 +534,13 @@ void walk_addr_ranges(void) + } + + if (!nr_addr_ranges) +- walk_pfn(0, ULONG_MAX); ++ add_addr_range(0, ULONG_MAX); + + for (i = 0; i < nr_addr_ranges; i++) +- walk_pfn(opt_offset[i], opt_size[i]); ++ if (!opt_pid) ++ walk_pfn(opt_offset[i], opt_size[i]); ++ else ++ walk_task(opt_offset[i], opt_size[i]); + + close(kpageflags_fd); + } +@@ -428,7 +550,7 @@ void walk_addr_ranges(void) * user interface */ @@ -52616,7 +53502,7 @@ index 0833f44..3eda8ea 100644 { if (flag & KPF_HACKERS_BITS) return "(r)"; -@@ -437,7 +437,7 @@ const char *page_flag_type(uint64_t flag) +@@ -437,7 +559,7 @@ const char *page_flag_type(uint64_t flag) return " "; } @@ -52625,7 +53511,26 @@ index 0833f44..3eda8ea 100644 { int i, j; -@@ -482,7 +482,7 @@ void usage(void) +@@ -446,8 +568,8 @@ void usage(void) + " -r|--raw Raw mode, for kernel developers\n" + " -a|--addr addr-spec Walk a range of pages\n" + " -b|--bits bits-spec Walk pages with specified bits\n" +-#if 0 /* planned features */ + " -p|--pid pid Walk process address space\n" ++#if 0 /* planned features */ + " -f|--file filename Walk file address space\n" + #endif + " -l|--list Show page details in ranges\n" +@@ -459,7 +581,7 @@ void usage(void) + " N+M pages range from N to N+M-1\n" + " N,M pages range from N to M-1\n" + " N, pages range from N to end\n" +-" ,M pages range from 0 to M\n" ++" ,M pages range from 0 to M-1\n" + "bits-spec:\n" + " bit1,bit2 (flags & (bit1|bit2)) != 0\n" + " bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1\n" +@@ -482,7 +604,7 @@ void usage(void) "(r) raw mode bits (o) overloaded bits\n"); } @@ -52634,28 +53539,74 @@ index 0833f44..3eda8ea 100644 { unsigned long long n; -@@ -494,16 +494,16 @@ unsigned long long parse_number(const char *str) +@@ -494,26 +616,62 @@ unsigned long long parse_number(const char *str) return n; } -void parse_pid(const char *str) +static void parse_pid(const char *str) { ++ FILE *file; ++ char buf[5000]; ++ opt_pid = parse_number(str); - } +-} -void parse_file(const char *name) -+static void parse_file(const char *name) - { +-{ ++ sprintf(buf, "/proc/%d/pagemap", opt_pid); ++ pagemap_fd = open(buf, O_RDONLY); ++ if (pagemap_fd < 0) { ++ perror(buf); ++ exit(EXIT_FAILURE); ++ } ++ ++ sprintf(buf, "/proc/%d/maps", opt_pid); ++ file = fopen(buf, "r"); ++ if (!file) { ++ perror(buf); ++ exit(EXIT_FAILURE); ++ } ++ ++ while (fgets(buf, sizeof(buf), file) != NULL) { ++ unsigned long vm_start; ++ unsigned long vm_end; ++ unsigned long long pgoff; ++ int major, minor; ++ char r, w, x, s; ++ unsigned long ino; ++ int n; ++ ++ n = sscanf(buf, "%lx-%lx %c%c%c%c %llx %x:%x %lu", ++ &vm_start, ++ &vm_end, ++ &r, &w, &x, &s, ++ &pgoff, ++ &major, &minor, ++ &ino); ++ if (n < 10) { ++ fprintf(stderr, "unexpected line: %s\n", buf); ++ continue; ++ } ++ pg_start[nr_vmas] = vm_start / page_size; ++ pg_end[nr_vmas] = vm_end / page_size; ++ if (++nr_vmas >= MAX_VMAS) { ++ fprintf(stderr, "too many VMAs\n"); ++ break; ++ } ++ } ++ fclose(file); } -void add_addr_range(unsigned long offset, unsigned long size) -+static void add_addr_range(unsigned long offset, unsigned long size) ++static void parse_file(const char *name) { - if (nr_addr_ranges >= MAX_ADDR_RANGES) - fatal("too much addr ranges\n"); -@@ -513,7 +513,7 @@ void add_addr_range(unsigned long offset, unsigned long size) - nr_addr_ranges++; +- if (nr_addr_ranges >= MAX_ADDR_RANGES) +- fatal("too much addr ranges\n"); +- +- opt_offset[nr_addr_ranges] = offset; +- opt_size[nr_addr_ranges] = size; +- nr_addr_ranges++; } -void parse_addr_range(const char *optarg) @@ -52663,7 +53614,7 @@ index 0833f44..3eda8ea 100644 { unsigned long offset; unsigned long size; -@@ -547,7 +547,7 @@ void parse_addr_range(const char *optarg) +@@ -547,7 +705,7 @@ void parse_addr_range(const char *optarg) add_addr_range(offset, size); } @@ -52672,7 +53623,7 @@ index 0833f44..3eda8ea 100644 { if (nr_bit_filters >= MAX_BIT_FILTERS) fatal("too much bit filters\n"); -@@ -557,7 +557,7 @@ void add_bits_filter(uint64_t mask, uint64_t bits) +@@ -557,7 +715,7 @@ void add_bits_filter(uint64_t mask, uint64_t bits) nr_bit_filters++; } @@ -52681,7 +53632,7 @@ index 0833f44..3eda8ea 100644 { int i; -@@ -577,7 +577,7 @@ uint64_t parse_flag_name(const char *str, int len) +@@ -577,7 +735,7 @@ uint64_t parse_flag_name(const char *str, int len) return parse_number(str); } @@ -52690,7 +53641,7 @@ index 0833f44..3eda8ea 100644 { const char *p = str; uint64_t flags = 0; -@@ -596,7 +596,7 @@ uint64_t parse_flag_names(const char *str, int all) +@@ -596,7 +754,7 @@ uint64_t parse_flag_names(const char *str, int all) return flags; } @@ -52699,7 +53650,7 @@ index 0833f44..3eda8ea 100644 { uint64_t mask; uint64_t bits; -@@ -621,7 +621,7 @@ void parse_bits_mask(const char *optarg) +@@ -621,7 +779,7 @@ void parse_bits_mask(const char *optarg) } @@ -52708,6 +53659,18 @@ index 0833f44..3eda8ea 100644 { "raw" , 0, NULL, 'r' }, { "pid" , 1, NULL, 'p' }, { "file" , 1, NULL, 'f' }, +@@ -676,8 +834,10 @@ int main(int argc, char *argv[]) + } + } + ++ if (opt_list && opt_pid) ++ printf("voffset\t"); + if (opt_list == 1) +- printf("offset\tcount\tflags\n"); ++ printf("offset\tlen\tflags\n"); + if (opt_list == 2) + printf("offset\tflags\n"); + diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c index df32276..92e729f 100644 --- a/Documentation/vm/slabinfo.c @@ -54208,7 +55171,7 @@ index 4f91385..feb37e1 100644 (struct ist_info) 080/010 ALL hd0_info hd0 disk parameter, OBSOLETE!! diff --git a/MAINTAINERS b/MAINTAINERS -index 8dca9d8..ea2afa5 100644 +index 8dca9d8..e50df07 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -233,6 +233,7 @@ S: Supported @@ -54430,15 +55393,15 @@ index 8dca9d8..ea2afa5 100644 M: Lennert Buytenhek -L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -+S: Maintained -+ + S: Maintained + +ARM/INTEL IXP4XX ARM ARCHITECTURE +M: Imre Kaloz +M: Krzysztof Halasa +L: linux-arm-kernel@lists.infradead.org - S: Maintained ++S: Maintained +F: arch/arm/mach-ixp4xx/ - ++ ARM/INTEL XSC3 (MANZANO) ARM CORE M: Lennert Buytenhek M: Dan Williams @@ -54665,7 +55628,21 @@ index 8dca9d8..ea2afa5 100644 W: http://www.atmel.com/products/AT91/ W: http://www.at91.com/ S: Maintained -@@ -1494,14 +1547,14 @@ F: drivers/net/cxgb3/ +@@ -1158,6 +1211,13 @@ L: netdev@vger.kernel.org + S: Supported + F: drivers/net/tg3.* + ++BROCADE BFA FC SCSI DRIVER ++P: Jing Huang ++M: huangj@brocade.com ++L: linux-scsi@vger.kernel.org ++S: Supported ++F: drivers/scsi/bfa/ ++ + BSG (block layer generic sg v4 driver) + M: FUJITA Tomonori + L: linux-scsi@vger.kernel.org +@@ -1494,14 +1554,14 @@ F: drivers/net/cxgb3/ CXGB3 IWARP RNIC DRIVER (IW_CXGB3) M: Steve Wise @@ -54682,7 +55659,7 @@ index 8dca9d8..ea2afa5 100644 W: http://www.arm.linux.org.uk/ S: Maintained F: drivers/video/cyber2000fb.* -@@ -1705,6 +1758,19 @@ S: Maintained +@@ -1705,6 +1765,19 @@ S: Maintained F: drivers/scsi/dpt* F: drivers/scsi/dpt/ @@ -54702,7 +55679,7 @@ index 8dca9d8..ea2afa5 100644 DRIVER CORE, KOBJECTS, AND SYSFS M: Greg Kroah-Hartman T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ -@@ -1868,7 +1934,7 @@ F: fs/efs/ +@@ -1868,7 +1941,7 @@ F: fs/efs/ EHCA (IBM GX bus InfiniBand adapter) DRIVER M: Hoang-Nam Nguyen M: Christoph Raisch @@ -54711,7 +55688,7 @@ index 8dca9d8..ea2afa5 100644 S: Supported F: drivers/infiniband/hw/ehca/ -@@ -1933,7 +1999,6 @@ F: fs/ext2/ +@@ -1933,7 +2006,6 @@ F: fs/ext2/ F: include/linux/ext2* EXT3 FILE SYSTEM @@ -54719,7 +55696,7 @@ index 8dca9d8..ea2afa5 100644 M: Andrew Morton M: Andreas Dilger L: linux-ext4@vger.kernel.org -@@ -2046,7 +2111,7 @@ F: drivers/i2c/busses/i2c-cpm.c +@@ -2046,7 +2118,7 @@ F: drivers/i2c/busses/i2c-cpm.c FREESCALE IMX / MXC FRAMEBUFFER DRIVER M: Sascha Hauer L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) @@ -54728,7 +55705,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: arch/arm/plat-mxc/include/mach/imxfb.h F: drivers/video/imxfb.c -@@ -2067,12 +2132,12 @@ S: Supported +@@ -2067,12 +2139,12 @@ S: Supported F: arch/powerpc/sysdev/qe_lib/ F: arch/powerpc/include/asm/*qe.h @@ -54743,7 +55720,7 @@ index 8dca9d8..ea2afa5 100644 FREESCALE QUICC ENGINE UCC ETHERNET DRIVER M: Li Yang -@@ -2118,13 +2183,16 @@ F: Documentation/filesystems/caching/ +@@ -2118,13 +2190,16 @@ F: Documentation/filesystems/caching/ F: fs/fscache/ F: include/linux/fscache*.h @@ -54762,7 +55739,7 @@ index 8dca9d8..ea2afa5 100644 F: kernel/trace/ FUJITSU FR-V (FRV) PORT -@@ -2184,6 +2252,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git +@@ -2184,6 +2259,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git S: Maintained F: include/asm-generic @@ -54776,7 +55753,7 @@ index 8dca9d8..ea2afa5 100644 GFS2 FILE SYSTEM M: Steven Whitehouse L: cluster-devel@redhat.com -@@ -2212,6 +2287,15 @@ W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ +@@ -2212,6 +2294,15 @@ W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ S: Maintained F: drivers/hwmon/hdaps.c @@ -54792,7 +55769,18 @@ index 8dca9d8..ea2afa5 100644 HYPERVISOR VIRTUAL CONSOLE DRIVER L: linuxppc-dev@ozlabs.org S: Odd Fixes -@@ -2552,7 +2636,7 @@ INFINIBAND SUBSYSTEM +@@ -2267,7 +2358,9 @@ S: Orphan + F: drivers/hwmon/ + + HARDWARE RANDOM NUMBER GENERATOR CORE +-S: Orphan ++M: Matt Mackall ++M: Herbert Xu ++S: Odd fixes + F: Documentation/hw_random.txt + F: drivers/char/hw_random/ + F: include/linux/hw_random.h +@@ -2552,7 +2645,7 @@ INFINIBAND SUBSYSTEM M: Roland Dreier M: Sean Hefty M: Hal Rosenstock @@ -54801,7 +55789,7 @@ index 8dca9d8..ea2afa5 100644 W: http://www.openib.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git S: Supported -@@ -2660,25 +2744,21 @@ F: drivers/net/ixgbe/ +@@ -2660,25 +2753,21 @@ F: drivers/net/ixgbe/ INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT M: Zhu Yi @@ -54831,7 +55819,7 @@ index 8dca9d8..ea2afa5 100644 F: Documentation/networking/README.ipw2200 F: drivers/net/wireless/ipw2x00/ipw2200.* -@@ -2695,8 +2775,8 @@ F: include/linux/wimax/i2400m.h +@@ -2695,8 +2784,8 @@ F: include/linux/wimax/i2400m.h INTEL WIRELESS WIFI LINK (iwlwifi) M: Zhu Yi M: Reinette Chatre @@ -54841,7 +55829,7 @@ index 8dca9d8..ea2afa5 100644 W: http://intellinuxwireless.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git S: Supported -@@ -2729,7 +2809,7 @@ F: drivers/net/ipg.c +@@ -2729,7 +2818,7 @@ F: drivers/net/ipg.c IPATH DRIVER M: Ralph Campbell @@ -54850,7 +55838,7 @@ index 8dca9d8..ea2afa5 100644 T: git git://git.qlogic.com/ipath-linux-2.6 S: Supported F: drivers/infiniband/hw/ipath/ -@@ -2758,6 +2838,8 @@ L: netdev@vger.kernel.org +@@ -2758,6 +2847,8 @@ L: netdev@vger.kernel.org L: lvs-devel@vger.kernel.org S: Maintained F: Documentation/networking/ipvs-sysctl.txt @@ -54859,7 +55847,7 @@ index 8dca9d8..ea2afa5 100644 F: net/netfilter/ipvs/ IPWIRELESS DRIVER -@@ -2855,8 +2937,8 @@ F: fs/jffs2/ +@@ -2855,8 +2946,8 @@ F: fs/jffs2/ F: include/linux/jffs2.h JOURNALLING LAYER FOR BLOCK DEVICES (JBD) @@ -54869,7 +55857,7 @@ index 8dca9d8..ea2afa5 100644 L: linux-ext4@vger.kernel.org S: Maintained F: fs/jbd*/ -@@ -2910,7 +2992,7 @@ F: scripts/Makefile.* +@@ -2910,7 +3001,7 @@ F: scripts/Makefile.* KERNEL JANITORS L: kernel-janitors@vger.kernel.org W: http://www.kerneljanitors.org/ @@ -54878,7 +55866,7 @@ index 8dca9d8..ea2afa5 100644 KERNEL NFSD, SUNRPC, AND LOCKD SERVERS M: "J. Bruce Fields" -@@ -2928,6 +3010,7 @@ F: include/linux/sunrpc/ +@@ -2928,6 +3019,7 @@ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) M: Avi Kivity @@ -54886,7 +55874,7 @@ index 8dca9d8..ea2afa5 100644 L: kvm@vger.kernel.org W: http://kvm.qumranet.com S: Supported -@@ -3279,8 +3362,14 @@ S: Supported +@@ -3279,8 +3371,14 @@ S: Supported F: drivers/net/mv643xx_eth.* F: include/linux/mv643xx.h @@ -54902,7 +55890,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained MARVELL YUKON / SYSKONNECT DRIVER -@@ -3397,7 +3486,7 @@ F: include/linux/meye.h +@@ -3397,7 +3495,7 @@ F: include/linux/meye.h MOTOROLA IMX MMC/SD HOST CONTROLLER INTERFACE DRIVER M: Pavel Pisa @@ -54911,7 +55899,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: drivers/mmc/host/imxmmc.* -@@ -3472,7 +3561,6 @@ F: drivers/net/natsemi.c +@@ -3472,7 +3570,6 @@ F: drivers/net/natsemi.c NCP FILESYSTEM M: Petr Vandrovec @@ -54919,7 +55907,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: fs/ncpfs/ -@@ -3485,7 +3573,7 @@ F: drivers/scsi/NCR_D700.* +@@ -3485,7 +3582,7 @@ F: drivers/scsi/NCR_D700.* NETEFFECT IWARP RNIC DRIVER (IW_NES) M: Faisal Latif M: Chien Tung @@ -54928,7 +55916,7 @@ index 8dca9d8..ea2afa5 100644 W: http://www.neteffect.com S: Supported F: drivers/infiniband/hw/nes/ -@@ -3591,9 +3679,12 @@ M: "John W. Linville" +@@ -3591,9 +3688,12 @@ M: "John W. Linville" L: linux-wireless@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained @@ -54941,7 +55929,7 @@ index 8dca9d8..ea2afa5 100644 NETWORKING DRIVERS L: netdev@vger.kernel.org -@@ -3679,7 +3770,7 @@ W: http://www.muru.com/linux/omap/ +@@ -3679,7 +3779,7 @@ W: http://www.muru.com/linux/omap/ W: http://linux.omap.com/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap-2.6.git S: Maintained @@ -54950,7 +55938,7 @@ index 8dca9d8..ea2afa5 100644 OMAP CLOCK FRAMEWORK SUPPORT M: Paul Walmsley -@@ -3711,7 +3802,13 @@ OMAP MMC SUPPORT +@@ -3711,7 +3811,13 @@ OMAP MMC SUPPORT M: Jarkko Lavinen L: linux-omap@vger.kernel.org S: Maintained @@ -54965,7 +55953,7 @@ index 8dca9d8..ea2afa5 100644 OMAP RANDOM NUMBER GENERATOR SUPPORT M: Deepak Saxena -@@ -3876,6 +3973,7 @@ F: drivers/block/paride/ +@@ -3876,6 +3982,7 @@ F: drivers/block/paride/ PARISC ARCHITECTURE M: Kyle McMartin M: Helge Deller @@ -54973,7 +55961,7 @@ index 8dca9d8..ea2afa5 100644 L: linux-parisc@vger.kernel.org W: http://www.parisc-linux.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git -@@ -3901,6 +3999,15 @@ S: Maintained +@@ -3901,6 +4008,15 @@ S: Maintained F: drivers/leds/leds-pca9532.c F: include/linux/leds-pca9532.h @@ -54989,7 +55977,7 @@ index 8dca9d8..ea2afa5 100644 PCI ERROR RECOVERY M: Linas Vepstas L: linux-pci@vger.kernel.org -@@ -3917,11 +4024,11 @@ F: Documentation/PCI/ +@@ -3917,11 +4033,11 @@ F: Documentation/PCI/ F: drivers/pci/ F: include/linux/pci* @@ -55004,7 +55992,7 @@ index 8dca9d8..ea2afa5 100644 PCMCIA SUBSYSTEM P: Linux PCMCIA Team -@@ -3945,7 +4052,7 @@ S: Maintained +@@ -3945,7 +4061,7 @@ S: Maintained F: include/linux/delayacct.h F: kernel/delayacct.c @@ -55013,7 +56001,7 @@ index 8dca9d8..ea2afa5 100644 M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar -@@ -3969,6 +4076,13 @@ S: Maintained +@@ -3969,6 +4085,13 @@ S: Maintained F: drivers/block/pktcdvd.c F: include/linux/pktcdvd.h @@ -55027,7 +56015,7 @@ index 8dca9d8..ea2afa5 100644 POSIX CLOCKS and TIMERS M: Thomas Gleixner S: Supported -@@ -4105,7 +4219,7 @@ F: drivers/media/video/pvrusb2/ +@@ -4105,7 +4228,7 @@ F: drivers/media/video/pvrusb2/ PXA2xx/PXA3xx SUPPORT M: Eric Miao M: Russell King @@ -55036,7 +56024,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: arch/arm/mach-pxa/ F: drivers/pcmcia/pxa2xx* -@@ -4118,13 +4232,13 @@ F: sound/soc/pxa +@@ -4118,13 +4241,13 @@ F: sound/soc/pxa PXA168 SUPPORT M: Eric Miao M: Jason Chagas @@ -55052,7 +56040,7 @@ index 8dca9d8..ea2afa5 100644 T: git git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6.git S: Maintained -@@ -4299,7 +4413,7 @@ L: linux-wireless@vger.kernel.org +@@ -4299,7 +4422,7 @@ L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained @@ -55061,7 +56049,7 @@ index 8dca9d8..ea2afa5 100644 RTL8187 WIRELESS DRIVER M: Herton Ronaldo Krzesinski -@@ -4365,7 +4479,7 @@ F: net/iucv/ +@@ -4365,7 +4488,7 @@ F: net/iucv/ S3C24XX SD/MMC Driver M: Ben Dooks @@ -55070,7 +56058,7 @@ index 8dca9d8..ea2afa5 100644 S: Supported F: drivers/mmc/host/s3cmci.* -@@ -4391,6 +4505,14 @@ S: Maintained +@@ -4391,6 +4514,14 @@ S: Maintained F: kernel/sched* F: include/linux/sched.h @@ -55085,7 +56073,7 @@ index 8dca9d8..ea2afa5 100644 SCSI CDROM DRIVER M: Jens Axboe L: linux-scsi@vger.kernel.org -@@ -4407,7 +4529,7 @@ F: drivers/scsi/sg.c +@@ -4407,7 +4538,7 @@ F: drivers/scsi/sg.c F: include/scsi/sg.h SCSI SUBSYSTEM @@ -55094,7 +56082,7 @@ index 8dca9d8..ea2afa5 100644 L: linux-scsi@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6.git -@@ -4462,20 +4584,20 @@ S: Maintained +@@ -4462,20 +4593,20 @@ S: Maintained F: drivers/mmc/host/sdricoh_cs.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER @@ -55121,7 +56109,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: drivers/mmc/host/sdhci-s3c.c -@@ -4517,6 +4639,14 @@ F: drivers/ata/ +@@ -4517,6 +4648,14 @@ F: drivers/ata/ F: include/linux/ata.h F: include/linux/libata.h @@ -55136,7 +56124,7 @@ index 8dca9d8..ea2afa5 100644 SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER M: Sathya Perla M: Subbu Seetharaman -@@ -4526,9 +4656,10 @@ S: Supported +@@ -4526,9 +4665,10 @@ S: Supported F: drivers/net/benet/ SFC NETWORK DRIVER @@ -55150,7 +56138,7 @@ index 8dca9d8..ea2afa5 100644 S: Supported F: drivers/net/sfc/ -@@ -4560,7 +4691,7 @@ F: drivers/misc/sgi-xp/ +@@ -4560,7 +4700,7 @@ F: drivers/misc/sgi-xp/ SHARP LH SUPPORT (LH7952X & LH7A40X) M: Marc Singer W: http://projects.buici.com/arm @@ -55159,7 +56147,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: Documentation/arm/Sharp-LH/ADC-LH7-Touchscreen F: arch/arm/mach-lh7a40x/ -@@ -4568,11 +4699,17 @@ F: drivers/serial/serial_lh7a40x.c +@@ -4568,11 +4708,16 @@ F: drivers/serial/serial_lh7a40x.c F: drivers/usb/gadget/lh7a40* F: drivers/usb/host/ohci-lh7a40* @@ -55177,11 +56165,10 @@ index 8dca9d8..ea2afa5 100644 +F: arch/x86/kernel/*sfi* +F: drivers/sfi/ +F: include/linux/sfi*.h -+ SIMTEC EB110ATX (Chalice CATS) P: Ben Dooks -@@ -4589,6 +4726,12 @@ F: arch/arm/mach-s3c2410/ +@@ -4589,6 +4734,12 @@ F: arch/arm/mach-s3c2410/ F: drivers/*/*s3c2410* F: drivers/*/*/*s3c2410* @@ -55194,7 +56181,7 @@ index 8dca9d8..ea2afa5 100644 SIS 190 ETHERNET DRIVER M: Francois Romieu L: netdev@vger.kernel.org -@@ -4640,7 +4783,7 @@ F: include/linux/sl?b*.h +@@ -4640,7 +4791,7 @@ F: include/linux/sl?b*.h F: mm/sl?b.c SMC91x ETHERNET DRIVER @@ -55203,7 +56190,7 @@ index 8dca9d8..ea2afa5 100644 S: Maintained F: drivers/net/smc91x.* -@@ -4968,6 +5111,11 @@ T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches +@@ -4968,6 +5119,11 @@ T: quilt http://svn.sourceforge.jp/svnroot/tomoyo/trunk/2.2.x/tomoyo-lsm/patches S: Maintained F: security/tomoyo/ @@ -55215,7 +56202,7 @@ index 8dca9d8..ea2afa5 100644 TOSHIBA ACPI EXTRAS DRIVER S: Orphan F: drivers/platform/x86/toshiba_acpi.c -@@ -5560,6 +5708,12 @@ L: linux-scsi@vger.kernel.org +@@ -5560,6 +5716,12 @@ L: linux-scsi@vger.kernel.org S: Maintained F: drivers/scsi/wd7000.c @@ -55228,7 +56215,7 @@ index 8dca9d8..ea2afa5 100644 WIMAX STACK M: Inaky Perez-Gonzalez M: linux-wimax@intel.com -@@ -5578,6 +5732,23 @@ M: Miloslav Trmac +@@ -5578,6 +5740,23 @@ M: Miloslav Trmac S: Maintained F: drivers/input/misc/wistron_btns.c @@ -55252,7 +56239,7 @@ index 8dca9d8..ea2afa5 100644 WL3501 WIRELESS PCMCIA CARD DRIVER M: Arnaldo Carvalho de Melo L: linux-wireless@vger.kernel.org -@@ -5595,6 +5766,26 @@ S: Supported +@@ -5595,6 +5774,26 @@ S: Supported F: drivers/input/touchscreen/*wm97* F: include/linux/wm97xx.h @@ -55279,7 +56266,7 @@ index 8dca9d8..ea2afa5 100644 X.25 NETWORK LAYER M: Henner Eisen L: linux-x25@vger.kernel.org -@@ -5627,7 +5818,7 @@ F: include/xen/ +@@ -5627,7 +5826,7 @@ F: include/xen/ XFS FILESYSTEM P: Silicon Graphics Inc @@ -55419,24 +56406,24 @@ index 60de4ef..f908acc 100644 # If asm is a stale symlink (point to dir that does not exist) remove it diff --git a/Next/SHA1s b/Next/SHA1s new file mode 100644 -index 0000000..5ebad35 +index 0000000..aa10a0e --- /dev/null +++ b/Next/SHA1s @@ -0,0 +1,141 @@ +Name SHA1 +---- ---- -+origin 0dd52d0df02733dfc2d5f3824e41b96492305384 -+fixes de55a8958f6e3ef5ce5f0971b80bd44bfcac7cf1 ++origin 94e0fb086fc5663c38bbc0fe86d698be8314f82f ++fixes 0049a32b5e685136b7f4ac928b8ae2394e67cfc9 +arm-current 9173a8ef24a6b1b8031507b35b8ffe5f85a87692 +m68k-current 9848484fad9ddeb18f18f02f9ecdcd330ac9a216 -+powerpc-merge ebc79c4f8da0f92efa968e0328f32334a2ce80cf ++powerpc-merge 09dd3fc19c09f79115267361ecd7d5c5d2c27a3a +sparc-current 0a375d75902c522ea36c6dc409296622f93db4a7 +scsi-rc-fixes 388ce4beb7135722c584b0af18f215e3ec657adf -+net-current 44c852ead55b7450c8cff0dc90a3d48310300210 ++net-current 139d6065c83071d5f66cd013a274a43699f8e2c1 +sound-current 87bfa1dbfb22aab2bb6c1085c1fe7d56cdd2f044 +pci-current ab86e5765d41a5eb4239a1c04d613db87bea5ed8 +wireless-current 11ebd1bf07fafde8d16562966c96b05b0d4ced9e -+kbuild-current 43c1266ce4dc06bfd236cec31e11e9ecd69c0bef ++kbuild-current 94e0fb086fc5663c38bbc0fe86d698be8314f82f +driver-core.current 7fa07729e439a6184bd824746d06a49cca553f15 +tty.current 7fa07729e439a6184bd824746d06a49cca553f15 +usb.current 28640c0b4caf0d045ffa1dc12e3b46bdfd2bb6e0 @@ -55452,22 +56439,22 @@ index 0000000..5ebad35 +pxa 52a7a1cec88acdaf3f8b36a6b1fe904f6eca7ee5 +thumb-2 4fb3c2e2ab3549308a1b1663296d165e45d72ba5 +avr32 2c731afd139a76d790862d33857654fea6ac2a1f -+blackfin 248be44166a5292546e6d73c675d68e3014ab572 ++blackfin 2941aeaac3600ffd6c4e4c516ca242467728c1cd +cris 24924ece4482d5466ffcd0affedce63816c88e53 +ia64 43c1266ce4dc06bfd236cec31e11e9ecd69c0bef +m68k b25ef35f34a9837e1133b3ef5fab8058155cc69f +m68knommu 04bbadcafb69511635def60844d91864515ab0d2 -+microblaze d38a6c3548845c131491f6aa36d05b6984b356a3 ++microblaze bfc8125858d777bd5bdba03a091c07cc2e0e17c0 +mips 4fa78c6123f21a399d48566c282c5eccf4296923 +parisc 1e0d061b462e48f9b1609a29aed9a5abcf65833e -+powerpc ebc79c4f8da0f92efa968e0328f32334a2ce80cf ++powerpc 94a8d5caba74211ec76dac80fc6e2d5c391530df +4xx ebc79c4f8da0f92efa968e0328f32334a2ce80cf +galak 1dcd8ffc81e80a170625883f63f6a5db3cd0428d -+s390 ed87b27e00d2ca240f62f3903583a2f1541fb9ef -+sh 064a16dc41be879d12bd5de5d2f9d38d890e0ee7 ++s390 9fd9515003b00e4049ba5cfcbf814e147692035f ++sh 40258ee97d0d5e5c30a3d4b7acaf294fe82cd23f +sparc 0cb583fd2862f19ea88b02eb307d11c09e51e2f8 +xtensa 4bcce919bd6dea26a6b9448707fba2a61d2e79a9 -+cifs 48541bd3dd4739b4d574b44ea47660c88d833677 ++cifs 086f68bd97126618ecb2dcff5f766f3a21722df7 +configfs 420118caa32c8ccdf9fce5a623b9de3f951573c5 +ecryptfs b020771b703493c12cf176bac685fb5a109a5afe +ext3 2844ce2c309ef2a28c41d1f6e2b4c50bc13e0a8f @@ -55476,7 +56463,7 @@ index 0000000..5ebad35 +fuse 79a9d99434b104c562f30f21b75317667f444793 +gfs2 754aadfea6391444edc45500c7ad088478cea252 +jfs 4a19fb11a90fdbbcb3bc02effa036230d035ca28 -+nfs a724eada8c2a7b62463b73ccf73fd0bb6e928aeb ++nfs 94e0fb086fc5663c38bbc0fe86d698be8314f82f +nfsd 3c394ddaa7ea4205f933fd9b481166b2669368a9 +nilfs2 7fa07729e439a6184bd824746d06a49cca553f15 +ocfs2 b80474b432913f73cce8db001e9fa3104f9b79ee @@ -55488,61 +56475,61 @@ index 0000000..5ebad35 +vfs aa7dfb8954ccf49e026ba13d12991a4eb7defb96 +pci 76baeebf7df493703eeb4428eac015bdb7fabda6 +hid 7fa07729e439a6184bd824746d06a49cca553f15 -+i2c 5e9f18db7d343124195c9f2c4ff394218729a78e -+jdelvare-hwmon 862f2193a1f556e2b2522d26546574c15b0ad30e -+kernel-doc 0dd52d0df02733dfc2d5f3824e41b96492305384 ++i2c 66d155e57442460811e903d93217658fde36aa3b ++jdelvare-hwmon 0dd52d0df02733dfc2d5f3824e41b96492305384 ++kernel-doc 94e0fb086fc5663c38bbc0fe86d698be8314f82f +v4l-dvb f25140438ef7ccdab2a53598ab8c974a29c35195 +quota dee865656f2d8b866f8ac22c60d6363b914e9f12 -+kbuild abe1ee3a221d53778c3e58747bbec6e518e5471b ++kbuild 94e0fb086fc5663c38bbc0fe86d698be8314f82f +kconfig 48586218b6515b9bd70694e3cd8c901a6a6ee69c +ide 7fa07729e439a6184bd824746d06a49cca553f15 +libata d15d6e6cc340566d53d953ffdec2c9e96816fa52 -+infiniband ab007313d47b73c7abe72977a65768a207cd0cdc -+acpi 193a6dec1c0246a80b6d0101e4f351ccf877bcac ++infiniband 1a616e1568d5ac080ee0b13e3135a906288dca40 ++acpi 6070710860aea169beebeaf08f1beee180bd06d5 +ieee1394 625f0850a8e27b6a8d6fdb95056f35bc22d92b55 +ubi de75c771b4cc4da963164a538a8448128301bc35 +kvm cba2be0ef98862a68fa25ed03b370829634e6b0e +dlm 1329e3f2c898cfabb6ed236d3fb8c1725197af53 -+scsi 338f43ee21f0a3a8fec25526aec21e60b7d30129 ++scsi 3fd5e3124028020e50cbdc61483cb623fb45e4c0 +async_tx 1f6672d44c1ae7408b43c06170ec34eb0a0e9b9f +net 4142e0d1def2c0176c27fd2e810243045a62eb6d +wireless b37fa870c7ccb500c7bf6aabc72cefa757da9791 -+mtd a7c367b95a9d8e65e0f0e7da31f700a556794efb ++mtd c1558b55c55620f54f0f78cb8295947a2a3f6de2 +crypto 81bd5f6c966cf2f137c2759dfc78abdffcff055e -+sound 1a6f0f946b7e0e1a9f68e961a8d23bff8d8b8912 ++sound 7a2f9e6ee8465aade70ffbf1eb21c5f53575d441 +cpufreq f0adb134d8dc9993a9998dc50845ec4f6ff4fadc +rr bb10e8363021e535836107dc6b3af9ad8479857b +mmc 7f72134c32eb64c77d1fb35123ba8bf815bf797c +input 9de48cc300fb10f7d9faa978670becf5e352462a +lsm ca05a99a54db1db5bca72eccb5866d2a86f8517f -+block f72873839e6805254acd18f9b546d1b8f0f2f21d -+device-mapper eb12874f8a3491d189bf334a947aa23b23e015dd ++block 1e6697c4add13b3818be445b8e4406947d4824cc ++device-mapper 48b17e1d9e1db0aa32cacf082460b5ae14ec8f71 +embedded 4744b43431e8613f920c5cba88346756f53c5165 +firmware 6e03a201bbe8137487f340d26aa662110e324b20 +pcmcia b1769450da0eeae2d95aae5496acbdf4c6ba89b2 +battery f056878332a91ed984a116bad4e7d49aefff9e6e -+leds f16a5dba01ed942f427f56b0d1128251721275a5 -+backlight 3b96ea9ef837c010f2187e0618d823fbdd8eeb54 ++leds ea56a4cf05ce901e9377de9a038d30a774b1cbcc ++backlight 3f4f1b3f80b4ce3124ace6bed70b53ff4738d7b8 +kgdb 98517d8f092cceea77ab93f15437c182b5615d9e +slab 11b7576bc42afa6096d966c3bc8737a5fe3c848a +uclinux 6e86841d05f371b5b9b86ce76c02aaee83352298 +md 4b3df5668c8ebaebd8d66a5a94374be3e3b2ef0c +mfd 75f2ba8f0006440e720e47ae14c917e07c452d72 +hdlc 4a6908a3a050aacc9c3a2f36b276b46c0629ad91 -+drm 5b31aee9d72f529ee6b60e8d66967f817a0e39fc ++drm f066a17d9f8d0a20d01d1aa9badce7f43c7bd6ad +voltage a724eada8c2a7b62463b73ccf73fd0bb6e928aeb -+security-testing 86d710146fb9975f04c505ec78caa43d227c1018 ++security-testing 7f366784f5c2b8fc0658b5b374f4c63ee42c789f +lblnet 86d710146fb9975f04c505ec78caa43d227c1018 +agp 121264827656f5f06328b17983c796af17dc5949 +uwb 0396c215f301e92677d1e9a064b405e31501dc1d -+watchdog 376f38198f6d611fad991b098e22e9582fc002fd ++watchdog f2cf50d6db23539838f2b55f231ee8186e77217a +bdev feaf3848a813a106f163013af6fcf6c4bfec92d9 -+dwmw2-iommu b09a75fc5e77b7c58d097236f89b1ff72dcdb562 -+cputime 27bf8712477db47c891e6198000c985631cd18de ++dwmw2-iommu 17b6097753e926ca546189463070a7e94e7ea9fa ++cputime 96830a57de1197519b62af6a4c9ceea556c18c3d +osd fb48922b3cf64d1b20d13468e4c4bb2988093e18 +jc_docs 6c19efb46aacf2c5043ad210b888ee58ffb848c0 +nommu 9a100a4464917b5ffff3a8ce1c2758088fd9bb32 -+trivial d80f6e74af2920e32cee36df91a07bb2b949cf83 ++trivial 36fd2127e6091dd6ca69845d5f29f387a9469da7 +audit def57543418a5f47debae28a0a9dea2effc11692 +omap ebc79c4f8da0f92efa968e0328f32334a2ce80cf +aoe c3643395dc3b8d47932e2bbc2992532ae88ee522 @@ -55553,7 +56540,7 @@ index 0000000..5ebad35 +hwlat a2c8b6b9bc412196e4a0bfa1c6b33840f7f0a039 +drbd 8034f62b3add784fcd657c620399010f6b7cf178 +kmemleak df58bee21ed218cb7dfb561a590b1bd2a99531cf -+tip 1a4ce84c287f7f4a7d0b411383114633529bc161 ++tip 0320071d4e5bbc5700734457152e2e510b58b77c +oprofile 8b5050255f993dda5e7b5908ab71d1cafc731bd1 +percpu 7fa07729e439a6184bd824746d06a49cca553f15 +sfi c602c65b2f81d14456771d1e3f15d1381f4b7efa @@ -55715,1188 +56702,589 @@ index 0000000..eacb7d3 +scsi-post-merge git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6.git#master diff --git a/Next/merge.log b/Next/merge.log new file mode 100644 -index 0000000..e6936a7 +index 0000000..2b5393c --- /dev/null +++ b/Next/merge.log -@@ -0,0 +1,2870 @@ +@@ -0,0 +1,2569 @@ +$ git checkout master +Already on 'master' +$ git reset --hard stable -+HEAD is now at 7fa0772 Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip ++HEAD is now at 0dd52d0 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input +Merging origin/master +$ git merge origin/master -+Updating 7fa0772..0dd52d0 ++Updating 0dd52d0..94e0fb0 +Fast forward -+ Documentation/ABI/stable/sysfs-class-backlight | 36 + -+ Documentation/ABI/testing/sysfs-class-lcd | 23 + -+ Documentation/ABI/testing/sysfs-class-led | 28 + -+ Documentation/ABI/testing/sysfs-gpio | 1 + -+ .../ABI/testing/sysfs-platform-asus-laptop | 52 + -+ .../ABI/testing/sysfs-platform-eeepc-laptop | 50 + -+ Documentation/Intel-IOMMU.txt | 6 +- -+ Documentation/accounting/getdelays.c | 12 +- -+ Documentation/auxdisplay/cfag12864b-example.c | 22 +- -+ Documentation/fb/ep93xx-fb.txt | 135 + -+ Documentation/fb/matroxfb.txt | 4 +- -+ Documentation/feature-removal-schedule.txt | 8 - -+ Documentation/filesystems/9p.txt | 40 +- -+ Documentation/filesystems/ncpfs.txt | 6 +- -+ Documentation/filesystems/proc.txt | 5 +- -+ Documentation/gpio.txt | 17 + -+ Documentation/hwmon/acpi_power_meter | 51 + -+ Documentation/hwmon/coretemp | 4 +- -+ Documentation/hwmon/fscher | 169 - -+ Documentation/i2c/busses/i2c-piix4 | 2 + -+ Documentation/i2c/chips/pca9539 | 58 - -+ Documentation/i2c/chips/pcf8574 | 65 - -+ Documentation/i2c/chips/pcf8575 | 69 - -+ Documentation/ia64/aliasing-test.c | 8 +- -+ Documentation/kbuild/kbuild.txt | 16 + -+ Documentation/kbuild/makefiles.txt | 20 +- -+ Documentation/kernel-parameters.txt | 2 +- -+ Documentation/laptops/asus-laptop.txt | 258 ++ -+ Documentation/laptops/thinkpad-acpi.txt | 8 +- -+ Documentation/leds-class.txt | 9 +- -+ Documentation/lguest/lguest.c | 26 +- -+ Documentation/pcmcia/crc32hash.c | 2 +- -+ Documentation/power/power_supply_class.txt | 7 + -+ Documentation/power/regulator/design.txt | 33 + -+ Documentation/power/regulator/machine.txt | 4 +- -+ Documentation/power/regulator/overview.txt | 4 +- -+ Documentation/power/regulator/regulator.txt | 5 +- -+ Documentation/powerpc/dts-bindings/fsl/esdhc.txt | 2 + -+ Documentation/powerpc/dts-bindings/mtd-physmap.txt | 42 +- -+ Documentation/rtc.txt | 26 + -+ Documentation/spi/spi-summary | 2 +- -+ Documentation/spi/spidev_test.c | 4 +- -+ Documentation/sysctl/kernel.txt | 8 + -+ Documentation/usb/authorization.txt | 10 +- -+ Documentation/usb/usbmon.txt | 8 +- -+ Documentation/video4linux/v4lgrab.c | 2 +- -+ Documentation/vm/page-types.c | 52 +- -+ Documentation/vm/slabinfo.c | 68 +- -+ Documentation/watchdog/src/watchdog-test.c | 2 +- -+ Documentation/x86/earlyprintk.txt | 39 +- -+ MAINTAINERS | 55 +- -+ Makefile | 62 +- -+ arch/arm/Makefile | 6 +- -+ arch/arm/boot/install.sh | 4 +- -+ arch/arm/configs/n770_defconfig | 2 +- -+ arch/arm/configs/nhk8815_defconfig | 2 +- -+ arch/arm/configs/omap3_beagle_defconfig | 47 +- -+ arch/arm/configs/omap_3430sdp_defconfig | 39 +- -+ arch/arm/configs/omap_ldp_defconfig | 54 +- -+ arch/arm/kernel/Makefile | 3 +- -+ arch/arm/kernel/init_task.c | 5 +- -+ arch/arm/mach-at91/Kconfig | 7 + -+ arch/arm/mach-at91/Makefile | 1 + -+ arch/arm/mach-at91/at91sam9260_devices.c | 96 + -+ arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c | 277 ++ -+ arch/arm/mach-at91/include/mach/board.h | 5 + -+ arch/arm/mach-ep93xx/clock.c | 88 +- -+ arch/arm/mach-ep93xx/core.c | 32 + -+ arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | 6 + -+ arch/arm/mach-ep93xx/include/mach/fb.h | 56 + -+ arch/arm/mach-ep93xx/include/mach/platform.h | 2 + -+ arch/arm/mach-ixp4xx/common.c | 16 +- -+ arch/arm/mach-ixp4xx/include/mach/system.h | 6 +- -+ arch/arm/mach-nomadik/board-nhk8815.c | 155 + -+ arch/arm/mach-nomadik/include/mach/fsmc.h | 29 + -+ arch/arm/mach-nomadik/include/mach/nand.h | 16 + -+ arch/arm/mach-omap2/board-apollon.c | 4 +- -+ arch/arm/mach-omap2/board-rx51-peripherals.c | 4 + -+ arch/arm/mach-omap2/devices.c | 71 +- -+ arch/arm/mach-omap2/gpmc.c | 63 +- -+ arch/arm/mach-omap2/mmc-twl4030.c | 78 + -+ arch/arm/mach-omap2/mmc-twl4030.h | 2 + -+ arch/arm/plat-mxc/include/mach/spi.h | 27 + -+ arch/arm/plat-omap/include/mach/gpmc.h | 4 + -+ arch/arm/plat-omap/include/mach/irqs.h | 2 + -+ arch/arm/plat-omap/include/mach/lcd_mipid.h | 5 + -+ arch/arm/plat-omap/include/mach/mmc.h | 20 +- -+ arch/arm/plat-omap/include/mach/omapfb.h | 4 +- -+ arch/avr32/kernel/init_task.c | 5 +- -+ arch/avr32/mm/init.c | 4 +- -+ arch/blackfin/Makefile | 4 +- -+ arch/blackfin/boot/install.sh | 6 +- -+ arch/blackfin/include/asm/sections.h | 38 +- -+ arch/cris/Makefile | 2 - -+ arch/cris/kernel/Makefile | 1 + -+ arch/cris/kernel/process.c | 5 +- -+ arch/frv/include/asm/gdb-stub.h | 1 - -+ arch/frv/include/asm/hardirq.h | 17 +- -+ arch/frv/kernel/debug-stub.c | 1 + -+ arch/frv/kernel/init_task.c | 5 +- -+ arch/frv/kernel/process.c | 4 - -+ arch/h8300/kernel/init_task.c | 5 +- -+ arch/ia64/Kconfig | 4 + -+ arch/ia64/hp/common/sba_iommu.c | 7 +- -+ arch/ia64/include/asm/cputime.h | 1 + -+ arch/ia64/install.sh | 4 +- -+ arch/ia64/kernel/Makefile.gate | 2 +- -+ arch/ia64/kernel/init_task.c | 3 +- -+ arch/ia64/kernel/pci-swiotlb.c | 2 +- -+ arch/ia64/mm/init.c | 5 - -+ arch/m32r/boot/compressed/install.sh | 4 +- -+ arch/m32r/kernel/init_task.c | 5 +- -+ arch/m68k/install.sh | 4 +- -+ arch/m68k/kernel/process.c | 6 +- -+ arch/m68knommu/kernel/init_task.c | 5 +- -+ arch/microblaze/kernel/init_task.c | 5 +- -+ arch/mips/Makefile | 27 +- -+ arch/mips/kernel/init_task.c | 5 +- -+ arch/mips/kernel/vmlinux.lds.S | 13 +- -+ arch/mips/mm/init.c | 7 +- -+ arch/mn10300/include/asm/gdb-stub.h | 1 - -+ arch/mn10300/kernel/asm-offsets.c | 2 +- -+ arch/mn10300/kernel/init_task.c | 5 +- -+ arch/mn10300/kernel/mn10300-serial-low.S | 2 +- -+ arch/mn10300/kernel/mn10300-serial.c | 14 +- -+ arch/mn10300/kernel/setup.c | 2 +- -+ arch/parisc/Makefile | 4 +- -+ arch/parisc/install.sh | 4 +- -+ arch/parisc/kernel/init_task.c | 4 +- -+ arch/powerpc/Makefile | 6 +- -+ arch/powerpc/boot/dts/mpc8377_mds.dts | 1 + -+ arch/powerpc/boot/dts/mpc8377_rdb.dts | 1 + -+ arch/powerpc/boot/dts/mpc8377_wlan.dts | 1 + -+ arch/powerpc/boot/dts/mpc8378_mds.dts | 1 + -+ arch/powerpc/boot/dts/mpc8378_rdb.dts | 1 + -+ arch/powerpc/boot/dts/mpc8379_mds.dts | 1 + -+ arch/powerpc/boot/dts/mpc8379_rdb.dts | 1 + -+ arch/powerpc/boot/install.sh | 4 +- -+ arch/powerpc/include/asm/cputime.h | 13 + -+ arch/powerpc/kernel/init_task.c | 5 +- -+ arch/powerpc/kernel/machine_kexec_64.c | 5 +- -+ arch/powerpc/kernel/setup-common.c | 2 +- -+ arch/powerpc/kernel/time.c | 4 + -+ arch/powerpc/kernel/vdso.c | 3 +- -+ arch/powerpc/kernel/vdso32/Makefile | 2 +- -+ arch/powerpc/kernel/vdso32/vdso32_wrapper.S | 3 +- -+ arch/powerpc/kernel/vdso64/Makefile | 2 +- -+ arch/powerpc/kernel/vdso64/vdso64_wrapper.S | 3 +- -+ arch/powerpc/mm/init_32.c | 36 - -+ arch/powerpc/mm/init_64.c | 29 - -+ arch/powerpc/mm/mem.c | 6 +- -+ arch/powerpc/platforms/pseries/hvCall_inst.c | 2 +- -+ arch/s390/boot/install.sh | 4 +- -+ arch/s390/defconfig | 37 +- -+ arch/s390/include/asm/cputime.h | 1 + -+ arch/s390/include/asm/lowcore.h | 9 + -+ arch/s390/include/asm/processor.h | 2 +- -+ arch/s390/kernel/asm-offsets.c | 7 +- -+ arch/s390/kernel/compat_linux.c | 83 +- -+ arch/s390/kernel/compat_linux.h | 4 +- -+ arch/s390/kernel/compat_wrapper.S | 27 +- -+ arch/s390/kernel/entry.h | 6 +- -+ arch/s390/kernel/init_task.c | 5 +- -+ arch/s390/kernel/process.c | 40 +- -+ arch/s390/kernel/ptrace.c | 19 +- -+ arch/s390/kernel/sclp.S | 5 +- -+ arch/s390/kernel/smp.c | 50 +- -+ arch/s390/kernel/suspend.c | 24 +- -+ arch/s390/kernel/swsusp_asm64.S | 102 +- -+ arch/s390/kernel/syscalls.S | 8 +- -+ arch/s390/kernel/vdso.c | 2 +- -+ arch/s390/kernel/vdso32/Makefile | 2 +- -+ arch/s390/kernel/vdso32/vdso32_wrapper.S | 3 +- -+ arch/s390/kernel/vdso64/Makefile | 2 +- -+ arch/s390/kernel/vdso64/vdso64_wrapper.S | 3 +- -+ arch/s390/mm/page-states.c | 52 +- -+ arch/s390/mm/pgtable.c | 17 +- -+ arch/score/include/asm/page.h | 3 +- -+ arch/score/include/asm/thread_info.h | 15 +- -+ arch/score/kernel/init_task.c | 5 +- -+ arch/score/kernel/vmlinux.lds.S | 77 +- -+ arch/sh/boot/compressed/install.sh | 4 +- -+ arch/sh/kernel/init_task.c | 5 +- -+ arch/sh/kernel/irq.c | 6 +- -+ arch/sh/kernel/vsyscall/Makefile | 2 +- -+ arch/sh/mm/init.c | 6 - -+ arch/sparc/Makefile | 4 - -+ arch/sparc/include/asm/vio.h | 2 +- -+ arch/sparc/kernel/Makefile | 6 +- -+ arch/sparc/kernel/init_task.c | 5 +- -+ arch/um/Makefile | 9 +- -+ arch/um/kernel/Makefile | 3 + -+ arch/um/kernel/init_task.c | 5 +- -+ arch/um/kernel/vmlinux.lds.S | 3 + -+ arch/x86/Kconfig | 10 +- -+ arch/x86/Makefile | 4 +- -+ arch/x86/boot/install.sh | 4 +- -+ arch/x86/include/asm/acpi.h | 1 - -+ arch/x86/include/asm/cache.h | 4 +- -+ arch/x86/include/asm/syscall.h | 14 +- -+ arch/x86/kernel/Makefile | 1 + -+ arch/x86/kernel/early_printk.c | 780 +---- -+ arch/x86/kernel/entry_64.S | 22 +- -+ arch/x86/kernel/head_32.S | 4 +- -+ arch/x86/kernel/head_64.S | 2 +- -+ arch/x86/kernel/init_task.c | 5 +- -+ arch/x86/kernel/pci-swiotlb.c | 5 +- -+ arch/x86/kernel/ptrace.c | 21 +- -+ arch/x86/kernel/setup.c | 3 + -+ arch/x86/kernel/sfi.c | 122 + -+ arch/x86/lguest/boot.c | 10 +- -+ arch/x86/mm/init_32.c | 6 - -+ arch/x86/mm/init_64.c | 10 +- -+ arch/x86/pci/mmconfig-shared.c | 8 +- -+ arch/x86/pci/mmconfig_32.c | 2 +- -+ arch/x86/vdso/Makefile | 2 +- -+ arch/xtensa/kernel/Makefile | 3 +- -+ arch/xtensa/kernel/head.S | 2 +- -+ arch/xtensa/kernel/init_task.c | 5 +- -+ drivers/Makefile | 5 +- -+ drivers/acpi/Kconfig | 17 +- -+ drivers/acpi/Makefile | 1 + -+ drivers/acpi/ac.c | 2 + -+ drivers/acpi/acpi_memhotplug.c | 51 +- -+ drivers/acpi/acpica/Makefile | 4 +- -+ drivers/acpi/acpica/acconfig.h | 10 +- -+ drivers/acpi/acpica/acdebug.h | 4 - -+ drivers/acpi/acpica/acglobal.h | 37 +- -+ drivers/acpi/acpica/achware.h | 8 + -+ drivers/acpi/acpica/acinterp.h | 4 +- -+ drivers/acpi/acpica/aclocal.h | 16 + -+ drivers/acpi/acpica/acmacros.h | 2 + -+ drivers/acpi/acpica/acnamesp.h | 25 + -+ drivers/acpi/acpica/acobject.h | 1 + -+ drivers/acpi/acpica/acparser.h | 2 + -+ drivers/acpi/acpica/acpredef.h | 584 ++- -+ drivers/acpi/acpica/acutils.h | 30 +- -+ drivers/acpi/acpica/amlcode.h | 1 + -+ drivers/acpi/acpica/dsfield.c | 18 +- -+ drivers/acpi/acpica/dsmethod.c | 15 +- -+ drivers/acpi/acpica/dsmthdat.c | 8 +- -+ drivers/acpi/acpica/dsobject.c | 23 +- -+ drivers/acpi/acpica/dswload.c | 41 +- -+ drivers/acpi/acpica/evgpe.c | 8 +- -+ drivers/acpi/acpica/evgpeblk.c | 4 +- -+ drivers/acpi/acpica/evrgnini.c | 45 +- -+ drivers/acpi/acpica/exconfig.c | 7 + -+ drivers/acpi/acpica/exdump.c | 6 +- -+ drivers/acpi/acpica/exfield.c | 82 +- -+ drivers/acpi/acpica/exfldio.c | 7 +- -+ drivers/acpi/acpica/exutils.c | 53 +- -+ drivers/acpi/acpica/hwgpe.c | 34 +- -+ drivers/acpi/acpica/hwregs.c | 206 +- -+ drivers/acpi/acpica/hwtimer.c | 2 +- -+ drivers/acpi/acpica/hwxface.c | 195 +- -+ drivers/acpi/acpica/nsalloc.c | 88 +- -+ drivers/acpi/acpica/nsdumpdv.c | 7 +- -+ drivers/acpi/acpica/nseval.c | 137 + -+ drivers/acpi/acpica/nsinit.c | 15 + -+ drivers/acpi/acpica/nsload.c | 3 +- -+ drivers/acpi/acpica/nspredef.c | 718 ++-- -+ drivers/acpi/acpica/nsrepair.c | 203 + -+ drivers/acpi/acpica/nsutils.c | 5 +- -+ drivers/acpi/acpica/nsxfeval.c | 23 +- -+ drivers/acpi/acpica/nsxfname.c | 237 +- -+ drivers/acpi/acpica/psloop.c | 119 +- -+ drivers/acpi/acpica/psxface.c | 4 + -+ drivers/acpi/acpica/tbutils.c | 82 +- -+ drivers/acpi/acpica/utdelete.c | 6 + -+ drivers/acpi/acpica/uteval.c | 378 +-- -+ drivers/acpi/acpica/utglobal.c | 12 +- -+ drivers/acpi/acpica/utids.c | 382 ++ -+ drivers/acpi/acpica/utinit.c | 22 +- -+ drivers/acpi/acpica/utmisc.c | 85 +- -+ drivers/acpi/acpica/utxface.c | 26 +- -+ drivers/acpi/battery.c | 22 + -+ drivers/acpi/blacklist.c | 2 + -+ drivers/acpi/bus.c | 3 +- -+ drivers/acpi/button.c | 2 + -+ drivers/acpi/cm_sbs.c | 2 + -+ drivers/acpi/container.c | 13 +- -+ drivers/acpi/debug.c | 82 +- -+ drivers/acpi/dock.c | 10 +- -+ drivers/acpi/ec.c | 270 +- -+ drivers/acpi/event.c | 2 + -+ drivers/acpi/fan.c | 2 + -+ drivers/acpi/glue.c | 10 +- -+ drivers/acpi/internal.h | 22 +- -+ drivers/acpi/numa.c | 2 + -+ drivers/acpi/osl.c | 126 +- -+ drivers/acpi/pci_irq.c | 2 + -+ drivers/acpi/pci_link.c | 2 + -+ drivers/acpi/pci_root.c | 2 + -+ drivers/acpi/pci_slot.c | 5 +- -+ drivers/acpi/power.c | 3 +- -+ drivers/acpi/power_meter.c | 1018 +++++ -+ drivers/acpi/processor_core.c | 246 +- -+ drivers/acpi/processor_idle.c | 12 +- -+ drivers/acpi/processor_perflib.c | 2 + -+ drivers/acpi/processor_thermal.c | 5 +- -+ drivers/acpi/processor_throttling.c | 5 +- -+ drivers/acpi/sbs.c | 2 + -+ drivers/acpi/sbshc.c | 2 + -+ drivers/acpi/scan.c | 183 +- -+ drivers/acpi/sleep.c | 8 + -+ drivers/acpi/system.c | 2 + -+ drivers/acpi/tables.c | 6 + -+ drivers/acpi/thermal.c | 2 + -+ drivers/acpi/utils.c | 2 + -+ drivers/acpi/video.c | 80 +- -+ drivers/acpi/video_detect.c | 2 + -+ drivers/block/DAC960.c | 2 +- -+ drivers/block/cciss.c | 2 +- -+ drivers/block/virtio_blk.c | 33 +- -+ drivers/char/agp/hp-agp.c | 9 +- -+ drivers/char/hw_random/virtio-rng.c | 3 +- -+ drivers/char/misc.c | 2 +- -+ drivers/char/tpm/tpm.c | 7 +- -+ drivers/char/tpm/tpm_bios.c | 4 +- -+ drivers/char/virtio_console.c | 5 +- -+ drivers/connector/cn_proc.c | 25 + -+ drivers/firewire/core-card.c | 13 +- -+ drivers/firewire/core-transaction.c | 2 +- -+ drivers/firewire/core.h | 14 + -+ drivers/firewire/ohci.c | 4 +- -+ drivers/firewire/sbp2.c | 16 +- -+ drivers/gpio/Kconfig | 35 + -+ drivers/gpio/Makefile | 4 + -+ drivers/gpio/adp5520-gpio.c | 206 + -+ drivers/gpio/bt8xxgpio.c | 3 +- -+ drivers/gpio/gpiolib.c | 253 ++- -+ drivers/gpio/langwell_gpio.c | 297 ++ -+ drivers/gpio/max7301.c | 1 + -+ drivers/gpio/mc33880.c | 196 + -+ drivers/gpio/mcp23s08.c | 5 +- -+ drivers/gpio/pca953x.c | 4 +- -+ drivers/gpio/pcf857x.c | 4 +- -+ drivers/gpio/ucb1400_gpio.c | 125 + -+ drivers/gpu/drm/radeon/r600_blit.c | 2 +- -+ drivers/gpu/drm/radeon/r600_blit_kms.c | 2 +- -+ drivers/gpu/drm/radeon/radeon.h | 59 +- -+ drivers/gpu/drm/radeon/radeon_drv.h | 65 +- -+ drivers/gpu/drm/radeon/radeon_family.h | 97 + -+ drivers/hwmon/Kconfig | 34 +- -+ drivers/hwmon/Makefile | 2 - -+ drivers/hwmon/adcxx.c | 101 +- -+ drivers/hwmon/adm1031.c | 40 + -+ drivers/hwmon/coretemp.c | 57 +- -+ drivers/hwmon/dme1737.c | 2 +- -+ drivers/hwmon/fscher.c | 680 --- -+ drivers/hwmon/fscpos.c | 654 --- -+ drivers/hwmon/lis3lv02d_spi.c | 2 +- -+ drivers/hwmon/lm70.c | 55 +- -+ drivers/hwmon/ltc4215.c | 2 +- -+ drivers/hwmon/ltc4245.c | 3 +- -+ drivers/hwmon/max1111.c | 1 + -+ drivers/i2c/Kconfig | 8 + -+ drivers/i2c/busses/Kconfig | 19 +- -+ drivers/i2c/busses/Makefile | 3 + -+ drivers/i2c/busses/i2c-piix4.c | 9 +- -+ drivers/i2c/busses/i2c-pnx.c | 7 +- -+ drivers/i2c/busses/i2c-scmi.c | 430 ++ -+ drivers/i2c/busses/i2c-taos-evm.c | 45 +- -+ drivers/i2c/busses/scx200_acb.c | 6 +- -+ drivers/i2c/chips/Kconfig | 48 - -+ drivers/i2c/chips/Makefile | 3 - -+ drivers/i2c/chips/pca9539.c | 152 - -+ drivers/i2c/chips/pcf8574.c | 215 - -+ drivers/i2c/chips/pcf8575.c | 198 - -+ drivers/i2c/chips/tsl2550.c | 42 +- -+ drivers/i2c/i2c-core.c | 165 +- -+ drivers/ide/ide-acpi.c | 5 +- -+ drivers/ieee1394/raw1394.c | 4 +- -+ drivers/ieee1394/sbp2.c | 3 +- -+ drivers/infiniband/hw/ehca/ehca_mrmw.c | 2 +- -+ drivers/input/input.c | 64 +- -+ drivers/input/keyboard/Kconfig | 40 + -+ drivers/input/keyboard/Makefile | 4 + -+ drivers/input/keyboard/adp5588-keys.c | 361 ++ -+ drivers/input/keyboard/atkbd.c | 25 - -+ drivers/input/keyboard/max7359_keypad.c | 330 ++ -+ drivers/input/keyboard/opencores-kbd.c | 180 + -+ drivers/input/keyboard/qt2160.c | 397 ++ -+ drivers/input/misc/dm355evm_keys.c | 26 +- -+ drivers/input/mouse/sentelic.c | 18 +- -+ drivers/input/mouse/synaptics_i2c.c | 51 +- -+ drivers/input/serio/i8042.c | 41 + -+ drivers/input/serio/libps2.c | 28 +- -+ drivers/input/touchscreen/Kconfig | 17 +- -+ drivers/input/touchscreen/Makefile | 1 + -+ drivers/input/touchscreen/ad7877.c | 1 + -+ drivers/input/touchscreen/ad7879.c | 7 +- -+ drivers/input/touchscreen/ads7846.c | 1 + -+ drivers/input/touchscreen/mcs5000_ts.c | 318 ++ -+ drivers/input/touchscreen/wm97xx-core.c | 3 + -+ drivers/isdn/capi/kcapi_proc.c | 10 +- -+ drivers/leds/leds-clevo-mail.c | 8 + -+ drivers/leds/leds-dac124s085.c | 1 + -+ drivers/lguest/core.c | 5 +- -+ drivers/lguest/page_tables.c | 45 +- -+ drivers/mfd/ezx-pcap.c | 1 + -+ drivers/mfd/ucb1400_core.c | 31 +- -+ drivers/misc/eeprom/at25.c | 2 +- -+ drivers/misc/lkdtm.c | 2 +- -+ drivers/mmc/core/core.c | 318 ++- -+ drivers/mmc/core/core.h | 8 +- -+ drivers/mmc/core/host.c | 1 + -+ drivers/mmc/core/host.h | 2 + -+ drivers/mmc/core/mmc.c | 149 +- -+ drivers/mmc/core/mmc_ops.c | 59 + -+ drivers/mmc/core/mmc_ops.h | 1 + -+ drivers/mmc/core/sd.c | 75 +- -+ drivers/mmc/core/sdio.c | 316 +- -+ drivers/mmc/core/sdio_bus.c | 3 - -+ drivers/mmc/core/sdio_cis.c | 2 +- -+ drivers/mmc/core/sdio_io.c | 2 +- -+ drivers/mmc/host/Kconfig | 29 +- -+ drivers/mmc/host/Makefile | 1 + -+ drivers/mmc/host/atmel-mci.c | 33 +- -+ drivers/mmc/host/mmc_spi.c | 1 + -+ drivers/mmc/host/msm_sdcc.c | 1287 ++++++ -+ drivers/mmc/host/msm_sdcc.h | 238 ++ -+ drivers/mmc/host/omap_hsmmc.c | 1083 ++++- -+ drivers/mmc/host/sdhci-of.c | 49 +- -+ drivers/mmc/host/sdhci-pci.c | 5 +- -+ drivers/mmc/host/sdhci.c | 54 +- -+ drivers/mmc/host/sdhci.h | 6 +- -+ drivers/mtd/Kconfig | 16 +- -+ drivers/mtd/afs.c | 2 +- -+ drivers/mtd/chips/cfi_cmdset_0002.c | 11 - -+ drivers/mtd/chips/cfi_util.c | 4 + -+ drivers/mtd/chips/jedec_probe.c | 41 +- -+ drivers/mtd/devices/Kconfig | 10 + -+ drivers/mtd/devices/Makefile | 1 + -+ drivers/mtd/devices/lart.c | 6 +- -+ drivers/mtd/devices/m25p80.c | 137 +- -+ drivers/mtd/devices/mtd_dataflash.c | 5 +- -+ drivers/mtd/devices/phram.c | 25 +- -+ drivers/mtd/devices/slram.c | 2 +- -+ drivers/mtd/devices/sst25l.c | 512 +++ -+ drivers/mtd/inftlcore.c | 2 +- -+ drivers/mtd/maps/Kconfig | 12 +- -+ drivers/mtd/maps/Makefile | 3 +- -+ drivers/mtd/maps/gpio-addr-flash.c | 311 ++ -+ drivers/mtd/maps/physmap_of.c | 24 +- -+ drivers/mtd/maps/plat-ram.c | 2 +- -+ drivers/mtd/maps/pmcmsp-flash.c | 76 +- -+ drivers/mtd/maps/uclinux.c | 8 + -+ drivers/mtd/mtdblock.c | 2 +- -+ drivers/mtd/mtdconcat.c | 6 +- -+ drivers/mtd/mtdcore.c | 4 +- -+ drivers/mtd/mtdpart.c | 3 +- -+ drivers/mtd/nand/Kconfig | 30 + -+ drivers/mtd/nand/Makefile | 2 + -+ drivers/mtd/nand/atmel_nand.c | 2 +- -+ drivers/mtd/nand/cafe_nand.c | 2 +- -+ drivers/mtd/nand/davinci_nand.c | 45 +- -+ drivers/mtd/nand/fsl_elbc_nand.c | 3 +- -+ drivers/mtd/nand/mxc_nand.c | 16 +- -+ drivers/mtd/nand/nand_base.c | 167 +- -+ drivers/mtd/nand/nand_ecc.c | 31 +- -+ drivers/mtd/nand/ndfc.c | 4 +- -+ drivers/mtd/nand/nomadik_nand.c | 250 ++ -+ drivers/mtd/nand/omap2.c | 347 ++- -+ drivers/mtd/nand/orion_nand.c | 3 +- -+ drivers/mtd/nand/pxa3xx_nand.c | 17 +- -+ drivers/mtd/nand/sh_flctl.c | 5 +- -+ drivers/mtd/nand/tmio_nand.c | 17 +- -+ drivers/mtd/nand/txx9ndfmc.c | 52 +- -+ drivers/mtd/nand/w90p910_nand.c | 382 ++ -+ drivers/mtd/ofpart.c | 21 +- -+ drivers/mtd/onenand/Kconfig | 3 +- -+ drivers/mtd/onenand/generic.c | 24 +- -+ drivers/mtd/onenand/onenand_base.c | 20 +- -+ drivers/mtd/tests/mtd_oobtest.c | 2 +- -+ drivers/mtd/tests/mtd_pagetest.c | 12 +- -+ drivers/net/ehea/ehea_qmr.c | 2 +- -+ drivers/net/enc28j60.c | 1 + -+ drivers/net/ks8851.c | 1 + -+ drivers/net/niu.c | 2 +- -+ drivers/net/usb/cdc_eem.c | 17 +- -+ drivers/net/virtio_net.c | 15 +- -+ drivers/net/wireless/libertas/if_spi.c | 1 + -+ drivers/net/wireless/p54/p54spi.c | 1 + -+ drivers/net/wireless/wl12xx/wl1251_main.c | 1 + -+ drivers/of/base.c | 1 - -+ drivers/pci/dmar.c | 41 +- -+ drivers/pci/hotplug/acpiphp_ibm.c | 12 +- -+ drivers/pci/intel-iommu.c | 323 +- -+ drivers/pci/intr_remapping.c | 8 + -+ drivers/pci/iova.c | 16 +- -+ drivers/platform/x86/Kconfig | 10 + -+ drivers/platform/x86/Makefile | 1 + -+ drivers/platform/x86/acer-wmi.c | 2 + -+ drivers/platform/x86/acerhdf.c | 121 +- -+ drivers/platform/x86/asus-laptop.c | 227 +- -+ drivers/platform/x86/eeepc-laptop.c | 340 +- -+ drivers/platform/x86/fujitsu-laptop.c | 109 +- -+ drivers/platform/x86/hp-wmi.c | 2 +- -+ drivers/platform/x86/sony-laptop.c | 7 +- -+ drivers/platform/x86/thinkpad_acpi.c | 382 ++- -+ drivers/platform/x86/topstar-laptop.c | 265 ++ -+ drivers/platform/x86/wmi.c | 1 - -+ drivers/pnp/pnpacpi/core.c | 6 +- -+ drivers/power/Kconfig | 7 + -+ drivers/power/Makefile | 1 + -+ drivers/power/ds2760_battery.c | 147 +- -+ drivers/power/olpc_battery.c | 50 + -+ drivers/power/power_supply_core.c | 44 +- -+ drivers/power/power_supply_sysfs.c | 12 + -+ drivers/power/wm831x_power.c | 779 ++++ -+ drivers/power/wm8350_power.c | 22 + -+ drivers/power/wm97xx_battery.c | 79 +- -+ drivers/regulator/Kconfig | 24 +- -+ drivers/regulator/Makefile | 3 + -+ drivers/regulator/core.c | 285 +- -+ drivers/regulator/da903x.c | 77 +- -+ drivers/regulator/fixed.c | 91 +- -+ drivers/regulator/lp3971.c | 2 +- -+ drivers/regulator/pcf50633-regulator.c | 98 +- -+ drivers/regulator/tps65023-regulator.c | 632 +++ -+ drivers/regulator/tps6507x-regulator.c | 714 ++++ -+ drivers/regulator/userspace-consumer.c | 45 +- -+ drivers/regulator/virtual.c | 56 +- -+ drivers/regulator/wm8350-regulator.c | 2 + -+ drivers/rtc/Kconfig | 49 + -+ drivers/rtc/Makefile | 17 +- -+ drivers/rtc/rtc-at91rm9200.c | 24 +- -+ drivers/rtc/rtc-bfin.c | 2 +- -+ drivers/rtc/rtc-coh901331.c | 311 ++ -+ drivers/rtc/rtc-ds1305.c | 1 + -+ drivers/rtc/rtc-ds1307.c | 3 +- -+ drivers/rtc/rtc-ds1390.c | 1 + -+ drivers/rtc/rtc-ds3234.c | 1 + -+ drivers/rtc/rtc-ep93xx.c | 14 +- -+ drivers/rtc/rtc-m41t94.c | 1 + -+ drivers/rtc/rtc-max6902.c | 1 + -+ drivers/rtc/rtc-mxc.c | 507 +++ -+ drivers/rtc/rtc-pcap.c | 224 + -+ drivers/rtc/rtc-pcf2123.c | 364 ++ -+ drivers/rtc/rtc-r9701.c | 1 + -+ drivers/rtc/rtc-rs5c348.c | 1 + -+ drivers/rtc/rtc-stmp3xxx.c | 304 ++ -+ drivers/rtc/rtc-sysfs.c | 14 + -+ drivers/s390/block/dasd_eckd.c | 13 +- -+ drivers/s390/cio/css.c | 252 +- -+ drivers/s390/cio/css.h | 3 + -+ drivers/s390/cio/device.c | 38 +- -+ drivers/s390/cio/device.h | 1 + -+ drivers/s390/cio/idset.c | 22 +- -+ drivers/s390/cio/idset.h | 2 + -+ drivers/s390/cio/qdio_main.c | 32 +- -+ drivers/s390/crypto/ap_bus.c | 40 +- -+ drivers/scsi/sg.c | 6 +- -+ drivers/serial/max3100.c | 1 + -+ drivers/serial/serial_core.c | 4 +- -+ drivers/sfi/Kconfig | 17 + -+ drivers/sfi/Makefile | 3 + -+ drivers/sfi/sfi_acpi.c | 175 + -+ drivers/sfi/sfi_core.c | 407 ++ -+ drivers/sfi/sfi_core.h | 70 + -+ drivers/spi/Kconfig | 23 +- -+ drivers/spi/Makefile | 4 +- -+ drivers/spi/mxc_spi.c | 685 ++++ -+ drivers/spi/omap2_mcspi.c | 210 +- -+ drivers/spi/pxa2xx_spi.c | 2 +- -+ drivers/spi/spi.c | 85 +- -+ drivers/spi/spi_imx.c | 1770 -------- -+ drivers/spi/spi_ppc4xx.c | 612 +++ -+ drivers/spi/spi_s3c24xx.c | 157 +- -+ drivers/spi/spi_stmp.c | 679 +++ -+ drivers/spi/spidev.c | 1 + -+ drivers/spi/tle62x0.c | 1 + -+ drivers/staging/stlc45xx/stlc45xx.c | 1 + -+ drivers/thermal/Kconfig | 1 + -+ drivers/usb/Kconfig | 3 + -+ drivers/usb/Makefile | 2 + -+ drivers/usb/class/cdc-acm.c | 2 + -+ drivers/usb/class/cdc-wdm.c | 30 +- -+ drivers/usb/class/usbtmc.c | 84 +- -+ drivers/usb/core/config.c | 2 +- -+ drivers/usb/core/devio.c | 247 +- -+ drivers/usb/core/driver.c | 75 +- -+ drivers/usb/core/generic.c | 4 +- -+ drivers/usb/core/hcd.c | 113 +- -+ drivers/usb/core/hcd.h | 5 + -+ drivers/usb/core/hub.c | 126 +- -+ drivers/usb/core/message.c | 32 +- -+ drivers/usb/core/usb.c | 13 +- -+ drivers/usb/core/usb.h | 7 + -+ drivers/usb/early/Makefile | 5 + -+ drivers/usb/early/ehci-dbgp.c | 996 +++++ -+ drivers/usb/gadget/Kconfig | 31 +- -+ drivers/usb/gadget/amd5536udc.c | 56 +- -+ drivers/usb/gadget/at91_udc.c | 1 - -+ drivers/usb/gadget/audio.c | 24 +- -+ drivers/usb/gadget/composite.c | 2 +- -+ drivers/usb/gadget/dummy_hcd.c | 5 - -+ drivers/usb/gadget/ether.c | 31 +- -+ drivers/usb/gadget/f_audio.c | 97 +- -+ drivers/usb/gadget/f_eem.c | 562 +++ -+ drivers/usb/gadget/f_rndis.c | 15 +- -+ drivers/usb/gadget/fsl_qe_udc.c | 4 + -+ drivers/usb/gadget/gmidi.c | 8 +- -+ drivers/usb/gadget/pxa25x_udc.c | 49 +- -+ drivers/usb/gadget/pxa25x_udc.h | 1 + -+ drivers/usb/gadget/rndis.c | 13 +- -+ drivers/usb/gadget/rndis.h | 3 +- -+ drivers/usb/gadget/s3c-hsotg.c | 6 +- -+ drivers/usb/gadget/s3c2410_udc.c | 3 +- -+ drivers/usb/gadget/u_audio.c | 10 +- -+ drivers/usb/gadget/u_ether.c | 85 +- -+ drivers/usb/gadget/u_ether.h | 12 +- -+ drivers/usb/gadget/u_serial.c | 1 - -+ drivers/usb/host/Kconfig | 18 + -+ drivers/usb/host/Makefile | 1 + -+ drivers/usb/host/ehci-atmel.c | 230 ++ -+ drivers/usb/host/ehci-au1xxx.c | 29 +- -+ drivers/usb/host/ehci-dbg.c | 46 +- -+ drivers/usb/host/ehci-hcd.c | 89 +- -+ drivers/usb/host/ehci-hub.c | 84 +- -+ drivers/usb/host/ehci-mem.c | 26 +- -+ drivers/usb/host/ehci-pci.c | 42 +- -+ drivers/usb/host/ehci-q.c | 95 +- -+ drivers/usb/host/ehci-sched.c | 100 +- -+ drivers/usb/host/ehci-w90x900.c | 181 + -+ drivers/usb/host/ehci.h | 14 +- -+ drivers/usb/host/isp1362-hcd.c | 2909 +++++++++++++ -+ drivers/usb/host/isp1362.h | 1079 +++++ -+ drivers/usb/host/isp1760-hcd.c | 4 + -+ drivers/usb/host/isp1760-hcd.h | 2 + -+ drivers/usb/host/isp1760-if.c | 21 +- -+ drivers/usb/host/ohci-at91.c | 2 +- -+ drivers/usb/host/ohci-au1xxx.c | 27 +- -+ drivers/usb/host/ohci-ep93xx.c | 1 - -+ drivers/usb/host/ohci-hcd.c | 1 - -+ drivers/usb/host/ohci-pxa27x.c | 4 + -+ drivers/usb/host/oxu210hp-hcd.c | 1 - -+ drivers/usb/host/pci-quirks.c | 2 +- -+ drivers/usb/host/sl811-hcd.c | 8 +- -+ drivers/usb/host/uhci-q.c | 1 - -+ drivers/usb/host/whci/asl.c | 12 +- -+ drivers/usb/host/whci/hcd.c | 8 +- -+ drivers/usb/host/whci/pzl.c | 12 +- -+ drivers/usb/host/whci/qset.c | 4 +- -+ drivers/usb/host/whci/whci-hc.h | 1 + -+ drivers/usb/host/xhci-dbg.c | 5 +- -+ drivers/usb/host/xhci-hcd.c | 530 ++- -+ drivers/usb/host/xhci-mem.c | 140 +- -+ drivers/usb/host/xhci-pci.c | 16 + -+ drivers/usb/host/xhci-ring.c | 377 ++- -+ drivers/usb/host/xhci.h | 111 +- -+ drivers/usb/image/microtek.c | 37 - -+ drivers/usb/misc/idmouse.c | 21 + -+ drivers/usb/misc/ldusb.c | 6 + -+ drivers/usb/misc/legousbtower.c | 6 + -+ drivers/usb/misc/sisusbvga/sisusb.c | 53 +- -+ drivers/usb/misc/sisusbvga/sisusb.h | 2 - -+ drivers/usb/misc/usbsevseg.c | 69 +- -+ drivers/usb/mon/Kconfig | 4 +- -+ drivers/usb/mon/Makefile | 2 +- -+ drivers/usb/mon/mon_bin.c | 12 +- -+ drivers/usb/mon/mon_dma.c | 95 - -+ drivers/usb/mon/mon_main.c | 1 - -+ drivers/usb/mon/mon_text.c | 14 - -+ drivers/usb/mon/usb_mon.h | 14 - -+ drivers/usb/musb/musb_core.c | 8 +- -+ drivers/usb/otg/isp1301_omap.c | 23 +- -+ drivers/usb/serial/ark3116.c | 24 +- -+ drivers/usb/serial/ch341.c | 52 + -+ drivers/usb/serial/ftdi_sio.c | 7 + -+ drivers/usb/serial/ftdi_sio.h | 10 + -+ drivers/usb/serial/generic.c | 206 +- -+ drivers/usb/serial/iuu_phoenix.c | 115 +- -+ drivers/usb/serial/moto_modem.c | 2 +- -+ drivers/usb/serial/option.c | 138 +- -+ drivers/usb/serial/pl2303.c | 71 +- -+ drivers/usb/serial/pl2303.h | 4 + -+ drivers/usb/serial/sierra.c | 157 +- -+ drivers/usb/serial/usb-serial.c | 23 +- -+ drivers/usb/storage/datafab.c | 4 +- -+ drivers/usb/storage/initializers.c | 2 +- -+ drivers/usb/storage/jumpshot.c | 2 +- -+ drivers/usb/storage/onetouch.c | 2 +- -+ drivers/usb/storage/unusual_devs.h | 22 +- -+ drivers/usb/usb-skeleton.c | 252 +- -+ drivers/video/Kconfig | 50 +- -+ drivers/video/Makefile | 3 + -+ drivers/video/aty/atyfb_base.c | 829 +++-- -+ drivers/video/au1100fb.c | 7 +- -+ drivers/video/backlight/corgi_lcd.c | 1 + -+ drivers/video/backlight/ltv350qv.c | 1 + -+ drivers/video/backlight/tdo24m.c | 1 + -+ drivers/video/backlight/tosa_lcd.c | 2 +- -+ drivers/video/backlight/vgg2432a4.c | 3 +- -+ drivers/video/console/bitblit.c | 8 +- -+ drivers/video/console/fbcon.c | 58 +- -+ drivers/video/console/newport_con.c | 2 +- -+ drivers/video/console/vgacon.c | 8 +- -+ drivers/video/da8xx-fb.c | 890 ++++ -+ drivers/video/ep93xx-fb.c | 646 +++ -+ drivers/video/fbmem.c | 19 +- -+ drivers/video/matrox/g450_pll.c | 209 +- -+ drivers/video/matrox/g450_pll.h | 8 +- -+ drivers/video/matrox/i2c-matroxfb.c | 18 +- -+ drivers/video/matrox/matroxfb_DAC1064.c | 614 ++-- -+ drivers/video/matrox/matroxfb_DAC1064.h | 4 +- -+ drivers/video/matrox/matroxfb_Ti3026.c | 258 +- -+ drivers/video/matrox/matroxfb_accel.c | 129 +- -+ drivers/video/matrox/matroxfb_accel.h | 2 +- -+ drivers/video/matrox/matroxfb_base.c | 772 ++-- -+ drivers/video/matrox/matroxfb_base.h | 80 +- -+ drivers/video/matrox/matroxfb_crtc2.c | 160 +- -+ drivers/video/matrox/matroxfb_g450.c | 185 +- -+ drivers/video/matrox/matroxfb_g450.h | 8 +- -+ drivers/video/matrox/matroxfb_maven.c | 50 +- -+ drivers/video/matrox/matroxfb_misc.c | 288 +- -+ drivers/video/matrox/matroxfb_misc.h | 15 +- -+ drivers/video/msm/Makefile | 19 + -+ drivers/video/msm/mddi.c | 828 ++++ -+ drivers/video/msm/mddi_client_dummy.c | 97 + -+ drivers/video/msm/mddi_client_nt35399.c | 255 ++ -+ drivers/video/msm/mddi_client_toshiba.c | 283 ++ -+ drivers/video/msm/mddi_hw.h | 305 ++ -+ drivers/video/msm/mdp.c | 538 +++ -+ drivers/video/msm/mdp_csc_table.h | 582 +++ -+ drivers/video/msm/mdp_hw.h | 621 +++ -+ drivers/video/msm/mdp_ppp.c | 750 ++++ -+ drivers/video/msm/mdp_scale_tables.c | 766 ++++ -+ drivers/video/msm/mdp_scale_tables.h | 38 + -+ drivers/video/msm/msm_fb.c | 636 +++ -+ drivers/video/omap/Kconfig | 82 +- -+ drivers/video/omap/Makefile | 12 + -+ drivers/video/omap/blizzard.c | 91 +- -+ drivers/video/omap/dispc.c | 130 +- -+ drivers/video/omap/dispc.h | 7 +- -+ drivers/video/omap/hwa742.c | 2 +- -+ drivers/video/omap/lcd_2430sdp.c | 202 + -+ drivers/video/omap/lcd_ams_delta.c | 137 + -+ drivers/video/omap/lcd_apollon.c | 138 + -+ drivers/video/omap/lcd_ldp.c | 200 + -+ drivers/video/omap/lcd_mipid.c | 625 +++ -+ drivers/video/omap/lcd_omap2evm.c | 191 + -+ drivers/video/omap/lcd_omap3beagle.c | 130 + -+ drivers/video/omap/lcd_omap3evm.c | 192 + -+ drivers/video/omap/lcd_overo.c | 179 + -+ drivers/video/omap/omapfb_main.c | 64 +- -+ drivers/video/omap/rfbi.c | 7 +- -+ drivers/video/platinumfb.c | 12 +- -+ drivers/video/s3c-fb.c | 2 +- -+ drivers/video/s3c2410fb.c | 4 +- -+ drivers/video/sis/sis_main.c | 4 +- -+ drivers/video/sis/vstruct.h | 2 +- -+ drivers/video/tmiofb.c | 2 +- -+ drivers/video/via/accel.c | 589 ++- -+ drivers/video/via/accel.h | 13 +- -+ drivers/video/via/chip.h | 4 +- -+ drivers/video/via/dvi.c | 6 +- -+ drivers/video/via/global.c | 3 - -+ drivers/video/via/global.h | 2 - -+ drivers/video/via/hw.c | 474 +-- -+ drivers/video/via/hw.h | 57 +- -+ drivers/video/via/ioctl.h | 6 +- -+ drivers/video/via/lcd.c | 16 +- -+ drivers/video/via/share.h | 98 + -+ drivers/video/via/via_i2c.c | 64 +- -+ drivers/video/via/viafbdev.c | 1049 ++--- -+ drivers/video/via/viafbdev.h | 61 +- -+ drivers/video/via/viamode.c | 100 +- -+ drivers/video/via/viamode.h | 141 +- -+ drivers/video/via/vt1636.c | 4 +- -+ drivers/virtio/virtio_balloon.c | 3 +- -+ drivers/virtio/virtio_pci.c | 125 +- -+ drivers/virtio/virtio_ring.c | 6 +- -+ drivers/vlynq/vlynq.c | 1 - -+ firmware/ihex2fw.c | 2 +- -+ fs/9p/Kconfig | 9 + -+ fs/9p/Makefile | 3 +- -+ fs/9p/cache.c | 474 +++ -+ fs/9p/cache.h | 176 + -+ fs/9p/v9fs.c | 196 +- -+ fs/9p/v9fs.h | 13 +- -+ fs/9p/v9fs_vfs.h | 6 + -+ fs/9p/vfs_addr.c | 88 +- -+ fs/9p/vfs_file.c | 25 +- -+ fs/9p/vfs_inode.c | 61 +- -+ fs/9p/vfs_super.c | 16 +- -+ fs/afs/proc.c | 8 +- -+ fs/aio.c | 10 +- -+ fs/anon_inodes.c | 68 +- -+ fs/buffer.c | 57 +- -+ fs/compat.c | 7 - -+ fs/devpts/inode.c | 3 +- -+ fs/dlm/debug_fs.c | 12 +- -+ fs/eventfd.c | 67 +- -+ fs/exec.c | 5 + -+ fs/ext2/namei.c | 2 +- -+ fs/hugetlbfs/inode.c | 4 +- -+ fs/inode.c | 19 +- -+ fs/jbd2/journal.c | 4 +- -+ fs/jffs2/background.c | 20 +- -+ fs/jffs2/malloc.c | 4 +- -+ fs/minix/dir.c | 22 +- -+ fs/ncpfs/dir.c | 2 +- -+ fs/ncpfs/ioctl.c | 2 +- -+ fs/nfs/client.c | 17 +- -+ fs/nfs/fscache.c | 25 +- -+ fs/nfs/fscache.h | 6 +- -+ fs/nfs/super.c | 76 +- -+ fs/nfsd/export.c | 2 +- -+ fs/ntfs/file.c | 42 +- -+ fs/ocfs2/Makefile | 1 + -+ fs/ocfs2/alloc.c | 1342 ++++--- -+ fs/ocfs2/alloc.h | 101 +- -+ fs/ocfs2/aops.c | 37 +- -+ fs/ocfs2/aops.h | 2 + -+ fs/ocfs2/buffer_head_io.c | 47 +- -+ fs/ocfs2/buffer_head_io.h | 8 +- -+ fs/ocfs2/cluster/masklog.c | 1 + -+ fs/ocfs2/cluster/masklog.h | 1 + -+ fs/ocfs2/cluster/netdebug.c | 4 +- -+ fs/ocfs2/dir.c | 107 +- -+ fs/ocfs2/dlm/dlmdebug.c | 2 +- -+ fs/ocfs2/dlm/dlmthread.c | 6 +- -+ fs/ocfs2/dlmglue.c | 105 +- -+ fs/ocfs2/dlmglue.h | 6 + -+ fs/ocfs2/extent_map.c | 33 +- -+ fs/ocfs2/extent_map.h | 8 +- -+ fs/ocfs2/file.c | 151 +- -+ fs/ocfs2/file.h | 2 + -+ fs/ocfs2/inode.c | 86 +- -+ fs/ocfs2/inode.h | 20 +- -+ fs/ocfs2/ioctl.c | 14 + -+ fs/ocfs2/journal.c | 82 +- -+ fs/ocfs2/journal.h | 94 +- -+ fs/ocfs2/localalloc.c | 12 +- -+ fs/ocfs2/namei.c | 341 ++- -+ fs/ocfs2/namei.h | 6 + -+ fs/ocfs2/ocfs2.h | 52 +- -+ fs/ocfs2/ocfs2_fs.h | 107 +- -+ fs/ocfs2/ocfs2_lockid.h | 5 + -+ fs/ocfs2/quota_global.c | 5 +- -+ fs/ocfs2/quota_local.c | 26 +- -+ fs/ocfs2/refcounttree.c | 4313 ++++++++++++++++++++ -+ fs/ocfs2/refcounttree.h | 106 + -+ fs/ocfs2/resize.c | 16 +- -+ fs/ocfs2/slot_map.c | 10 +- -+ fs/ocfs2/suballoc.c | 35 +- -+ fs/ocfs2/super.c | 13 +- -+ fs/ocfs2/uptodate.c | 265 +- -+ fs/ocfs2/uptodate.h | 51 +- -+ fs/ocfs2/xattr.c | 2056 +++++++++- -+ fs/ocfs2/xattr.h | 15 +- -+ fs/open.c | 5 +- -+ fs/proc/array.c | 85 +- -+ fs/proc/base.c | 23 +- -+ fs/proc/kcore.c | 300 ++- -+ fs/proc/nommu.c | 2 +- -+ fs/proc/task_mmu.c | 33 +- -+ fs/qnx4/Kconfig | 11 - -+ fs/qnx4/Makefile | 2 +- -+ fs/qnx4/bitmap.c | 81 - -+ fs/qnx4/dir.c | 5 - -+ fs/qnx4/file.c | 40 - -+ fs/qnx4/inode.c | 84 +- -+ fs/qnx4/namei.c | 105 - -+ fs/qnx4/qnx4.h | 8 - -+ fs/qnx4/truncate.c | 34 - -+ fs/ramfs/inode.c | 4 +- -+ fs/select.c | 14 +- -+ fs/smbfs/proc.c | 2 +- -+ fs/sync.c | 1 + -+ include/acpi/acpi_bus.h | 16 +- -+ include/acpi/acpiosxf.h | 3 + -+ include/acpi/acpixf.h | 10 +- -+ include/acpi/actbl.h | 78 +- -+ include/acpi/actbl1.h | 872 +--- -+ include/acpi/actbl2.h | 868 ++++ -+ include/acpi/actypes.h | 92 +- -+ include/acpi/platform/aclinux.h | 4 +- -+ include/asm-generic/cputime.h | 1 + -+ include/asm-generic/gpio.h | 8 + -+ include/asm-generic/kmap_types.h | 47 +- -+ include/asm-generic/sections.h | 16 + -+ include/asm-generic/syscall.h | 8 +- -+ include/linux/acpi.h | 15 +- -+ include/linux/anon_inodes.h | 3 + -+ include/linux/cn_proc.h | 10 + -+ include/linux/cpumask.h | 12 + -+ include/linux/cred.h | 18 +- -+ include/linux/eventfd.h | 6 + -+ include/linux/firewire.h | 14 - -+ include/linux/gfp.h | 2 +- -+ include/linux/gpio.h | 11 + -+ include/linux/i2c-id.h | 11 - -+ include/linux/i2c.h | 2 - -+ include/linux/i2c/adp5588.h | 92 + -+ include/linux/i2c/mcs5000_ts.h | 24 + -+ include/linux/i8042.h | 30 + -+ include/linux/input.h | 2 +- -+ include/linux/intel-iommu.h | 2 + -+ include/linux/ioport.h | 4 + -+ include/linux/iova.h | 1 - -+ include/linux/jbd.h | 2 +- -+ include/linux/kernel.h | 16 +- -+ include/linux/kmemcheck.h | 6 +- -+ include/linux/libps2.h | 2 + -+ include/linux/linkage.h | 2 + -+ include/linux/magic.h | 6 + -+ include/linux/memory_hotplug.h | 8 - -+ include/linux/mfd/da903x.h | 4 +- -+ include/linux/mfd/wm831x/pmu.h | 189 + -+ include/linux/mm.h | 8 + -+ include/linux/mmc/card.h | 12 +- -+ include/linux/mmc/core.h | 1 + -+ include/linux/mmc/host.h | 58 + -+ include/linux/mmc/mmc.h | 3 + -+ include/linux/mmc/sdio_func.h | 3 + -+ include/linux/mod_devicetable.h | 11 + -+ include/linux/mtd/nand.h | 5 +- -+ include/linux/mtd/nand_ecc.h | 6 + -+ include/linux/mtd/onenand.h | 8 + -+ include/linux/mtd/onenand_regs.h | 3 + -+ include/linux/nfsd/nfsd.h | 2 +- -+ include/linux/pci_ids.h | 1 + -+ include/linux/power_supply.h | 21 + -+ include/linux/proc_fs.h | 16 +- -+ include/linux/regulator/consumer.h | 4 + -+ include/linux/regulator/driver.h | 5 +- -+ include/linux/regulator/fixed.h | 24 + -+ include/linux/regulator/machine.h | 26 +- -+ include/linux/regulator/max1586.h | 4 +- -+ include/linux/sched.h | 27 +- -+ include/linux/serial_core.h | 4 +- -+ include/linux/sfi.h | 206 + -+ include/linux/sfi_acpi.h | 93 + -+ include/linux/spi/mc33880.h | 10 + -+ include/linux/spi/spi.h | 51 +- -+ include/linux/sunrpc/xdr.h | 5 +- -+ include/linux/syscalls.h | 3 +- -+ include/linux/ucb1400.h | 19 + -+ include/linux/usb.h | 25 +- -+ include/linux/usb/audio.h | 287 +- -+ include/linux/usb/ch9.h | 8 + -+ include/linux/usb/ehci_def.h | 35 + -+ include/linux/usb/isp1362.h | 46 + -+ include/linux/usb/isp1760.h | 18 + -+ include/linux/usb/serial.h | 2 + -+ include/linux/usbdevice_fs.h | 3 + -+ include/linux/vgaarb.h | 11 +- -+ include/linux/virtio.h | 2 +- -+ include/linux/virtio_9p.h | 2 - -+ include/linux/virtio_balloon.h | 3 - -+ include/linux/virtio_blk.h | 18 +- -+ include/linux/virtio_config.h | 3 +- -+ include/linux/virtio_console.h | 3 - -+ include/linux/virtio_ids.h | 17 + -+ include/linux/virtio_net.h | 3 - -+ include/linux/virtio_rng.h | 3 - -+ include/linux/wm97xx.h | 18 + -+ include/linux/wm97xx_batt.h | 18 +- -+ include/net/9p/9p.h | 3 + -+ include/trace/events/timer.h | 342 ++ -+ include/video/da8xx-fb.h | 103 + -+ init/Kconfig | 8 - -+ init/main.c | 2 + -+ ipc/util.c | 2 +- -+ kernel/cgroup.c | 2 +- -+ kernel/cred.c | 19 + -+ kernel/exit.c | 10 +- -+ kernel/fork.c | 12 +- -+ kernel/hrtimer.c | 40 +- -+ kernel/itimer.c | 169 +- -+ kernel/kallsyms.c | 3 +- ++ Documentation/auxdisplay/cfag12864b-example.c | 1 - ++ Documentation/cgroups/cgroups.txt | 32 +- ++ Documentation/cgroups/memory.txt | 41 +- ++ Documentation/crypto/async-tx-api.txt | 75 +- ++ Documentation/filesystems/sharedsubtree.txt | 220 +-- ++ Documentation/filesystems/vfs.txt | 7 + ++ Documentation/ioctl/ioctl-number.txt | 1 + ++ Documentation/sysctl/fs.txt | 17 +- ++ Documentation/sysctl/kernel.txt | 22 + ++ Documentation/sysctl/vm.txt | 41 +- ++ Documentation/vm/.gitignore | 1 + ++ Documentation/vm/locking | 2 +- ++ Documentation/vm/page-types.c | 200 ++- ++ MAINTAINERS | 23 +- ++ arch/alpha/include/asm/fcntl.h | 2 + ++ arch/alpha/include/asm/smp.h | 2 +- ++ arch/alpha/include/asm/topology.h | 18 - ++ arch/alpha/kernel/core_marvel.c | 2 +- ++ arch/alpha/kernel/core_titan.c | 2 +- ++ arch/alpha/kernel/pci_impl.h | 2 +- ++ arch/alpha/kernel/pci_iommu.c | 4 +- ++ arch/alpha/kernel/process.c | 1 - ++ arch/alpha/kernel/smp.c | 14 +- ++ arch/arm/include/asm/cacheflush.h | 8 +- ++ arch/arm/include/asm/hardware/iop3xx-adma.h | 81 +- ++ arch/arm/include/asm/hardware/iop_adma.h | 3 + ++ arch/arm/include/asm/mmu_context.h | 7 +- ++ arch/arm/include/asm/smp.h | 1 - ++ arch/arm/include/asm/tlbflush.h | 4 +- ++ arch/arm/kernel/smp.c | 10 +- ++ arch/arm/kernel/sys_arm.c | 1 - ++ arch/arm/mach-iop13xx/include/mach/adma.h | 119 ++- ++ arch/arm/mach-iop13xx/setup.c | 17 +- ++ arch/arm/mm/context.c | 2 +- ++ arch/arm/mm/flush.c | 10 +- ++ arch/arm/plat-iop/adma.c | 4 +- ++ arch/frv/kernel/pm.c | 14 +- ++ arch/frv/kernel/sys_frv.c | 1 - ++ arch/h8300/kernel/sys_h8300.c | 1 - ++ arch/ia64/include/asm/smp.h | 1 - ++ arch/ia64/include/asm/topology.h | 3 - ++ arch/ia64/kernel/smp.c | 2 +- ++ arch/m32r/include/asm/mmu_context.h | 4 +- ++ arch/m32r/include/asm/smp.h | 2 +- ++ arch/m32r/kernel/smp.c | 30 +- ++ arch/m32r/kernel/smpboot.c | 2 +- ++ arch/m68k/kernel/sys_m68k.c | 1 - ++ arch/m68knommu/kernel/sys_m68k.c | 1 - ++ arch/microblaze/Kconfig | 1 + ++ arch/microblaze/Makefile | 31 +- ++ arch/microblaze/boot/Makefile | 41 +- ++ arch/microblaze/boot/dts/system.dts | 1 + ++ arch/microblaze/boot/linked_dtb.S | 3 + ++ arch/microblaze/configs/mmu_defconfig | 30 +- ++ arch/microblaze/configs/nommu_defconfig | 35 +- ++ arch/microblaze/include/asm/asm-compat.h | 17 + ++ arch/microblaze/include/asm/io.h | 3 + ++ arch/microblaze/include/asm/ipc.h | 1 - ++ arch/microblaze/include/asm/page.h | 3 + ++ arch/microblaze/include/asm/setup.h | 2 +- ++ arch/microblaze/include/asm/syscall.h | 99 ++ ++ arch/microblaze/kernel/cpu/cpuinfo.c | 3 + ++ arch/microblaze/kernel/entry.S | 72 +- ++ arch/microblaze/kernel/exceptions.c | 33 +- ++ arch/microblaze/kernel/head.S | 14 +- ++ arch/microblaze/kernel/hw_exception_handler.S | 10 +- ++ arch/microblaze/kernel/process.c | 1 + ++ arch/microblaze/kernel/ptrace.c | 62 + ++ arch/microblaze/kernel/setup.c | 12 +- ++ arch/microblaze/kernel/sys_microblaze.c | 1 - ++ arch/microblaze/kernel/vmlinux.lds.S | 72 +- ++ arch/microblaze/mm/init.c | 3 +- ++ arch/mips/alchemy/common/time.c | 2 +- ++ arch/mips/include/asm/mach-ip27/topology.h | 2 - ++ arch/mips/include/asm/mmu_context.h | 10 +- ++ arch/mips/include/asm/smp-ops.h | 2 +- ++ arch/mips/include/asm/smp.h | 2 +- ++ arch/mips/kernel/smp-cmp.c | 6 +- ++ arch/mips/kernel/smp-mt.c | 6 +- ++ arch/mips/kernel/smp-up.c | 3 +- ++ arch/mips/kernel/smp.c | 8 +- ++ arch/mips/kernel/smtc.c | 6 +- ++ arch/mips/lasat/sysctl.c | 18 +- ++ arch/mips/mipssim/sim_smtc.c | 5 +- ++ arch/mips/mm/c-octeon.c | 2 +- ++ arch/mips/mti-malta/malta-smtc.c | 4 +- ++ arch/mips/pmc-sierra/yosemite/smp.c | 4 +- ++ arch/mips/sgi-ip27/ip27-memory.c | 2 +- ++ arch/mips/sgi-ip27/ip27-smp.c | 4 +- ++ arch/mips/sibyte/bcm1480/smp.c | 5 +- ++ arch/mips/sibyte/sb1250/smp.c | 5 +- ++ arch/mn10300/include/asm/mmu_context.h | 12 +- ++ arch/mn10300/kernel/sys_mn10300.c | 1 - ++ arch/parisc/include/asm/fcntl.h | 2 + ++ arch/parisc/include/asm/smp.h | 1 - ++ arch/parisc/kernel/sys_parisc32.c | 1 - ++ arch/powerpc/include/asm/fsldma.h | 136 ++ ++ arch/powerpc/include/asm/smp.h | 2 +- ++ arch/powerpc/include/asm/topology.h | 12 - ++ arch/powerpc/kernel/setup-common.c | 7 +- ++ arch/powerpc/kernel/smp.c | 12 +- ++ arch/powerpc/kernel/sys_ppc32.c | 1 - ++ arch/powerpc/platforms/powermac/smp.c | 6 +- ++ arch/powerpc/platforms/pseries/hotplug-cpu.c | 6 +- ++ arch/s390/appldata/appldata_base.c | 9 +- ++ arch/s390/include/asm/smp.h | 2 +- ++ arch/s390/include/asm/topology.h | 1 - ++ arch/s390/kernel/compat_linux.c | 1 - ++ arch/s390/kernel/debug.c | 4 +- ++ arch/s390/kernel/process.c | 1 - ++ arch/s390/kernel/smp.c | 4 +- ++ arch/s390/mm/cmm.c | 4 +- ++ arch/sh/drivers/dma/Kconfig | 12 +- ++ arch/sh/drivers/dma/Makefile | 3 +- ++ arch/sh/include/asm/dma-sh.h | 13 + ++ arch/sh/include/asm/smp.h | 1 - ++ arch/sh/include/asm/topology.h | 1 - ++ arch/sh/kernel/sys_sh32.c | 1 - ++ arch/sh/kernel/sys_sh64.c | 1 - ++ arch/sparc/include/asm/smp_64.h | 1 - ++ arch/sparc/include/asm/topology_64.h | 16 - ++ arch/sparc/kernel/sys_sparc32.c | 1 - ++ arch/sparc/kernel/systbls.h | 3 +- ++ arch/um/include/asm/mmu_context.h | 4 +- ++ arch/um/kernel/smp.c | 2 +- ++ arch/x86/include/asm/mmu_context.h | 6 +- ++ arch/x86/include/asm/nmi.h | 3 +- ++ arch/x86/include/asm/pci.h | 6 +- ++ arch/x86/include/asm/smp.h | 1 - ++ arch/x86/kernel/apic/io_apic.c | 7 +- ++ arch/x86/kernel/apic/nmi.c | 4 +- ++ arch/x86/kernel/dumpstack_32.c | 1 - ++ arch/x86/kernel/dumpstack_64.c | 1 - ++ arch/x86/kernel/ldt.c | 4 +- ++ arch/x86/kernel/process.c | 6 +- ++ arch/x86/kernel/smpboot.c | 9 +- ++ arch/x86/kernel/time.c | 1 - ++ arch/x86/kernel/traps.c | 1 - ++ arch/x86/kernel/vsyscall_64.c | 10 +- ++ arch/x86/mm/fault.c | 19 +- ++ arch/x86/mm/pageattr.c | 1 + ++ arch/x86/mm/tlb.c | 15 +- ++ arch/x86/pci/common.c | 2 +- ++ arch/x86/xen/mmu.c | 4 +- ++ crypto/async_tx/Kconfig | 9 + ++ crypto/async_tx/Makefile | 3 + ++ crypto/async_tx/async_memcpy.c | 44 +- ++ crypto/async_tx/async_memset.c | 43 +- ++ crypto/async_tx/async_pq.c | 395 +++++ ++ crypto/async_tx/async_raid6_recov.c | 468 ++++++ ++ crypto/async_tx/async_tx.c | 87 +- ++ crypto/async_tx/async_xor.c | 207 ++-- ++ crypto/async_tx/raid6test.c | 240 +++ ++ drivers/acpi/button.c | 45 +- ++ drivers/acpi/osl.c | 2 +- ++ drivers/acpi/processor_perflib.c | 3 +- ++ drivers/acpi/processor_throttling.c | 3 +- ++ drivers/cdrom/cdrom.c | 8 +- ++ drivers/char/Kconfig | 8 + ++ drivers/char/Makefile | 1 + ++ drivers/char/agp/intel-agp.c | 37 +- ++ drivers/char/bfin-otp.c | 173 ++- ++ drivers/char/hpet.c | 21 +- ++ drivers/char/mem.c | 2 +- ++ drivers/char/mwave/mwavedd.c | 22 +- ++ drivers/char/random.c | 4 +- ++ drivers/char/rio/rioctrl.c | 2 +- ++ drivers/char/uv_mmtimer.c | 216 +++ ++ drivers/dca/dca-core.c | 124 ++- ++ drivers/dma/Kconfig | 14 +- ++ drivers/dma/Makefile | 4 +- ++ drivers/dma/at_hdmac.c | 60 +- ++ drivers/dma/at_hdmac_regs.h | 1 + ++ drivers/dma/dmaengine.c | 94 +- ++ drivers/dma/dmatest.c | 40 + ++ drivers/dma/dw_dmac.c | 50 +- ++ drivers/dma/dw_dmac_regs.h | 1 + ++ drivers/dma/fsldma.c | 288 +++- ++ drivers/dma/fsldma.h | 4 +- ++ drivers/dma/ioat.c | 202 --- ++ drivers/dma/ioat/Makefile | 2 + ++ drivers/dma/{ioat_dca.c => ioat/dca.c} | 13 +- ++ drivers/dma/ioat/dma.c | 1238 ++++++++++++++ ++ drivers/dma/ioat/dma.h | 337 ++++ ++ drivers/dma/ioat/dma_v2.c | 871 ++++++++++ ++ drivers/dma/ioat/dma_v2.h | 190 +++ ++ drivers/dma/ioat/dma_v3.c | 1223 ++++++++++++++ ++ drivers/dma/ioat/hw.h | 215 +++ ++ drivers/dma/ioat/pci.c | 210 +++ ++ .../dma/{ioatdma_registers.h => ioat/registers.h} | 54 +- ++ drivers/dma/ioat_dma.c | 1741 -------------------- ++ drivers/dma/ioatdma.h | 165 -- ++ drivers/dma/ioatdma_hw.h | 70 - ++ drivers/dma/iop-adma.c | 491 +++++- ++ drivers/dma/iovlock.c | 10 + ++ drivers/dma/mv_xor.c | 7 +- ++ drivers/dma/mv_xor.h | 4 +- ++ drivers/dma/shdma.c | 786 +++++++++ ++ drivers/dma/shdma.h | 64 + ++ drivers/dma/txx9dmac.c | 24 +- ++ drivers/dma/txx9dmac.h | 1 + ++ drivers/edac/Kconfig | 13 +- ++ drivers/edac/Makefile | 2 + ++ drivers/edac/cpc925_edac.c | 6 +- ++ drivers/edac/edac_device.c | 5 +- ++ drivers/edac/edac_mc.c | 4 +- ++ drivers/edac/edac_pci.c | 4 +- ++ drivers/edac/i3200_edac.c | 527 ++++++ ++ drivers/edac/mpc85xx_edac.c | 30 +- ++ drivers/edac/mv64x60_edac.c | 22 +- ++ drivers/gpu/drm/Kconfig | 1 + ++ drivers/gpu/drm/drm_gem.c | 13 + ++ drivers/gpu/drm/i915/Makefile | 1 + ++ drivers/gpu/drm/i915/i915_debugfs.c | 6 +- ++ drivers/gpu/drm/i915/i915_dma.c | 194 +++- ++ drivers/gpu/drm/i915/i915_drv.c | 133 ++- ++ drivers/gpu/drm/i915/i915_drv.h | 77 +- ++ drivers/gpu/drm/i915/i915_gem.c | 876 ++++++++--- ++ drivers/gpu/drm/i915/i915_irq.c | 92 +- ++ drivers/gpu/drm/i915/i915_opregion.c | 22 +- ++ drivers/gpu/drm/i915/i915_reg.h | 34 + ++ drivers/gpu/drm/i915/i915_suspend.c | 170 ++- ++ drivers/gpu/drm/i915/i915_trace.h | 315 ++++ ++ drivers/gpu/drm/i915/i915_trace_points.c | 11 + ++ drivers/gpu/drm/i915/intel_bios.c | 3 + ++ drivers/gpu/drm/i915/intel_crt.c | 9 +- ++ drivers/gpu/drm/i915/intel_display.c | 616 ++++++-- ++ drivers/gpu/drm/i915/intel_drv.h | 5 +- ++ drivers/gpu/drm/i915/intel_lvds.c | 63 +- ++ drivers/gpu/drm/i915/intel_sdvo.c | 502 ++++++- ++ drivers/idle/i7300_idle.c | 20 +- ++ drivers/input/misc/Kconfig | 1 + ++ drivers/md/Kconfig | 26 + ++ drivers/md/bitmap.c | 5 +- ++ drivers/md/linear.c | 3 + ++ drivers/md/md.c | 25 +- ++ drivers/md/md.h | 1 + ++ drivers/md/multipath.c | 6 +- ++ drivers/md/raid0.c | 8 +- ++ drivers/md/raid1.c | 15 +- ++ drivers/md/raid10.c | 12 +- ++ drivers/md/raid5.c | 1493 +++++++++++------- ++ drivers/md/raid5.h | 28 +- ++ drivers/media/dvb/dvb-core/dvbdev.h | 5 +- ++ drivers/media/dvb/dvb-usb/Kconfig | 2 +- ++ drivers/media/video/saa7164/saa7164-api.c | 8 +- ++ drivers/media/video/saa7164/saa7164-cmd.c | 2 +- ++ drivers/media/video/saa7164/saa7164-core.c | 6 +- ++ drivers/media/video/saa7164/saa7164.h | 4 +- ++ drivers/media/video/usbvision/usbvision-core.c | 1 - ++ drivers/media/video/usbvision/usbvision-i2c.c | 1 - ++ drivers/media/video/usbvision/usbvision-video.c | 1 - ++ drivers/memstick/core/memstick.c | 2 +- ++ drivers/misc/sgi-gru/grukservices.c | 2 + ++ drivers/misc/sgi-gru/gruprocfs.c | 3 +- ++ drivers/mmc/host/atmel-mci.c | 9 +- ++ drivers/mtd/Kconfig | 2 +- ++ drivers/mtd/maps/Kconfig | 2 +- ++ drivers/net/sfc/efx.c | 3 +- ++ drivers/net/wireless/arlan-proc.c | 28 +- ++ drivers/oprofile/buffer_sync.c | 3 +- ++ drivers/parport/procfs.c | 12 +- ++ drivers/pci/hotplug/pciehp.h | 107 +- ++ drivers/pci/hotplug/pciehp_acpi.c | 17 +- ++ drivers/pci/hotplug/pciehp_core.c | 136 +- ++ drivers/pci/hotplug/pciehp_ctrl.c | 109 +- ++ drivers/pci/hotplug/pciehp_hpc.c | 109 +- ++ drivers/pci/hotplug/pciehp_pci.c | 23 +- ++ drivers/pci/pcie/aer/aerdrv.c | 2 + ++ drivers/pci/pcie/aspm.c | 3 - ++ drivers/s390/char/zcore.c | 1 - ++ drivers/staging/go7007/Makefile | 5 - ++ drivers/usb/Kconfig | 1 - ++ drivers/usb/gadget/f_loopback.c | 1 - ++ drivers/usb/gadget/f_obex.c | 1 - ++ drivers/usb/gadget/f_sourcesink.c | 1 - ++ drivers/usb/gadget/u_audio.c | 1 - ++ drivers/usb/gadget/u_ether.c | 1 - ++ drivers/usb/serial/sierra.c | 5 + ++ drivers/vlynq/vlynq.c | 2 +- ++ fs/adfs/inode.c | 7 - ++ fs/attr.c | 46 +- ++ fs/befs/linuxvfs.c | 7 +- ++ fs/binfmt_elf.c | 52 +- ++ fs/binfmt_elf_fdpic.c | 17 +- ++ fs/binfmt_flat.c | 22 +- ++ fs/block_dev.c | 140 +- ++ fs/btrfs/async-thread.c | 254 +++- ++ fs/btrfs/async-thread.h | 12 + ++ fs/btrfs/btrfs_inode.h | 1 + ++ fs/btrfs/compression.c | 8 +- ++ fs/btrfs/ctree.c | 6 + ++ fs/btrfs/ctree.h | 78 +- ++ fs/btrfs/dir-item.c | 47 + ++ fs/btrfs/disk-io.c | 235 ++- ++ fs/btrfs/export.c | 133 +- ++ fs/btrfs/extent-tree.c | 1662 ++++++++----------- ++ fs/btrfs/extent_io.c | 330 +++-- ++ fs/btrfs/extent_io.h | 16 +- ++ fs/btrfs/extent_map.c | 103 ++- ++ fs/btrfs/extent_map.h | 5 +- ++ fs/btrfs/file.c | 35 +- ++ fs/btrfs/free-space-cache.c | 36 +- ++ fs/btrfs/inode-item.c | 4 +- ++ fs/btrfs/inode-map.c | 93 +- ++ fs/btrfs/inode.c | 664 ++++++-- ++ fs/btrfs/ioctl.c | 339 +++-- ++ fs/btrfs/ioctl.h | 3 +- ++ fs/btrfs/ordered-data.c | 33 +- ++ fs/btrfs/ordered-data.h | 3 + ++ fs/btrfs/orphan.c | 20 + ++ fs/btrfs/relocation.c | 280 ++-- ++ fs/btrfs/root-tree.c | 138 ++- ++ fs/btrfs/super.c | 1 + ++ fs/btrfs/transaction.c | 38 +- ++ fs/btrfs/tree-log.c | 25 +- ++ fs/btrfs/volumes.c | 117 +- ++ fs/btrfs/volumes.h | 3 + ++ fs/buffer.c | 10 +- ++ fs/char_dev.c | 3 - ++ fs/cifs/cifsfs.c | 3 +- ++ fs/cifs/inode.c | 53 +- ++ fs/coda/coda_int.h | 1 + ++ fs/compat.c | 24 +- ++ fs/drop_caches.c | 4 +- ++ fs/exec.c | 114 +- ++ fs/exofs/super.c | 6 - ++ fs/ext2/inode.c | 2 + ++ fs/ext3/inode.c | 3 + ++ fs/ext4/inode.c | 4 + ++ fs/fat/inode.c | 16 +- ++ fs/fcntl.c | 108 ++- ++ fs/file_table.c | 6 +- ++ fs/fuse/dir.c | 14 +- ++ fs/fuse/fuse_i.h | 2 - ++ fs/fuse/inode.c | 11 +- ++ fs/gfs2/aops.c | 3 + ++ fs/gfs2/ops_inode.c | 1 - ++ fs/hfs/mdb.c | 6 +- ++ fs/hfsplus/super.c | 6 +- ++ fs/hugetlbfs/inode.c | 45 +- ++ fs/inode.c | 89 +- ++ fs/internal.h | 1 + ++ fs/ioctl.c | 9 +- ++ fs/isofs/inode.c | 8 +- ++ fs/jfs/super.c | 9 +- ++ fs/libfs.c | 13 +- ++ fs/lockd/xdr.c | 1 - ++ fs/lockd/xdr4.c | 1 - ++ fs/namespace.c | 77 +- ++ fs/ncpfs/inode.c | 12 +- ++ fs/ncpfs/ioctl.c | 6 +- ++ fs/nfs/file.c | 1 + ++ fs/nfs/inode.c | 54 +- ++ fs/nfs/nfs2xdr.c | 1 - ++ fs/nfs/nfs3proc.c | 1 - ++ fs/nfs/nfs3xdr.c | 1 - ++ fs/nfs/nfs4proc.c | 1 - ++ fs/nfs/nfs4xdr.c | 1 - ++ fs/nfs/proc.c | 1 - ++ fs/nfsd/nfs4idmap.c | 1 - ++ fs/nls/nls_base.c | 3 +- ++ fs/ntfs/aops.c | 2 + ++ fs/ntfs/super.c | 10 +- ++ fs/ocfs2/aops.c | 1 + ++ fs/ocfs2/dlm/dlmast.c | 1 - ++ fs/ocfs2/dlm/dlmconvert.c | 1 - ++ fs/ocfs2/dlm/dlmdebug.c | 1 - ++ fs/ocfs2/dlm/dlmdomain.c | 1 - ++ fs/ocfs2/dlm/dlmlock.c | 1 - ++ fs/ocfs2/dlm/dlmmaster.c | 1 - ++ fs/ocfs2/dlm/dlmrecovery.c | 1 - ++ fs/ocfs2/dlm/dlmthread.c | 1 - ++ fs/ocfs2/dlm/dlmunlock.c | 1 - ++ fs/ocfs2/super.c | 1 - ++ fs/ocfs2/symlink.c | 1 - ++ fs/proc/meminfo.c | 9 +- ++ fs/proc/proc_sysctl.c | 2 +- ++ fs/proc/uptime.c | 7 +- ++ fs/ramfs/file-nommu.c | 18 +- ++ fs/read_write.c | 3 - ++ fs/romfs/super.c | 2 +- ++ fs/seq_file.c | 74 +- ++ fs/smbfs/inode.c | 10 +- ++ fs/super.c | 67 +- ++ fs/xfs/linux-2.6/xfs_aops.c | 1 + ++ fs/xfs/linux-2.6/xfs_sysctl.c | 3 +- ++ include/acpi/button.h | 25 + ++ include/asm-generic/fcntl.h | 13 + ++ include/asm-generic/mman-common.h | 1 + ++ include/asm-generic/siginfo.h | 8 +- ++ include/asm-generic/topology.h | 17 - ++ include/drm/drm_pciids.h | 1 + ++ include/drm/i915_drm.h | 19 + ++ include/linux/async_tx.h | 129 ++- ++ include/linux/binfmts.h | 2 +- ++ include/linux/cgroup.h | 53 +- ++ include/linux/configfs.h | 4 +- ++ include/linux/cpumask.h | 709 +++----- ++ include/linux/dca.h | 11 +- ++ include/linux/debugfs.h | 2 +- ++ include/linux/dmaengine.h | 179 ++- ++ include/linux/fs.h | 11 +- ++ include/linux/ftrace.h | 4 +- ++ include/linux/futex.h | 10 +- ++ include/linux/hugetlb.h | 6 +- ++ include/linux/interrupt.h | 2 - ++ include/linux/memcontrol.h | 10 + ++ include/linux/mm.h | 22 +- ++ include/linux/mm_types.h | 7 +- ++ include/linux/mmzone.h | 13 +- ++ include/linux/module.h | 17 +- ++ include/linux/page-flags.h | 17 +- ++ include/linux/page_cgroup.h | 13 + ++ include/linux/pci_ids.h | 10 + ++ include/linux/prctl.h | 2 + ++ include/linux/relay.h | 2 +- ++ include/linux/res_counter.h | 64 +- ++ include/linux/rmap.h | 21 +- ++ include/linux/sched.h | 20 +- ++ include/linux/security.h | 2 +- ++ include/linux/seq_file.h | 38 + ++ include/linux/signal.h | 2 + ++ include/linux/smp.h | 11 - ++ include/linux/swap.h | 41 +- ++ include/linux/swapops.h | 38 + ++ include/linux/sysctl.h | 19 +- ++ include/linux/time.h | 28 + ++ include/linux/topology.h | 6 - ++ include/linux/tracehook.h | 34 +- ++ include/linux/tracepoint.h | 2 +- ++ include/linux/unaligned/be_byteshift.h | 2 +- ++ include/linux/unaligned/le_byteshift.h | 2 +- ++ include/linux/utsname.h | 1 - ++ include/linux/vgaarb.h | 3 +- ++ include/linux/writeback.h | 11 +- ++ include/net/ip.h | 2 +- ++ include/net/ndisc.h | 2 - ++ init/main.c | 6 - ++ ipc/ipc_sysctl.c | 16 +- ++ ipc/mq_sysctl.c | 8 +- ++ kernel/Makefile | 1 - ++ kernel/audit.c | 18 +- ++ kernel/audit_watch.c | 2 +- ++ kernel/auditsc.c | 6 +- ++ kernel/cgroup.c | 1107 +++++++++---- ++ kernel/cgroup_debug.c | 105 -- ++ kernel/cgroup_freezer.c | 15 +- ++ kernel/cpuset.c | 66 +- ++ kernel/exit.c | 146 +- ++ kernel/fork.c | 34 +- ++ kernel/gcov/Kconfig | 2 +- ++ kernel/hung_task.c | 4 +- + kernel/kmod.c | 13 +- -+ kernel/kprobes.c | 2 +- -+ kernel/lockdep.c | 3 + -+ kernel/lockdep_proc.c | 2 +- -+ kernel/posix-cpu-timers.c | 155 +- -+ kernel/printk.c | 27 +- -+ kernel/resource.c | 23 +- -+ kernel/sched.c | 9 +- -+ kernel/smp.c | 29 +- -+ kernel/sys.c | 14 + -+ kernel/sysctl.c | 14 + -+ kernel/timer.c | 32 +- ++ kernel/module.c | 159 ++- ++ kernel/ns_cgroup.c | 16 +- ++ kernel/params.c | 7 +- ++ kernel/pid_namespace.c | 2 +- ++ kernel/power/swap.c | 1 - ++ kernel/ptrace.c | 11 +- ++ kernel/res_counter.c | 21 +- ++ kernel/sched.c | 39 +- ++ kernel/sched_fair.c | 4 +- ++ kernel/signal.c | 168 +-- ++ kernel/slow-work.c | 12 +- ++ kernel/smp.c | 7 - ++ kernel/softlockup.c | 4 +- ++ kernel/sys.c | 22 + ++ kernel/sysctl.c | 113 +- ++ kernel/time/Makefile | 2 +- ++ kernel/time/timeconv.c | 127 ++ + kernel/trace/ftrace.c | 4 +- -+ kernel/trace/trace.c | 4 +- -+ lib/Kconfig.debug | 8 + -+ mm/Makefile | 4 +- -+ mm/memory_hotplug.c | 6 +- -+ mm/nommu.c | 3 +- -+ mm/vmalloc.c | 2 +- -+ net/9p/trans_virtio.c | 5 +- -+ net/ipv6/ip6mr.c | 2 +- -+ net/socket.c | 3 +- -+ net/sunrpc/rpc_pipe.c | 3 +- -+ net/sunrpc/xprtsock.c | 9 + -+ scripts/Kbuild.include | 16 +- -+ scripts/Makefile.build | 6 +- -+ scripts/basic/docproc.c | 34 +- -+ scripts/basic/fixdep.c | 26 +- -+ scripts/basic/hash.c | 4 +- -+ scripts/checkincludes.pl | 71 +- -+ scripts/conmakehash.c | 6 +- -+ scripts/genksyms/genksyms.c | 6 +- -+ scripts/kallsyms.c | 2 +- -+ scripts/kconfig/conf.c | 24 +- -+ scripts/kconfig/confdata.c | 2 +- -+ scripts/kconfig/expr.c | 6 +- -+ scripts/kconfig/gconf.c | 21 +- -+ scripts/kconfig/gconf.glade | 4 +- -+ scripts/kconfig/kxgettext.c | 4 +- -+ scripts/kconfig/lkc_proto.h | 2 + -+ scripts/kconfig/mconf.c | 78 +- -+ scripts/kconfig/menu.c | 84 +- -+ scripts/kconfig/qconf.cc | 10 +- -+ scripts/kconfig/symbol.c | 6 +- -+ scripts/markup_oops.pl | 5 +- -+ scripts/mod/file2alias.c | 13 + -+ scripts/mod/modpost.c | 4 +- -+ scripts/selinux/mdp/mdp.c | 4 +- -+ scripts/tags.sh | 3 +- -+ security/integrity/ima/ima_fs.c | 4 +- -+ security/keys/gc.c | 4 +- -+ security/selinux/avc.c | 19 +- -+ security/smack/smack_lsm.c | 8 +- -+ security/smack/smackfs.c | 6 +- -+ sound/core/pcm_native.c | 73 +- -+ sound/pci/lx6464es/lx6464es.h | 2 - -+ sound/pci/lx6464es/lx_core.c | 98 +- -+ sound/soc/blackfin/bf5xx-ac97.c | 8 + -+ sound/soc/blackfin/bf5xx-ac97.h | 2 +- -+ sound/soc/blackfin/bf5xx-i2s.c | 22 +- -+ sound/soc/blackfin/bf5xx-i2s.h | 2 +- -+ sound/soc/blackfin/bf5xx-sport.c | 2 +- -+ sound/soc/codecs/ad1836.c | 3 +- -+ sound/soc/codecs/ad1938.c | 2 +- -+ sound/soc/codecs/wm8753.c | 1 + -+ sound/soc/davinci/davinci-mcasp.c | 24 +- -+ usr/.gitignore | 2 + -+ usr/Makefile | 2 +- -+ usr/gen_init_cpio.c | 2 +- -+ 1043 files changed, 62626 insertions(+), 18117 deletions(-) -+ create mode 100644 Documentation/ABI/stable/sysfs-class-backlight -+ create mode 100644 Documentation/ABI/testing/sysfs-class-lcd -+ create mode 100644 Documentation/ABI/testing/sysfs-class-led -+ create mode 100644 Documentation/ABI/testing/sysfs-platform-asus-laptop -+ create mode 100644 Documentation/ABI/testing/sysfs-platform-eeepc-laptop -+ create mode 100644 Documentation/fb/ep93xx-fb.txt -+ create mode 100644 Documentation/hwmon/acpi_power_meter -+ delete mode 100644 Documentation/hwmon/fscher -+ delete mode 100644 Documentation/i2c/chips/pca9539 -+ delete mode 100644 Documentation/i2c/chips/pcf8574 -+ delete mode 100644 Documentation/i2c/chips/pcf8575 -+ create mode 100644 Documentation/laptops/asus-laptop.txt -+ create mode 100644 Documentation/power/regulator/design.txt -+ create mode 100644 arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c -+ create mode 100644 arch/arm/mach-ep93xx/include/mach/fb.h -+ create mode 100644 arch/arm/mach-nomadik/include/mach/fsmc.h -+ create mode 100644 arch/arm/mach-nomadik/include/mach/nand.h -+ create mode 100644 arch/arm/plat-mxc/include/mach/spi.h -+ create mode 100644 arch/x86/kernel/sfi.c -+ create mode 100644 drivers/acpi/acpica/nsrepair.c -+ create mode 100644 drivers/acpi/acpica/utids.c -+ create mode 100644 drivers/acpi/power_meter.c -+ create mode 100644 drivers/gpio/adp5520-gpio.c -+ create mode 100644 drivers/gpio/langwell_gpio.c -+ create mode 100644 drivers/gpio/mc33880.c -+ create mode 100644 drivers/gpio/ucb1400_gpio.c -+ create mode 100644 drivers/gpu/drm/radeon/radeon_family.h -+ delete mode 100644 drivers/hwmon/fscher.c -+ delete mode 100644 drivers/hwmon/fscpos.c -+ create mode 100644 drivers/i2c/busses/i2c-scmi.c -+ delete mode 100644 drivers/i2c/chips/pca9539.c -+ delete mode 100644 drivers/i2c/chips/pcf8574.c -+ delete mode 100644 drivers/i2c/chips/pcf8575.c -+ create mode 100644 drivers/input/keyboard/adp5588-keys.c -+ create mode 100644 drivers/input/keyboard/max7359_keypad.c -+ create mode 100644 drivers/input/keyboard/opencores-kbd.c -+ create mode 100644 drivers/input/keyboard/qt2160.c -+ create mode 100644 drivers/input/touchscreen/mcs5000_ts.c -+ create mode 100644 drivers/mmc/host/msm_sdcc.c -+ create mode 100644 drivers/mmc/host/msm_sdcc.h -+ mode change 100644 => 100755 drivers/mtd/chips/cfi_util.c -+ create mode 100644 drivers/mtd/devices/sst25l.c -+ mode change 100644 => 100755 drivers/mtd/inftlcore.c -+ create mode 100644 drivers/mtd/maps/gpio-addr-flash.c -+ create mode 100644 drivers/mtd/nand/nomadik_nand.c -+ create mode 100644 drivers/mtd/nand/w90p910_nand.c -+ create mode 100644 drivers/platform/x86/topstar-laptop.c -+ create mode 100644 drivers/power/wm831x_power.c -+ create mode 100644 drivers/regulator/tps65023-regulator.c -+ create mode 100644 drivers/regulator/tps6507x-regulator.c -+ create mode 100644 drivers/rtc/rtc-coh901331.c -+ create mode 100644 drivers/rtc/rtc-mxc.c -+ create mode 100644 drivers/rtc/rtc-pcap.c -+ create mode 100644 drivers/rtc/rtc-pcf2123.c -+ create mode 100644 drivers/rtc/rtc-stmp3xxx.c -+ create mode 100644 drivers/sfi/Kconfig -+ create mode 100644 drivers/sfi/Makefile -+ create mode 100644 drivers/sfi/sfi_acpi.c -+ create mode 100644 drivers/sfi/sfi_core.c -+ create mode 100644 drivers/sfi/sfi_core.h -+ create mode 100644 drivers/spi/mxc_spi.c -+ delete mode 100644 drivers/spi/spi_imx.c -+ create mode 100644 drivers/spi/spi_ppc4xx.c -+ create mode 100644 drivers/spi/spi_stmp.c -+ create mode 100644 drivers/usb/early/Makefile -+ create mode 100644 drivers/usb/early/ehci-dbgp.c -+ create mode 100644 drivers/usb/gadget/f_eem.c -+ create mode 100644 drivers/usb/host/ehci-atmel.c -+ create mode 100644 drivers/usb/host/ehci-w90x900.c -+ create mode 100644 drivers/usb/host/isp1362-hcd.c -+ create mode 100644 drivers/usb/host/isp1362.h -+ delete mode 100644 drivers/usb/mon/mon_dma.c -+ create mode 100644 drivers/video/da8xx-fb.c -+ create mode 100644 drivers/video/ep93xx-fb.c -+ create mode 100644 drivers/video/msm/Makefile -+ create mode 100644 drivers/video/msm/mddi.c -+ create mode 100644 drivers/video/msm/mddi_client_dummy.c -+ create mode 100644 drivers/video/msm/mddi_client_nt35399.c -+ create mode 100644 drivers/video/msm/mddi_client_toshiba.c -+ create mode 100644 drivers/video/msm/mddi_hw.h -+ create mode 100644 drivers/video/msm/mdp.c -+ create mode 100644 drivers/video/msm/mdp_csc_table.h -+ create mode 100644 drivers/video/msm/mdp_hw.h -+ create mode 100644 drivers/video/msm/mdp_ppp.c -+ create mode 100644 drivers/video/msm/mdp_scale_tables.c -+ create mode 100644 drivers/video/msm/mdp_scale_tables.h -+ create mode 100644 drivers/video/msm/msm_fb.c -+ create mode 100644 drivers/video/omap/lcd_2430sdp.c -+ create mode 100644 drivers/video/omap/lcd_ams_delta.c -+ create mode 100644 drivers/video/omap/lcd_apollon.c -+ create mode 100644 drivers/video/omap/lcd_ldp.c -+ create mode 100644 drivers/video/omap/lcd_mipid.c -+ create mode 100644 drivers/video/omap/lcd_omap2evm.c -+ create mode 100644 drivers/video/omap/lcd_omap3beagle.c -+ create mode 100644 drivers/video/omap/lcd_omap3evm.c -+ create mode 100644 drivers/video/omap/lcd_overo.c -+ create mode 100644 fs/9p/cache.c -+ create mode 100644 fs/9p/cache.h -+ create mode 100644 fs/ocfs2/refcounttree.c -+ create mode 100644 fs/ocfs2/refcounttree.h -+ delete mode 100644 fs/qnx4/file.c -+ delete mode 100644 fs/qnx4/truncate.c -+ create mode 100644 include/acpi/actbl2.h -+ create mode 100644 include/linux/i2c/adp5588.h -+ create mode 100644 include/linux/i2c/mcs5000_ts.h -+ create mode 100644 include/linux/mfd/wm831x/pmu.h -+ create mode 100644 include/linux/sfi.h -+ create mode 100644 include/linux/sfi_acpi.h -+ create mode 100644 include/linux/spi/mc33880.h -+ create mode 100644 include/linux/usb/isp1362.h -+ create mode 100644 include/linux/usb/isp1760.h -+ create mode 100644 include/linux/virtio_ids.h -+ create mode 100644 include/trace/events/timer.h -+ create mode 100644 include/video/da8xx-fb.h ++ kernel/trace/trace.c | 7 +- ++ kernel/trace/trace_stack.c | 4 +- ++ kernel/uid16.c | 1 - ++ kernel/utsname_sysctl.c | 4 +- ++ lib/decompress_inflate.c | 8 + ++ lib/decompress_unlzma.c | 10 +- ++ mm/Kconfig | 14 + ++ mm/Makefile | 2 + ++ mm/filemap.c | 6 +- ++ mm/hugetlb.c | 12 +- ++ mm/hwpoison-inject.c | 41 + ++ mm/ksm.c | 14 +- ++ mm/madvise.c | 30 + ++ mm/memcontrol.c | 737 ++++++++- ++ mm/memory-failure.c | 832 ++++++++++ ++ mm/memory.c | 86 +- ++ mm/migrate.c | 2 +- ++ mm/mremap.c | 4 +- ++ mm/nommu.c | 40 - ++ mm/page-writeback.c | 27 +- ++ mm/page_alloc.c | 44 +- ++ mm/quicklist.c | 3 +- ++ mm/rmap.c | 60 +- ++ mm/shmem.c | 5 +- ++ mm/swapfile.c | 4 +- ++ mm/truncate.c | 136 ++- ++ mm/vmscan.c | 51 +- ++ net/bridge/br_netfilter.c | 4 +- ++ net/decnet/dn_dev.c | 5 +- ++ net/decnet/sysctl_net_decnet.c | 2 - ++ net/ipv4/devinet.c | 12 +- ++ net/ipv4/route.c | 7 +- ++ net/ipv4/sysctl_net_ipv4.c | 16 +- ++ net/ipv6/addrconf.c | 8 +- ++ net/ipv6/ndisc.c | 8 +- ++ net/ipv6/route.c | 4 +- ++ net/irda/irsysctl.c | 8 +- ++ net/netfilter/ipvs/ip_vs_ctl.c | 8 +- ++ net/netfilter/nf_log.c | 4 +- ++ net/phonet/sysctl.c | 4 +- ++ net/sunrpc/auth_null.c | 1 - ++ net/sunrpc/sysctl.c | 4 +- ++ net/sunrpc/xprtrdma/svc_rdma.c | 2 +- ++ security/device_cgroup.c | 3 +- ++ security/lsm_audit.c | 2 +- ++ security/min_addr.c | 4 +- ++ security/selinux/hooks.c | 2 +- ++ virt/kvm/kvm_main.c | 3 +- ++ 520 files changed, 21854 insertions(+), 9097 deletions(-) ++ create mode 120000 arch/microblaze/boot/dts/system.dts ++ create mode 100644 arch/microblaze/boot/linked_dtb.S ++ create mode 100644 arch/microblaze/include/asm/asm-compat.h ++ delete mode 100644 arch/microblaze/include/asm/ipc.h ++ create mode 100644 arch/microblaze/include/asm/syscall.h ++ create mode 100644 arch/powerpc/include/asm/fsldma.h ++ create mode 100644 crypto/async_tx/async_pq.c ++ create mode 100644 crypto/async_tx/async_raid6_recov.c ++ create mode 100644 crypto/async_tx/raid6test.c ++ create mode 100644 drivers/char/uv_mmtimer.c ++ delete mode 100644 drivers/dma/ioat.c ++ create mode 100644 drivers/dma/ioat/Makefile ++ rename drivers/dma/{ioat_dca.c => ioat/dca.c} (98%) ++ create mode 100644 drivers/dma/ioat/dma.c ++ create mode 100644 drivers/dma/ioat/dma.h ++ create mode 100644 drivers/dma/ioat/dma_v2.c ++ create mode 100644 drivers/dma/ioat/dma_v2.h ++ create mode 100644 drivers/dma/ioat/dma_v3.c ++ create mode 100644 drivers/dma/ioat/hw.h ++ create mode 100644 drivers/dma/ioat/pci.c ++ rename drivers/dma/{ioatdma_registers.h => ioat/registers.h} (84%) ++ delete mode 100644 drivers/dma/ioat_dma.c ++ delete mode 100644 drivers/dma/ioatdma.h ++ delete mode 100644 drivers/dma/ioatdma_hw.h ++ create mode 100644 drivers/dma/shdma.c ++ create mode 100644 drivers/dma/shdma.h ++ create mode 100644 drivers/edac/i3200_edac.c ++ create mode 100644 drivers/gpu/drm/i915/i915_trace.h ++ create mode 100644 drivers/gpu/drm/i915/i915_trace_points.c ++ create mode 100644 include/acpi/button.h ++ delete mode 100644 kernel/cgroup_debug.c ++ create mode 100644 kernel/time/timeconv.c ++ create mode 100644 mm/hwpoison-inject.c ++ create mode 100644 mm/memory-failure.c +Merging fixes/fixes +$ git merge fixes/fixes -+Already up-to-date. ++Updating 94e0fb0..0049a32 ++Fast forward ++ arch/powerpc/kvm/timing.h | 2 +- ++ 1 files changed, 1 insertions(+), 1 deletions(-) +Merging arm-current/master +$ git merge arm-current/master -+Resolved 'MAINTAINERS' using previous resolution. ++Recorded preimage for 'MAINTAINERS' +Auto-merging MAINTAINERS +CONFLICT (content): Merge conflict in MAINTAINERS +Auto-merging arch/arm/mach-at91/board-neocore926.c +Automatic merge failed; fix conflicts and then commit the result. +$ git commit -v -a -+[master 6213a22] Merge remote branch 'arm-current/master' ++Recorded resolution for 'MAINTAINERS'. ++[master a4d2da8] Merge remote branch 'arm-current/master' +$ git diff -M --stat --summary HEAD^.. + arch/arm/common/vic.c | 1 + + arch/arm/include/asm/atomic.h | 26 ++---- @@ -56931,7 +57319,41 @@ index 0000000..e6936a7 +Already up-to-date. +Merging powerpc-merge/merge +$ git merge powerpc-merge/merge -+Already up-to-date. ++Merge made by recursive. ++ arch/powerpc/Kconfig | 6 +++ ++ arch/powerpc/Makefile | 11 +++++ ++ arch/powerpc/include/asm/device.h | 11 ++++- ++ arch/powerpc/include/asm/dma-mapping.h | 27 ++++++++++- ++ arch/powerpc/include/asm/iommu.h | 10 ++++ ++ arch/powerpc/include/asm/pmc.h | 2 +- ++ arch/powerpc/include/asm/pte-40x.h | 1 + ++ arch/powerpc/include/asm/pte-8xx.h | 1 + ++ arch/powerpc/include/asm/pte-common.h | 5 -- ++ arch/powerpc/kernel/dma-iommu.c | 16 +++--- ++ arch/powerpc/kernel/dma.c | 15 ++----- ++ arch/powerpc/kernel/exceptions-64e.S | 1 - ++ arch/powerpc/kernel/pci-common.c | 2 +- ++ arch/powerpc/kernel/process.c | 17 +++++++- ++ arch/powerpc/kernel/prom_init.c | 3 +- ++ arch/powerpc/kernel/vdso.c | 14 ++++-- ++ arch/powerpc/kernel/vio.c | 4 +- ++ arch/powerpc/kernel/vmlinux.lds.S | 69 ++++++----------------------- ++ arch/powerpc/mm/pgtable.c | 19 +++++++- ++ arch/powerpc/mm/tlb_low_64e.S | 1 - ++ arch/powerpc/platforms/cell/beat_iommu.c | 2 +- ++ arch/powerpc/platforms/cell/iommu.c | 9 +--- ++ arch/powerpc/platforms/iseries/iommu.c | 2 +- ++ arch/powerpc/platforms/pasemi/iommu.c | 2 +- ++ arch/powerpc/platforms/pseries/iommu.c | 8 ++-- ++ arch/powerpc/relocs_check.pl | 56 ++++++++++++++++++++++++ ++ arch/powerpc/sysdev/dart_iommu.c | 2 +- ++ arch/powerpc/xmon/xmon.c | 16 ++++++- ++ drivers/char/hvc_console.c | 6 +- ++ drivers/char/hvc_console.h | 12 +++++- ++ drivers/char/hvc_iucv.c | 4 +- ++ drivers/serial/cpm_uart/cpm_uart_core.c | 2 +- ++ 32 files changed, 237 insertions(+), 119 deletions(-) ++ create mode 100755 arch/powerpc/relocs_check.pl +Merging sparc-current/master +$ git merge sparc-current/master +Already up-to-date. @@ -56942,6 +57364,12 @@ index 0000000..e6936a7 +$ git merge net-current/master +Resolved 'drivers/staging/Kconfig' using previous resolution. +Resolved 'drivers/staging/Makefile' using previous resolution. ++Auto-merging arch/arm/mach-at91/at91sam9263_devices.c ++Auto-merging arch/arm/mach-at91/board-sam9263ek.c ++Auto-merging arch/arm/mach-at91/include/mach/board.h ++Auto-merging drivers/net/Kconfig ++Auto-merging drivers/net/sky2.c ++Auto-merging drivers/net/tun.c +Auto-merging drivers/staging/Kconfig +CONFLICT (content): Merge conflict in drivers/staging/Kconfig +Auto-merging drivers/staging/Makefile @@ -56956,6 +57384,7 @@ index 0000000..e6936a7 +Removing drivers/staging/cpc-usb/sja2m16c.h +Removing drivers/staging/cpc-usb/sja2m16c_2.c +Auto-merging kernel/sys_ni.c ++Auto-merging lib/vsprintf.c +Automatic merge failed; fix conflicts and then commit the result. +$ git rm -f drivers/staging/cpc-usb/TODO drivers/staging/cpc-usb/cpc-usb_drv.c drivers/staging/cpc-usb/cpc.h drivers/staging/cpc-usb/cpc_int.h drivers/staging/cpc-usb/cpcusb.h +drivers/staging/Kconfig: needs merge @@ -56971,33 +57400,91 @@ index 0000000..e6936a7 +rm 'drivers/staging/cpc-usb/cpc_int.h' +rm 'drivers/staging/cpc-usb/cpcusb.h' +$ git commit -v -a -+[master 3a6f9f6] Merge remote branch 'net-current/master' ++[master 1d4a13c] Merge remote branch 'net-current/master' +$ git diff -M --stat --summary HEAD^.. -+ drivers/net/can/Kconfig | 7 + -+ drivers/net/can/Makefile | 2 + -+ drivers/net/can/usb/Makefile | 5 + -+ drivers/net/can/usb/ems_usb.c | 1155 ++++++++++++++++++++++++++++++++ -+ drivers/net/cpmac.c | 8 +- -+ drivers/net/igb/e1000_mac.c | 72 +- -+ drivers/net/igb/e1000_mac.h | 1 - -+ drivers/net/ixgbe/ixgbe.h | 6 +- -+ drivers/net/ixgbe/ixgbe_ethtool.c | 75 ++- -+ drivers/net/ixgbe/ixgbe_main.c | 111 ++-- -+ drivers/staging/Kconfig | 2 - -+ drivers/staging/Makefile | 1 - -+ drivers/staging/cpc-usb/Kconfig | 4 - -+ drivers/staging/cpc-usb/Makefile | 3 - -+ drivers/staging/cpc-usb/TODO | 10 - -+ drivers/staging/cpc-usb/cpc-usb_drv.c | 1184 --------------------------------- -+ drivers/staging/cpc-usb/cpc.h | 417 ------------ -+ drivers/staging/cpc-usb/cpc_int.h | 83 --- -+ drivers/staging/cpc-usb/cpcusb.h | 86 --- -+ drivers/staging/cpc-usb/sja2m16c.h | 41 -- -+ drivers/staging/cpc-usb/sja2m16c_2.c | 452 ------------- -+ kernel/sys_ni.c | 1 + -+ 22 files changed, 1342 insertions(+), 2384 deletions(-) ++ arch/arm/mach-at91/at91sam9263_devices.c | 36 + ++ arch/arm/mach-at91/board-sam9263ek.c | 19 + ++ arch/arm/mach-at91/include/mach/board.h | 6 + ++ drivers/atm/he.c | 59 ++- ++ drivers/atm/solos-attrlist.c | 11 + ++ drivers/atm/solos-pci.c | 75 ++- ++ drivers/net/8139cp.c | 2 +- ++ drivers/net/Kconfig | 2 +- ++ drivers/net/atl1c/atl1c_main.c | 2 +- ++ drivers/net/can/Kconfig | 13 + ++ drivers/net/can/Makefile | 3 + ++ drivers/net/can/usb/Makefile | 5 + ++ drivers/net/can/usb/ems_usb.c | 1155 ++++++++++++++++++++++++++ ++ drivers/net/cnic.c | 4 +- ++ drivers/net/cpmac.c | 8 +- ++ drivers/net/ehea/ehea_main.c | 1 - ++ drivers/net/igb/e1000_mac.c | 72 +- ++ drivers/net/igb/e1000_mac.h | 1 - ++ drivers/net/ixgbe/ixgbe.h | 6 +- ++ drivers/net/ixgbe/ixgbe_ethtool.c | 75 ++- ++ drivers/net/ixgbe/ixgbe_main.c | 111 ++- ++ drivers/net/netxen/netxen_nic_main.c | 8 +- ++ drivers/net/pcmcia/pcnet_cs.c | 11 +- ++ drivers/net/sky2.c | 4 +- ++ drivers/net/sunvnet.c | 1 - ++ drivers/net/tun.c | 4 +- ++ drivers/net/usb/kaweth.c | 18 +- ++ drivers/net/usb/smsc95xx.c | 67 ++- ++ drivers/net/usb/usbnet.c | 2 +- ++ drivers/net/wireless/ath/ar9170/usb.c | 2 + ++ drivers/net/wireless/ath/ath9k/calib.c | 23 +- ++ drivers/net/wireless/ath/ath9k/calib.h | 1 + ++ drivers/net/wireless/ath/ath9k/eeprom_def.c | 4 +- ++ drivers/net/wireless/ath/ath9k/hw.c | 202 +++-- ++ drivers/net/wireless/ath/ath9k/hw.h | 4 +- ++ drivers/net/wireless/ath/ath9k/main.c | 16 +- ++ drivers/net/wireless/ath/ath9k/reg.h | 3 +- ++ drivers/net/wireless/b43/Kconfig | 21 +- ++ drivers/net/wireless/b43/Makefile | 1 + ++ drivers/net/wireless/b43/b43.h | 23 +- ++ drivers/net/wireless/b43/debugfs.c | 1 + ++ drivers/net/wireless/b43/debugfs.h | 1 + ++ drivers/net/wireless/b43/dma.c | 4 +- ++ drivers/net/wireless/b43/leds.c | 266 +++++-- ++ drivers/net/wireless/b43/leds.h | 33 +- ++ drivers/net/wireless/b43/main.c | 224 +++--- ++ drivers/net/wireless/b43/phy_lp.c | 12 +- ++ drivers/net/wireless/b43/pio.c | 2 +- ++ drivers/net/wireless/b43/rfkill.c | 2 +- ++ drivers/net/wireless/b43/sdio.c | 202 +++++ ++ drivers/net/wireless/b43/sdio.h | 45 + ++ drivers/net/wireless/b43/xmit.c | 5 +- ++ drivers/net/wireless/iwlwifi/iwl-4965.c | 6 + ++ drivers/net/wireless/iwlwifi/iwl-5000.c | 6 + ++ drivers/net/wireless/iwlwifi/iwl-rx.c | 10 +- ++ drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- ++ drivers/net/wireless/iwlwifi/iwl3945-base.c | 9 +- ++ drivers/net/wireless/rt2x00/rt2x00lib.h | 2 +- ++ drivers/net/wireless/wl12xx/Kconfig | 2 +- ++ drivers/net/wireless/zd1211rw/zd_usb.c | 2 +- ++ drivers/net/xilinx_emaclite.c | 7 +- ++ drivers/staging/Kconfig | 2 - ++ drivers/staging/Makefile | 1 - ++ drivers/staging/cpc-usb/Kconfig | 4 - ++ drivers/staging/cpc-usb/Makefile | 3 - ++ drivers/staging/cpc-usb/TODO | 10 - ++ drivers/staging/cpc-usb/cpc-usb_drv.c | 1184 --------------------------- ++ drivers/staging/cpc-usb/cpc.h | 417 ---------- ++ drivers/staging/cpc-usb/cpc_int.h | 83 -- ++ drivers/staging/cpc-usb/cpcusb.h | 86 -- ++ drivers/staging/cpc-usb/sja2m16c.h | 41 - ++ drivers/staging/cpc-usb/sja2m16c_2.c | 452 ---------- ++ include/linux/usb/usbnet.h | 1 + ++ kernel/sys_ni.c | 1 + ++ lib/vsprintf.c | 25 +- ++ net/ax25/af_ax25.c | 4 +- ++ net/mac80211/scan.c | 4 +- ++ net/wireless/wext-sme.c | 2 +- ++ 78 files changed, 2488 insertions(+), 2756 deletions(-) + create mode 100644 drivers/net/can/usb/Makefile + create mode 100644 drivers/net/can/usb/ems_usb.c ++ create mode 100644 drivers/net/wireless/b43/sdio.c ++ create mode 100644 drivers/net/wireless/b43/sdio.h + delete mode 100644 drivers/staging/cpc-usb/Kconfig + delete mode 100644 drivers/staging/cpc-usb/Makefile + delete mode 100644 drivers/staging/cpc-usb/TODO @@ -57027,10 +57514,10 @@ index 0000000..e6936a7 +Already up-to-date. +Merging quilt/usb.current +$ git merge quilt/usb.current -+Recorded preimage for 'drivers/usb/host/xhci-hcd.c' -+Recorded preimage for 'drivers/usb/host/xhci-mem.c' -+Recorded preimage for 'drivers/usb/host/xhci-ring.c' -+Recorded preimage for 'drivers/usb/host/xhci.h' ++Resolved 'drivers/usb/host/xhci-hcd.c' using previous resolution. ++Resolved 'drivers/usb/host/xhci-mem.c' using previous resolution. ++Resolved 'drivers/usb/host/xhci-ring.c' using previous resolution. ++Resolved 'drivers/usb/host/xhci.h' using previous resolution. +Auto-merging drivers/usb/host/xhci-hcd.c +CONFLICT (content): Merge conflict in drivers/usb/host/xhci-hcd.c +Auto-merging drivers/usb/host/xhci-mem.c @@ -57044,11 +57531,7 @@ index 0000000..e6936a7 +Auto-merging drivers/usb/serial/pl2303.c +Automatic merge failed; fix conflicts and then commit the result. +$ git commit -v -a -+Recorded resolution for 'drivers/usb/host/xhci-hcd.c'. -+Recorded resolution for 'drivers/usb/host/xhci-mem.c'. -+Recorded resolution for 'drivers/usb/host/xhci-ring.c'. -+Recorded resolution for 'drivers/usb/host/xhci.h'. -+[master 3a6e758] Merge branch 'quilt/usb.current' ++[master c19e97c] Merge branch 'quilt/usb.current' +$ git diff -M --stat --summary HEAD^.. +Merging cpufreq-current/fixes +$ git merge cpufreq-current/fixes @@ -57058,103 +57541,7 @@ index 0000000..e6936a7 +Already up-to-date. +Merging md-current/for-linus +$ git merge md-current/for-linus -+Removing drivers/dma/ioat.c -+Removing drivers/dma/ioat_dma.c -+Removing drivers/dma/ioatdma.h -+Removing drivers/dma/ioatdma_hw.h -+Auto-merging drivers/mmc/host/atmel-mci.c -+Auto-merging include/linux/pci_ids.h -+Merge made by recursive. -+ Documentation/crypto/async-tx-api.txt | 75 +- -+ arch/arm/include/asm/hardware/iop3xx-adma.h | 81 +- -+ arch/arm/include/asm/hardware/iop_adma.h | 3 + -+ arch/arm/mach-iop13xx/include/mach/adma.h | 119 ++- -+ arch/arm/mach-iop13xx/setup.c | 17 +- -+ arch/arm/plat-iop/adma.c | 4 +- -+ arch/powerpc/include/asm/fsldma.h | 136 ++ -+ arch/sh/drivers/dma/Kconfig | 12 +- -+ arch/sh/drivers/dma/Makefile | 3 +- -+ arch/sh/include/asm/dma-sh.h | 13 + -+ crypto/async_tx/Kconfig | 9 + -+ crypto/async_tx/Makefile | 3 + -+ crypto/async_tx/async_memcpy.c | 44 +- -+ crypto/async_tx/async_memset.c | 43 +- -+ crypto/async_tx/async_pq.c | 395 +++++ -+ crypto/async_tx/async_raid6_recov.c | 468 ++++++ -+ crypto/async_tx/async_tx.c | 87 +- -+ crypto/async_tx/async_xor.c | 207 ++-- -+ crypto/async_tx/raid6test.c | 240 +++ -+ drivers/dca/dca-core.c | 124 ++- -+ drivers/dma/Kconfig | 14 +- -+ drivers/dma/Makefile | 4 +- -+ drivers/dma/at_hdmac.c | 60 +- -+ drivers/dma/at_hdmac_regs.h | 1 + -+ drivers/dma/dmaengine.c | 94 +- -+ drivers/dma/dmatest.c | 40 + -+ drivers/dma/dw_dmac.c | 50 +- -+ drivers/dma/dw_dmac_regs.h | 1 + -+ drivers/dma/fsldma.c | 288 +++- -+ drivers/dma/fsldma.h | 4 +- -+ drivers/dma/ioat.c | 202 --- -+ drivers/dma/ioat/Makefile | 2 + -+ drivers/dma/{ioat_dca.c => ioat/dca.c} | 13 +- -+ drivers/dma/ioat/dma.c | 1238 ++++++++++++++ -+ drivers/dma/ioat/dma.h | 337 ++++ -+ drivers/dma/ioat/dma_v2.c | 871 ++++++++++ -+ drivers/dma/ioat/dma_v2.h | 190 +++ -+ drivers/dma/ioat/dma_v3.c | 1223 ++++++++++++++ -+ drivers/dma/ioat/hw.h | 215 +++ -+ drivers/dma/ioat/pci.c | 210 +++ -+ .../dma/{ioatdma_registers.h => ioat/registers.h} | 54 +- -+ drivers/dma/ioat_dma.c | 1741 -------------------- -+ drivers/dma/ioatdma.h | 165 -- -+ drivers/dma/ioatdma_hw.h | 70 - -+ drivers/dma/iop-adma.c | 491 +++++- -+ drivers/dma/iovlock.c | 10 + -+ drivers/dma/mv_xor.c | 7 +- -+ drivers/dma/mv_xor.h | 4 +- -+ drivers/dma/shdma.c | 786 +++++++++ -+ drivers/dma/shdma.h | 64 + -+ drivers/dma/txx9dmac.c | 24 +- -+ drivers/dma/txx9dmac.h | 1 + -+ drivers/idle/i7300_idle.c | 20 +- -+ drivers/md/Kconfig | 26 + -+ drivers/md/bitmap.c | 5 +- -+ drivers/md/linear.c | 3 + -+ drivers/md/md.c | 25 +- -+ drivers/md/md.h | 1 + -+ drivers/md/multipath.c | 6 +- -+ drivers/md/raid0.c | 8 +- -+ drivers/md/raid1.c | 15 +- -+ drivers/md/raid10.c | 12 +- -+ drivers/md/raid5.c | 1493 +++++++++++------- -+ drivers/md/raid5.h | 28 +- -+ drivers/mmc/host/atmel-mci.c | 9 +- -+ include/linux/async_tx.h | 129 ++- -+ include/linux/dca.h | 11 +- -+ include/linux/dmaengine.h | 179 ++- -+ include/linux/pci_ids.h | 10 + -+ 69 files changed, 9199 insertions(+), 3338 deletions(-) -+ create mode 100644 arch/powerpc/include/asm/fsldma.h -+ create mode 100644 crypto/async_tx/async_pq.c -+ create mode 100644 crypto/async_tx/async_raid6_recov.c -+ create mode 100644 crypto/async_tx/raid6test.c -+ delete mode 100644 drivers/dma/ioat.c -+ create mode 100644 drivers/dma/ioat/Makefile -+ rename drivers/dma/{ioat_dca.c => ioat/dca.c} (98%) -+ create mode 100644 drivers/dma/ioat/dma.c -+ create mode 100644 drivers/dma/ioat/dma.h -+ create mode 100644 drivers/dma/ioat/dma_v2.c -+ create mode 100644 drivers/dma/ioat/dma_v2.h -+ create mode 100644 drivers/dma/ioat/dma_v3.c -+ create mode 100644 drivers/dma/ioat/hw.h -+ create mode 100644 drivers/dma/ioat/pci.c -+ rename drivers/dma/{ioatdma_registers.h => ioat/registers.h} (84%) -+ delete mode 100644 drivers/dma/ioat_dma.c -+ delete mode 100644 drivers/dma/ioatdma.h -+ delete mode 100644 drivers/dma/ioatdma_hw.h -+ create mode 100644 drivers/dma/shdma.c -+ create mode 100644 drivers/dma/shdma.h ++Already up-to-date. +Merging audit-current/for-linus +$ git merge audit-current/for-linus +Already up-to-date. @@ -57354,9 +57741,10 @@ index 0000000..e6936a7 +Merging blackfin/for-linus +$ git merge blackfin/for-linus +Merge made by recursive. -+ arch/blackfin/Kconfig | 10 ++++--- -+ arch/blackfin/kernel/time.c | 63 +----------------------------------------- -+ 2 files changed, 8 insertions(+), 65 deletions(-) ++ arch/blackfin/Kconfig | 10 +++-- ++ arch/blackfin/kernel/time.c | 63 +------------------------------ ++ arch/blackfin/mach-bf548/boards/ezkit.c | 1 - ++ 3 files changed, 8 insertions(+), 66 deletions(-) +Merging cris/for-next +$ git merge cris/for-next +Auto-merging arch/cris/kernel/vmlinux.lds.S @@ -57381,14 +57769,13 @@ index 0000000..e6936a7 +Already up-to-date. +Merging m68k/for-next +$ git merge m68k/for-next -+Recorded preimage for 'drivers/rtc/Kconfig' ++Resolved 'drivers/rtc/Kconfig' using previous resolution. +Auto-merging drivers/rtc/Kconfig +CONFLICT (content): Merge conflict in drivers/rtc/Kconfig +Auto-merging drivers/rtc/Makefile +Automatic merge failed; fix conflicts and then commit the result. +$ git commit -v -a -+Recorded resolution for 'drivers/rtc/Kconfig'. -+[master ed66948] Merge remote branch 'm68k/for-next' ++[master 04e24bf] Merge remote branch 'm68k/for-next' +$ git diff -M --stat --summary HEAD^.. + drivers/rtc/Kconfig | 19 +++ + drivers/rtc/Makefile | 2 + @@ -57406,45 +57793,7 @@ index 0000000..e6936a7 + 3 files changed, 29 insertions(+), 3 deletions(-) +Merging microblaze/next +$ git merge microblaze/next -+Removing arch/microblaze/include/asm/ipc.h -+Auto-merging arch/microblaze/mm/init.c -+Auto-merging drivers/mtd/Kconfig -+Auto-merging drivers/mtd/maps/Kconfig -+Auto-merging drivers/usb/Kconfig -+Merge made by recursive. -+ arch/microblaze/Kconfig | 1 + -+ arch/microblaze/Makefile | 31 ++++++-- -+ arch/microblaze/boot/Makefile | 41 ++++++++++- -+ arch/microblaze/boot/dts/system.dts | 1 + -+ arch/microblaze/boot/linked_dtb.S | 3 + -+ arch/microblaze/configs/mmu_defconfig | 2 +- -+ arch/microblaze/configs/nommu_defconfig | 2 +- -+ arch/microblaze/include/asm/asm-compat.h | 17 ++++ -+ arch/microblaze/include/asm/io.h | 3 + -+ arch/microblaze/include/asm/ipc.h | 1 - -+ arch/microblaze/include/asm/page.h | 3 + -+ arch/microblaze/include/asm/setup.h | 2 +- -+ arch/microblaze/include/asm/syscall.h | 99 +++++++++++++++++++++++++ -+ arch/microblaze/kernel/cpu/cpuinfo.c | 3 + -+ arch/microblaze/kernel/entry.S | 72 +++++++++++++++--- -+ arch/microblaze/kernel/exceptions.c | 33 +++++--- -+ arch/microblaze/kernel/head.S | 14 +++- -+ arch/microblaze/kernel/hw_exception_handler.S | 10 ++- -+ arch/microblaze/kernel/process.c | 1 + -+ arch/microblaze/kernel/ptrace.c | 62 +++++++++++++++ -+ arch/microblaze/kernel/setup.c | 12 +++- -+ arch/microblaze/kernel/vmlinux.lds.S | 72 +++++++----------- -+ arch/microblaze/mm/init.c | 3 +- -+ drivers/mtd/Kconfig | 2 +- -+ drivers/mtd/maps/Kconfig | 2 +- -+ drivers/usb/Kconfig | 1 - -+ kernel/gcov/Kconfig | 2 +- -+ 27 files changed, 404 insertions(+), 91 deletions(-) -+ create mode 120000 arch/microblaze/boot/dts/system.dts -+ create mode 100644 arch/microblaze/boot/linked_dtb.S -+ create mode 100644 arch/microblaze/include/asm/asm-compat.h -+ delete mode 100644 arch/microblaze/include/asm/ipc.h -+ create mode 100644 arch/microblaze/include/asm/syscall.h ++Already up-to-date. +Merging mips/mips-for-linux-next +$ git merge mips/mips-for-linux-next +Resolved 'arch/mips/Kconfig' using previous resolution. @@ -57455,12 +57804,14 @@ index 0000000..e6936a7 +Auto-merging arch/mips/Kconfig +CONFLICT (content): Merge conflict in arch/mips/Kconfig +Auto-merging arch/mips/Makefile ++Auto-merging arch/mips/alchemy/common/time.c +Auto-merging arch/mips/bcm63xx/Makefile +CONFLICT (add/add): Merge conflict in arch/mips/bcm63xx/Makefile +Auto-merging arch/mips/bcm63xx/boards/board_bcm963xx.c +CONFLICT (add/add): Merge conflict in arch/mips/bcm63xx/boards/board_bcm963xx.c +Auto-merging arch/mips/kernel/scall32-o32.S +Auto-merging arch/mips/kernel/scall64-64.S ++Auto-merging arch/mips/kernel/smtc.c +Auto-merging arch/mips/kernel/vmlinux.lds.S +CONFLICT (delete/modify): arch/mips/lemote/lm2e/Makefile deleted in HEAD and modified in mips/mips-for-linux-next. Version mips/mips-for-linux-next of arch/mips/lemote/lm2e/Makefile left in tree. +CONFLICT (delete/modify): arch/mips/lemote/lm2e/pci.c deleted in HEAD and modified in mips/mips-for-linux-next. Version mips/mips-for-linux-next of arch/mips/lemote/lm2e/pci.c left in tree. @@ -57479,7 +57830,7 @@ index 0000000..e6936a7 +rm 'arch/mips/lemote/lm2e/pci.c' +rm 'arch/mips/lemote/lm2e/prom.c' +$ git commit -v -a -+[master e416680] Merge remote branch 'mips/mips-for-linux-next' ++[master 38f5aeb] Merge remote branch 'mips/mips-for-linux-next' +$ git diff -M --stat --summary HEAD^.. + arch/mips/lemote/lm2e/early_printk.c | 41 ++++++++++++++++++++++++++++++++++ + 1 files changed, 41 insertions(+), 0 deletions(-) @@ -57500,7 +57851,7 @@ index 0000000..e6936a7 +CONFLICT (content): Merge conflict in arch/parisc/kernel/signal.c +Automatic merge failed; fix conflicts and then commit the result. +$ git commit -v -a -+[master 8538de0] Merge remote branch 'parisc/next' ++[master 1a8d6a4] Merge remote branch 'parisc/next' +$ git diff -M --stat --summary HEAD^.. + MAINTAINERS | 1 + + arch/parisc/Kconfig | 1 + @@ -57529,10 +57880,22 @@ index 0000000..e6936a7 +Already up-to-date. +Merging s390/features +$ git merge s390/features -+Already up-to-date. ++Merge made by recursive. ++ arch/s390/include/asm/delay.h | 7 ++++--- ++ arch/s390/kernel/compat_wrapper.S | 2 +- ++ arch/s390/kernel/ftrace.c | 3 --- ++ arch/s390/lib/delay.c | 27 ++++++++++++++++----------- ++ drivers/s390/cio/device.c | 4 ++-- ++ drivers/s390/cio/device.h | 1 + ++ drivers/s390/cio/device_fsm.c | 31 +++++++++++++++++++++++-------- ++ 7 files changed, 47 insertions(+), 28 deletions(-) +Merging sh/master +$ git merge sh/master -+Already up-to-date. ++Merge made by recursive. ++ arch/sh/boards/mach-ecovec24/setup.c | 1 + ++ arch/sh/kernel/dwarf.c | 1 - ++ arch/sh/kernel/traps_32.c | 23 ++++++++++++++--------- ++ 3 files changed, 15 insertions(+), 10 deletions(-) +Merging sparc/master +$ git merge sparc/master +Already up-to-date. @@ -57542,13 +57905,19 @@ index 0000000..e6936a7 +Merge made by recursive. +Merging cifs/master +$ git merge cifs/master ++Auto-merging fs/cifs/cifsfs.c +Merge made by recursive. -+ fs/cifs/cifsglob.h | 9 +++++---- -+ fs/cifs/cifsproto.h | 2 +- -+ fs/cifs/dir.c | 11 +++++------ -+ fs/cifs/file.c | 16 ++++++++++------ -+ fs/cifs/misc.c | 7 +++---- -+ 5 files changed, 24 insertions(+), 21 deletions(-) ++ fs/cifs/Kconfig | 1 + ++ fs/cifs/cifsfs.c | 95 ++---------------------------------------- ++ fs/cifs/cifsglob.h | 21 ++++----- ++ fs/cifs/cifsproto.h | 11 ++--- ++ fs/cifs/cifssmb.c | 1 + ++ fs/cifs/connect.c | 1 - ++ fs/cifs/dir.c | 64 +++++++++++++--------------- ++ fs/cifs/file.c | 115 ++++++++++++++++++++++++++++++++++++--------------- ++ fs/cifs/misc.c | 34 ++++++++++----- ++ fs/cifs/transport.c | 50 ---------------------- ++ 10 files changed, 155 insertions(+), 238 deletions(-) +Merging configfs/linux-next +$ git merge configfs/linux-next +Already up-to-date. @@ -57580,7 +57949,9 @@ index 0000000..e6936a7 +Merge made by recursive. +Merging fatfs/master +$ git merge fatfs/master ++Auto-merging fs/fat/inode.c +Auto-merging fs/fat/misc.c ++Auto-merging fs/nls/nls_base.c +Merge made by recursive. + Documentation/filesystems/vfat.txt | 2 +- + fs/fat/fat.h | 2 +- @@ -57634,46 +58005,25 @@ index 0000000..e6936a7 +Merging vfs/for-next +$ git merge vfs/for-next +Already up-to-date. ++$ git revert 086f68bd97126618ecb2dcff5f766f3a21722df7 ++Finished one revert. ++[master f0488c2] Revert "cifs: eliminate cifs_init_private" ++ 3 files changed, 50 insertions(+), 20 deletions(-) ++$ git revert 3bc303c254335dbd7c7012cc1760b12f1d5514d3 ++Finished one revert. ++[master 39e619d] Revert "cifs: convert oplock breaks to use slow_work facility (try #4)" ++ 10 files changed, 175 insertions(+), 119 deletions(-) +Merging pci/linux-next +$ git merge pci/linux-next -+Resolved 'MAINTAINERS' using previous resolution. -+Auto-merging MAINTAINERS -+CONFLICT (content): Merge conflict in MAINTAINERS -+Auto-merging include/linux/vgaarb.h -+Automatic merge failed; fix conflicts and then commit the result. -+$ git commit -v -a -+[master 281b080] Merge remote branch 'pci/linux-next' -+$ git diff -M --stat --summary HEAD^.. -+ MAINTAINERS | 18 +---- -+ arch/x86/include/asm/pci.h | 6 ++- -+ arch/x86/pci/common.c | 2 +- -+ drivers/pci/hotplug/pciehp.h | 107 ++++++++--------------------- -+ drivers/pci/hotplug/pciehp_acpi.c | 17 +++-- -+ drivers/pci/hotplug/pciehp_core.c | 136 +++++++++++++++++-------------------- -+ drivers/pci/hotplug/pciehp_ctrl.c | 109 ++++++++++++------------------ -+ drivers/pci/hotplug/pciehp_hpc.c | 109 +++++++++--------------------- -+ drivers/pci/hotplug/pciehp_pci.c | 23 +++--- -+ drivers/pci/pcie/aer/aerdrv.c | 2 + -+ drivers/pci/pcie/aspm.c | 3 - -+ include/linux/vgaarb.h | 3 +- -+ 12 files changed, 203 insertions(+), 332 deletions(-) ++Already up-to-date. +Merging hid/for-next +$ git merge hid/for-next +Already up-to-date. +Merging quilt/i2c +$ git merge quilt/i2c -+Auto-merging Documentation/feature-removal-schedule.txt +Removing Documentation/i2c/busses/i2c-voodoo3 -+Auto-merging MAINTAINERS -+Auto-merging drivers/gpio/pcf857x.c -+Auto-merging drivers/hwmon/ltc4215.c -+Auto-merging drivers/hwmon/ltc4245.c +Auto-merging drivers/i2c/busses/Kconfig -+Auto-merging drivers/i2c/busses/Makefile +Removing drivers/i2c/busses/i2c-voodoo3.c -+Auto-merging drivers/i2c/i2c-core.c -+Auto-merging include/linux/i2c.h -+Auto-merging include/linux/pci_ids.h +Merge made by recursive. + Documentation/feature-removal-schedule.txt | 9 - + Documentation/hwmon/ltc4215 | 7 +- @@ -57699,10 +58049,7 @@ index 0000000..e6936a7 + delete mode 100644 drivers/i2c/busses/i2c-voodoo3.c +Merging quilt/jdelvare-hwmon +$ git merge quilt/jdelvare-hwmon -+Auto-merging Documentation/feature-removal-schedule.txt -+Auto-merging drivers/hwmon/ltc4215.c -+Auto-merging drivers/hwmon/ltc4245.c -+Merge made by recursive. ++Already up-to-date. +Merging quilt/kernel-doc +$ git merge quilt/kernel-doc +Already up-to-date. @@ -57760,19 +58107,26 @@ index 0000000..e6936a7 +Already up-to-date. +Merging infiniband/for-next +$ git merge infiniband/for-next ++Auto-merging drivers/char/Kconfig ++Auto-merging drivers/char/Makefile ++Auto-merging drivers/infiniband/hw/nes/nes_nic.c +Auto-merging include/linux/Kbuild +Merge made by recursive. -+ Documentation/Makefile | 3 +- -+ Documentation/ummunotify/Makefile | 7 + -+ Documentation/ummunotify/ummunotify.txt | 150 ++++++++ -+ Documentation/ummunotify/umn-test.c | 200 +++++++++++ -+ drivers/char/Kconfig | 12 + -+ drivers/char/Makefile | 1 + -+ drivers/char/ummunotify.c | 566 +++++++++++++++++++++++++++++++ -+ drivers/infiniband/core/mad_rmpp.c | 17 +- -+ include/linux/Kbuild | 1 + -+ include/linux/ummunotify.h | 121 +++++++ -+ 10 files changed, 1073 insertions(+), 5 deletions(-) ++ Documentation/Makefile | 3 +- ++ Documentation/ummunotify/Makefile | 7 + ++ Documentation/ummunotify/ummunotify.txt | 150 +++++++ ++ Documentation/ummunotify/umn-test.c | 200 +++++++++ ++ drivers/char/Kconfig | 12 + ++ drivers/char/Makefile | 1 + ++ drivers/char/ummunotify.c | 566 ++++++++++++++++++++++++ ++ drivers/infiniband/core/mad_rmpp.c | 17 +- ++ drivers/infiniband/hw/mthca/mthca_catas.c | 11 +- ++ drivers/infiniband/hw/nes/nes_nic.c | 1 - ++ drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 7 + ++ drivers/net/mlx4/fw.c | 5 + ++ include/linux/Kbuild | 1 + ++ include/linux/ummunotify.h | 121 +++++ ++ 14 files changed, 1093 insertions(+), 9 deletions(-) + create mode 100644 Documentation/ummunotify/Makefile + create mode 100644 Documentation/ummunotify/ummunotify.txt + create mode 100644 Documentation/ummunotify/umn-test.c @@ -57780,7 +58134,14 @@ index 0000000..e6936a7 + create mode 100644 include/linux/ummunotify.h +Merging acpi/test +$ git merge acpi/test -+Already up-to-date. ++Merge made by recursive. ++ Documentation/laptops/thinkpad-acpi.txt | 48 ++- ++ drivers/acpi/bus.c | 49 +-- ++ drivers/acpi/scan.c | 427 ++++++++++------------ ++ drivers/pci/hotplug/acpiphp_ibm.c | 1 - ++ drivers/platform/x86/thinkpad_acpi.c | 632 +++++++++++++++++++++---------- ++ include/acpi/acpi_bus.h | 6 +- ++ 6 files changed, 670 insertions(+), 493 deletions(-) +Merging ieee1394/for-next +$ git merge ieee1394/for-next +Already up-to-date. @@ -57791,6 +58152,7 @@ index 0000000..e6936a7 +$ git merge kvm/linux-next +Auto-merging arch/x86/kvm/x86.c +Auto-merging include/linux/kvm_host.h ++Auto-merging virt/kvm/kvm_main.c +Merge made by recursive. + arch/ia64/include/asm/kvm.h | 1 + + arch/ia64/include/asm/kvm_host.h | 1 - @@ -57824,18 +58186,458 @@ index 0000000..e6936a7 +Already up-to-date. +Merging scsi/master +$ git merge scsi/master ++Auto-merging MAINTAINERS +Auto-merging drivers/scsi/bnx2i/bnx2i_hwi.c ++Auto-merging drivers/scsi/fcoe/libfcoe.c ++Auto-merging drivers/scsi/sd.c ++Auto-merging drivers/scsi/sg.c ++Auto-merging drivers/scsi/sr.c +Merge made by recursive. -+ Documentation/scsi/hptiop.txt | 21 ++++++++++- -+ drivers/scsi/bnx2i/bnx2i.h | 2 + -+ drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- -+ drivers/scsi/device_handler/scsi_dh_rdac.c | 2 - -+ drivers/scsi/hptiop.c | 37 ++++++++++++----- -+ drivers/scsi/hptiop.h | 3 +- -+ drivers/scsi/mvsas/mv_defs.h | 4 ++ -+ drivers/scsi/mvsas/mv_init.c | 4 ++ -+ drivers/scsi/pmcraid.c | 58 +++++++++++++++------------- -+ 9 files changed, 90 insertions(+), 43 deletions(-) ++ Documentation/scsi/hptiop.txt | 21 +- ++ MAINTAINERS | 7 + ++ drivers/scsi/Kconfig | 10 + ++ drivers/scsi/Makefile | 1 + ++ drivers/scsi/bfa/Makefile | 15 + ++ drivers/scsi/bfa/bfa_callback_priv.h | 57 + ++ drivers/scsi/bfa/bfa_cb_ioim_macros.h | 205 ++ ++ drivers/scsi/bfa/bfa_cee.c | 492 ++++ ++ drivers/scsi/bfa/bfa_core.c | 402 +++ ++ drivers/scsi/bfa/bfa_csdebug.c | 58 + ++ drivers/scsi/bfa/bfa_fcpim.c | 175 ++ ++ drivers/scsi/bfa/bfa_fcpim_priv.h | 188 ++ ++ drivers/scsi/bfa/bfa_fcport.c | 1671 +++++++++++++ ++ drivers/scsi/bfa/bfa_fcs.c | 182 ++ ++ drivers/scsi/bfa/bfa_fcs_lport.c | 940 +++++++ ++ drivers/scsi/bfa/bfa_fcs_port.c | 68 + ++ drivers/scsi/bfa/bfa_fcs_uf.c | 105 + ++ drivers/scsi/bfa/bfa_fcxp.c | 782 ++++++ ++ drivers/scsi/bfa/bfa_fcxp_priv.h | 138 + ++ drivers/scsi/bfa/bfa_fwimg_priv.h | 31 + ++ drivers/scsi/bfa/bfa_hw_cb.c | 142 ++ ++ drivers/scsi/bfa/bfa_hw_ct.c | 162 ++ ++ drivers/scsi/bfa/bfa_intr.c | 218 ++ ++ drivers/scsi/bfa/bfa_intr_priv.h | 115 + ++ drivers/scsi/bfa/bfa_ioc.c | 2382 ++++++++++++++++++ ++ drivers/scsi/bfa/bfa_ioc.h | 259 ++ ++ drivers/scsi/bfa/bfa_iocfc.c | 872 +++++++ ++ drivers/scsi/bfa/bfa_iocfc.h | 168 ++ ++ drivers/scsi/bfa/bfa_iocfc_q.c | 44 + ++ drivers/scsi/bfa/bfa_ioim.c | 1311 ++++++++++ ++ drivers/scsi/bfa/bfa_itnim.c | 1088 ++++++++ ++ drivers/scsi/bfa/bfa_log.c | 346 +++ ++ drivers/scsi/bfa/bfa_log_module.c | 451 ++++ ++ drivers/scsi/bfa/bfa_lps.c | 782 ++++++ ++ drivers/scsi/bfa/bfa_lps_priv.h | 38 + ++ drivers/scsi/bfa/bfa_module.c | 90 + ++ drivers/scsi/bfa/bfa_modules_priv.h | 43 + ++ drivers/scsi/bfa/bfa_os_inc.h | 222 ++ ++ drivers/scsi/bfa/bfa_port.c | 460 ++++ ++ drivers/scsi/bfa/bfa_port_priv.h | 90 + ++ drivers/scsi/bfa/bfa_priv.h | 113 + ++ drivers/scsi/bfa/bfa_rport.c | 911 +++++++ ++ drivers/scsi/bfa/bfa_rport_priv.h | 45 + ++ drivers/scsi/bfa/bfa_sgpg.c | 231 ++ ++ drivers/scsi/bfa/bfa_sgpg_priv.h | 79 + ++ drivers/scsi/bfa/bfa_sm.c | 38 + ++ drivers/scsi/bfa/bfa_timer.c | 90 + ++ drivers/scsi/bfa/bfa_trcmod_priv.h | 66 + ++ drivers/scsi/bfa/bfa_tskim.c | 689 +++++ ++ drivers/scsi/bfa/bfa_uf.c | 345 +++ ++ drivers/scsi/bfa/bfa_uf_priv.h | 47 + ++ drivers/scsi/bfa/bfad.c | 1182 +++++++++ ++ drivers/scsi/bfa/bfad_attr.c | 649 +++++ ++ drivers/scsi/bfa/bfad_attr.h | 65 + ++ drivers/scsi/bfa/bfad_drv.h | 295 +++ ++ drivers/scsi/bfa/bfad_fwimg.c | 95 + ++ drivers/scsi/bfa/bfad_im.c | 1230 +++++++++ ++ drivers/scsi/bfa/bfad_im.h | 150 ++ ++ drivers/scsi/bfa/bfad_im_compat.h | 46 + ++ drivers/scsi/bfa/bfad_intr.c | 214 ++ ++ drivers/scsi/bfa/bfad_ipfc.h | 42 + ++ drivers/scsi/bfa/bfad_os.c | 50 + ++ drivers/scsi/bfa/bfad_tm.h | 59 + ++ drivers/scsi/bfa/bfad_trcmod.h | 52 + ++ drivers/scsi/bfa/fab.c | 62 + ++ drivers/scsi/bfa/fabric.c | 1278 ++++++++++ ++ drivers/scsi/bfa/fcbuild.c | 1449 +++++++++++ ++ drivers/scsi/bfa/fcbuild.h | 273 ++ ++ drivers/scsi/bfa/fcpim.c | 844 +++++++ ++ drivers/scsi/bfa/fcptm.c | 68 + ++ drivers/scsi/bfa/fcs.h | 30 + ++ drivers/scsi/bfa/fcs_auth.h | 37 + ++ drivers/scsi/bfa/fcs_fabric.h | 61 + ++ drivers/scsi/bfa/fcs_fcpim.h | 44 + ++ drivers/scsi/bfa/fcs_fcptm.h | 45 + ++ drivers/scsi/bfa/fcs_fcxp.h | 29 + ++ drivers/scsi/bfa/fcs_lport.h | 117 + ++ drivers/scsi/bfa/fcs_ms.h | 35 + ++ drivers/scsi/bfa/fcs_port.h | 32 + ++ drivers/scsi/bfa/fcs_rport.h | 61 + ++ drivers/scsi/bfa/fcs_trcmod.h | 56 + ++ drivers/scsi/bfa/fcs_uf.h | 32 + ++ drivers/scsi/bfa/fcs_vport.h | 39 + ++ drivers/scsi/bfa/fdmi.c | 1223 +++++++++ ++ drivers/scsi/bfa/include/aen/bfa_aen.h | 92 + ++ drivers/scsi/bfa/include/aen/bfa_aen_adapter.h | 31 + ++ drivers/scsi/bfa/include/aen/bfa_aen_audit.h | 31 + ++ drivers/scsi/bfa/include/aen/bfa_aen_ethport.h | 35 + ++ drivers/scsi/bfa/include/aen/bfa_aen_ioc.h | 37 + ++ drivers/scsi/bfa/include/aen/bfa_aen_itnim.h | 33 + ++ drivers/scsi/bfa/include/aen/bfa_aen_lport.h | 51 + ++ drivers/scsi/bfa/include/aen/bfa_aen_port.h | 57 + ++ drivers/scsi/bfa/include/aen/bfa_aen_rport.h | 37 + ++ drivers/scsi/bfa/include/bfa.h | 177 ++ ++ drivers/scsi/bfa/include/bfa_fcpim.h | 159 ++ ++ drivers/scsi/bfa/include/bfa_fcptm.h | 47 + ++ drivers/scsi/bfa/include/bfa_svc.h | 324 +++ ++ drivers/scsi/bfa/include/bfa_timer.h | 53 + ++ drivers/scsi/bfa/include/bfi/bfi.h | 174 ++ ++ drivers/scsi/bfa/include/bfi/bfi_boot.h | 34 + ++ drivers/scsi/bfa/include/bfi/bfi_cbreg.h | 305 +++ ++ drivers/scsi/bfa/include/bfi/bfi_cee.h | 119 + ++ drivers/scsi/bfa/include/bfi/bfi_ctreg.h | 611 +++++ ++ drivers/scsi/bfa/include/bfi/bfi_fabric.h | 92 + ++ drivers/scsi/bfa/include/bfi/bfi_fcpim.h | 301 +++ ++ drivers/scsi/bfa/include/bfi/bfi_fcxp.h | 71 + ++ drivers/scsi/bfa/include/bfi/bfi_ioc.h | 202 ++ ++ drivers/scsi/bfa/include/bfi/bfi_iocfc.h | 177 ++ ++ drivers/scsi/bfa/include/bfi/bfi_lport.h | 89 + ++ drivers/scsi/bfa/include/bfi/bfi_lps.h | 96 + ++ drivers/scsi/bfa/include/bfi/bfi_port.h | 115 + ++ drivers/scsi/bfa/include/bfi/bfi_pport.h | 184 ++ ++ drivers/scsi/bfa/include/bfi/bfi_rport.h | 104 + ++ drivers/scsi/bfa/include/bfi/bfi_uf.h | 52 + ++ drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h | 36 + ++ drivers/scsi/bfa/include/cna/cee/bfa_cee.h | 77 + ++ drivers/scsi/bfa/include/cna/port/bfa_port.h | 69 + ++ drivers/scsi/bfa/include/cna/pstats/ethport_defs.h | 36 + ++ drivers/scsi/bfa/include/cna/pstats/phyport_defs.h | 218 ++ ++ drivers/scsi/bfa/include/cs/bfa_checksum.h | 60 + ++ drivers/scsi/bfa/include/cs/bfa_debug.h | 44 + ++ drivers/scsi/bfa/include/cs/bfa_log.h | 184 ++ ++ drivers/scsi/bfa/include/cs/bfa_perf.h | 34 + ++ drivers/scsi/bfa/include/cs/bfa_plog.h | 162 ++ ++ drivers/scsi/bfa/include/cs/bfa_q.h | 81 + ++ drivers/scsi/bfa/include/cs/bfa_sm.h | 69 + ++ drivers/scsi/bfa/include/cs/bfa_trc.h | 176 ++ ++ drivers/scsi/bfa/include/cs/bfa_wc.h | 68 + ++ drivers/scsi/bfa/include/defs/bfa_defs_adapter.h | 82 + ++ drivers/scsi/bfa/include/defs/bfa_defs_aen.h | 73 + ++ drivers/scsi/bfa/include/defs/bfa_defs_audit.h | 38 + ++ drivers/scsi/bfa/include/defs/bfa_defs_auth.h | 112 + ++ drivers/scsi/bfa/include/defs/bfa_defs_boot.h | 71 + ++ drivers/scsi/bfa/include/defs/bfa_defs_cee.h | 159 ++ ++ drivers/scsi/bfa/include/defs/bfa_defs_driver.h | 40 + ++ drivers/scsi/bfa/include/defs/bfa_defs_ethport.h | 98 + ++ drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h | 45 + ++ drivers/scsi/bfa/include/defs/bfa_defs_im_common.h | 32 + ++ drivers/scsi/bfa/include/defs/bfa_defs_im_team.h | 72 + ++ drivers/scsi/bfa/include/defs/bfa_defs_ioc.h | 152 ++ ++ drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h | 310 +++ ++ drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h | 70 + ++ drivers/scsi/bfa/include/defs/bfa_defs_itnim.h | 126 + ++ drivers/scsi/bfa/include/defs/bfa_defs_led.h | 35 + ++ drivers/scsi/bfa/include/defs/bfa_defs_lport.h | 68 + ++ drivers/scsi/bfa/include/defs/bfa_defs_mfg.h | 58 + ++ drivers/scsi/bfa/include/defs/bfa_defs_pci.h | 41 + ++ drivers/scsi/bfa/include/defs/bfa_defs_pm.h | 33 + ++ drivers/scsi/bfa/include/defs/bfa_defs_pom.h | 56 + ++ drivers/scsi/bfa/include/defs/bfa_defs_port.h | 245 ++ ++ drivers/scsi/bfa/include/defs/bfa_defs_pport.h | 383 +++ ++ drivers/scsi/bfa/include/defs/bfa_defs_qos.h | 99 + ++ drivers/scsi/bfa/include/defs/bfa_defs_rport.h | 199 ++ ++ drivers/scsi/bfa/include/defs/bfa_defs_status.h | 255 ++ ++ drivers/scsi/bfa/include/defs/bfa_defs_tin.h | 118 + ++ drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h | 43 + ++ drivers/scsi/bfa/include/defs/bfa_defs_types.h | 30 + ++ drivers/scsi/bfa/include/defs/bfa_defs_version.h | 22 + ++ drivers/scsi/bfa/include/defs/bfa_defs_vf.h | 74 + ++ drivers/scsi/bfa/include/defs/bfa_defs_vport.h | 91 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb.h | 33 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h | 76 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb_port.h | 113 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h | 80 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h | 47 + ++ drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h | 47 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs.h | 73 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h | 82 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h | 112 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h | 131 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h | 63 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h | 226 ++ ++ drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h | 104 + ++ drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h | 63 + ++ drivers/scsi/bfa/include/log/bfa_log_fcs.h | 28 + ++ drivers/scsi/bfa/include/log/bfa_log_hal.h | 30 + ++ drivers/scsi/bfa/include/log/bfa_log_linux.h | 44 + ++ drivers/scsi/bfa/include/log/bfa_log_wdrv.h | 36 + ++ drivers/scsi/bfa/include/protocol/ct.h | 492 ++++ ++ drivers/scsi/bfa/include/protocol/fc.h | 1105 +++++++++ ++ drivers/scsi/bfa/include/protocol/fc_sp.h | 224 ++ ++ drivers/scsi/bfa/include/protocol/fcp.h | 186 ++ ++ drivers/scsi/bfa/include/protocol/fdmi.h | 163 ++ ++ drivers/scsi/bfa/include/protocol/pcifw.h | 75 + ++ drivers/scsi/bfa/include/protocol/scsi.h | 1648 ++++++++++++ ++ drivers/scsi/bfa/include/protocol/types.h | 42 + ++ drivers/scsi/bfa/loop.c | 422 ++++ ++ drivers/scsi/bfa/lport_api.c | 291 +++ ++ drivers/scsi/bfa/lport_priv.h | 82 + ++ drivers/scsi/bfa/ms.c | 759 ++++++ ++ drivers/scsi/bfa/n2n.c | 105 + ++ drivers/scsi/bfa/ns.c | 1243 ++++++++++ ++ drivers/scsi/bfa/plog.c | 184 ++ ++ drivers/scsi/bfa/rport.c | 2618 ++++++++++++++++++++ ++ drivers/scsi/bfa/rport_api.c | 180 ++ ++ drivers/scsi/bfa/rport_ftrs.c | 375 +++ ++ drivers/scsi/bfa/scn.c | 482 ++++ ++ drivers/scsi/bfa/vfapi.c | 292 +++ ++ drivers/scsi/bfa/vport.c | 891 +++++++ ++ drivers/scsi/bnx2i/bnx2i.h | 2 + ++ drivers/scsi/bnx2i/bnx2i_hwi.c | 2 +- ++ drivers/scsi/device_handler/scsi_dh_rdac.c | 2 - ++ drivers/scsi/fcoe/fcoe.c | 1073 ++++++--- ++ drivers/scsi/fcoe/fcoe.h | 76 +- ++ drivers/scsi/fcoe/libfcoe.c | 288 ++- ++ drivers/scsi/fnic/fnic_main.c | 10 +- ++ drivers/scsi/hptiop.c | 37 +- ++ drivers/scsi/hptiop.h | 3 +- ++ drivers/scsi/libfc/Makefile | 4 +- ++ drivers/scsi/libfc/fc_disc.c | 2 + ++ drivers/scsi/libfc/fc_elsct.c | 3 +- ++ drivers/scsi/libfc/fc_exch.c | 361 ++-- ++ drivers/scsi/libfc/fc_fcp.c | 180 +- ++ drivers/scsi/libfc/fc_frame.c | 7 +- ++ drivers/scsi/libfc/fc_libfc.c | 134 + ++ drivers/scsi/libfc/fc_libfc.h | 112 + ++ drivers/scsi/libfc/fc_lport.c | 550 +++-- ++ drivers/scsi/libfc/fc_npiv.c | 161 ++ ++ drivers/scsi/libfc/fc_rport.c | 6 +- ++ drivers/scsi/lpfc/lpfc_scsi.c | 15 +- ++ drivers/scsi/mvsas/mv_defs.h | 4 + ++ drivers/scsi/mvsas/mv_init.c | 4 + ++ drivers/scsi/pmcraid.c | 58 +- ++ drivers/scsi/scsi.c | 11 +- ++ drivers/scsi/scsi_debug.c | 139 +- ++ drivers/scsi/scsi_error.c | 3 + ++ drivers/scsi/scsi_transport_fc.c | 2 + ++ drivers/scsi/sd.c | 140 +- ++ drivers/scsi/sd.h | 9 +- ++ drivers/scsi/sd_dif.c | 65 - ++ drivers/scsi/sg.c | 10 +- ++ drivers/scsi/sr.c | 22 +- ++ include/scsi/Kbuild | 1 + ++ include/scsi/fc/Kbuild | 4 + ++ include/scsi/fc/fc_els.h | 6 +- ++ include/scsi/fc/fc_fs.h | 2 + ++ include/scsi/fc/fc_gs.h | 2 + ++ include/scsi/fc/fc_ns.h | 22 + ++ include/scsi/fc_encode.h | 54 +- ++ include/scsi/fc_frame.h | 3 + ++ include/scsi/libfc.h | 200 +-- ++ include/scsi/libfcoe.h | 89 +- ++ include/scsi/scsi.h | 3 + ++ include/scsi/scsi_cmnd.h | 4 - ++ include/scsi/scsi_host.h | 15 +- ++ 245 files changed, 51778 insertions(+), 1332 deletions(-) ++ create mode 100644 drivers/scsi/bfa/Makefile ++ create mode 100644 drivers/scsi/bfa/bfa_callback_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_cb_ioim_macros.h ++ create mode 100644 drivers/scsi/bfa/bfa_cee.c ++ create mode 100644 drivers/scsi/bfa/bfa_core.c ++ create mode 100644 drivers/scsi/bfa/bfa_csdebug.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcpim.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcpim_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_fcport.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcs.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcs_lport.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcs_port.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcs_uf.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcxp.c ++ create mode 100644 drivers/scsi/bfa/bfa_fcxp_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_fwimg_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_hw_cb.c ++ create mode 100644 drivers/scsi/bfa/bfa_hw_ct.c ++ create mode 100644 drivers/scsi/bfa/bfa_intr.c ++ create mode 100644 drivers/scsi/bfa/bfa_intr_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_ioc.c ++ create mode 100644 drivers/scsi/bfa/bfa_ioc.h ++ create mode 100644 drivers/scsi/bfa/bfa_iocfc.c ++ create mode 100644 drivers/scsi/bfa/bfa_iocfc.h ++ create mode 100644 drivers/scsi/bfa/bfa_iocfc_q.c ++ create mode 100644 drivers/scsi/bfa/bfa_ioim.c ++ create mode 100644 drivers/scsi/bfa/bfa_itnim.c ++ create mode 100644 drivers/scsi/bfa/bfa_log.c ++ create mode 100644 drivers/scsi/bfa/bfa_log_module.c ++ create mode 100644 drivers/scsi/bfa/bfa_lps.c ++ create mode 100644 drivers/scsi/bfa/bfa_lps_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_module.c ++ create mode 100644 drivers/scsi/bfa/bfa_modules_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_os_inc.h ++ create mode 100644 drivers/scsi/bfa/bfa_port.c ++ create mode 100644 drivers/scsi/bfa/bfa_port_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_rport.c ++ create mode 100644 drivers/scsi/bfa/bfa_rport_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_sgpg.c ++ create mode 100644 drivers/scsi/bfa/bfa_sgpg_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_sm.c ++ create mode 100644 drivers/scsi/bfa/bfa_timer.c ++ create mode 100644 drivers/scsi/bfa/bfa_trcmod_priv.h ++ create mode 100644 drivers/scsi/bfa/bfa_tskim.c ++ create mode 100644 drivers/scsi/bfa/bfa_uf.c ++ create mode 100644 drivers/scsi/bfa/bfa_uf_priv.h ++ create mode 100644 drivers/scsi/bfa/bfad.c ++ create mode 100644 drivers/scsi/bfa/bfad_attr.c ++ create mode 100644 drivers/scsi/bfa/bfad_attr.h ++ create mode 100644 drivers/scsi/bfa/bfad_drv.h ++ create mode 100644 drivers/scsi/bfa/bfad_fwimg.c ++ create mode 100644 drivers/scsi/bfa/bfad_im.c ++ create mode 100644 drivers/scsi/bfa/bfad_im.h ++ create mode 100644 drivers/scsi/bfa/bfad_im_compat.h ++ create mode 100644 drivers/scsi/bfa/bfad_intr.c ++ create mode 100644 drivers/scsi/bfa/bfad_ipfc.h ++ create mode 100644 drivers/scsi/bfa/bfad_os.c ++ create mode 100644 drivers/scsi/bfa/bfad_tm.h ++ create mode 100644 drivers/scsi/bfa/bfad_trcmod.h ++ create mode 100644 drivers/scsi/bfa/fab.c ++ create mode 100644 drivers/scsi/bfa/fabric.c ++ create mode 100644 drivers/scsi/bfa/fcbuild.c ++ create mode 100644 drivers/scsi/bfa/fcbuild.h ++ create mode 100644 drivers/scsi/bfa/fcpim.c ++ create mode 100644 drivers/scsi/bfa/fcptm.c ++ create mode 100644 drivers/scsi/bfa/fcs.h ++ create mode 100644 drivers/scsi/bfa/fcs_auth.h ++ create mode 100644 drivers/scsi/bfa/fcs_fabric.h ++ create mode 100644 drivers/scsi/bfa/fcs_fcpim.h ++ create mode 100644 drivers/scsi/bfa/fcs_fcptm.h ++ create mode 100644 drivers/scsi/bfa/fcs_fcxp.h ++ create mode 100644 drivers/scsi/bfa/fcs_lport.h ++ create mode 100644 drivers/scsi/bfa/fcs_ms.h ++ create mode 100644 drivers/scsi/bfa/fcs_port.h ++ create mode 100644 drivers/scsi/bfa/fcs_rport.h ++ create mode 100644 drivers/scsi/bfa/fcs_trcmod.h ++ create mode 100644 drivers/scsi/bfa/fcs_uf.h ++ create mode 100644 drivers/scsi/bfa/fcs_vport.h ++ create mode 100644 drivers/scsi/bfa/fdmi.c ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_adapter.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_audit.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_ethport.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_ioc.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_itnim.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_lport.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_port.h ++ create mode 100644 drivers/scsi/bfa/include/aen/bfa_aen_rport.h ++ create mode 100644 drivers/scsi/bfa/include/bfa.h ++ create mode 100644 drivers/scsi/bfa/include/bfa_fcpim.h ++ create mode 100644 drivers/scsi/bfa/include/bfa_fcptm.h ++ create mode 100644 drivers/scsi/bfa/include/bfa_svc.h ++ create mode 100644 drivers/scsi/bfa/include/bfa_timer.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_boot.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_cbreg.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_cee.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_ctreg.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_fabric.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_fcpim.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_fcxp.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_ioc.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_iocfc.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_lport.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_lps.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_port.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_pport.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_rport.h ++ create mode 100644 drivers/scsi/bfa/include/bfi/bfi_uf.h ++ create mode 100644 drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h ++ create mode 100644 drivers/scsi/bfa/include/cna/cee/bfa_cee.h ++ create mode 100644 drivers/scsi/bfa/include/cna/port/bfa_port.h ++ create mode 100644 drivers/scsi/bfa/include/cna/pstats/ethport_defs.h ++ create mode 100644 drivers/scsi/bfa/include/cna/pstats/phyport_defs.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_checksum.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_debug.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_log.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_perf.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_plog.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_q.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_sm.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_trc.h ++ create mode 100644 drivers/scsi/bfa/include/cs/bfa_wc.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_adapter.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_aen.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_audit.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_auth.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_boot.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_cee.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_driver.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_ethport.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_im_common.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_im_team.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_ioc.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_itnim.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_led.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_lport.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_mfg.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_pci.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_pm.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_pom.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_port.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_pport.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_qos.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_rport.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_status.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_tin.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_types.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_version.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_vf.h ++ create mode 100644 drivers/scsi/bfa/include/defs/bfa_defs_vport.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb_port.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h ++ create mode 100644 drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h ++ create mode 100644 drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h ++ create mode 100644 drivers/scsi/bfa/include/log/bfa_log_fcs.h ++ create mode 100644 drivers/scsi/bfa/include/log/bfa_log_hal.h ++ create mode 100644 drivers/scsi/bfa/include/log/bfa_log_linux.h ++ create mode 100644 drivers/scsi/bfa/include/log/bfa_log_wdrv.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/ct.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/fc.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/fc_sp.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/fcp.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/fdmi.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/pcifw.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/scsi.h ++ create mode 100644 drivers/scsi/bfa/include/protocol/types.h ++ create mode 100644 drivers/scsi/bfa/loop.c ++ create mode 100644 drivers/scsi/bfa/lport_api.c ++ create mode 100644 drivers/scsi/bfa/lport_priv.h ++ create mode 100644 drivers/scsi/bfa/ms.c ++ create mode 100644 drivers/scsi/bfa/n2n.c ++ create mode 100644 drivers/scsi/bfa/ns.c ++ create mode 100644 drivers/scsi/bfa/plog.c ++ create mode 100644 drivers/scsi/bfa/rport.c ++ create mode 100644 drivers/scsi/bfa/rport_api.c ++ create mode 100644 drivers/scsi/bfa/rport_ftrs.c ++ create mode 100644 drivers/scsi/bfa/scn.c ++ create mode 100644 drivers/scsi/bfa/vfapi.c ++ create mode 100644 drivers/scsi/bfa/vport.c ++ create mode 100644 drivers/scsi/libfc/fc_libfc.c ++ create mode 100644 drivers/scsi/libfc/fc_libfc.h ++ create mode 100644 drivers/scsi/libfc/fc_npiv.c ++ create mode 100644 include/scsi/fc/Kbuild +Merging async_tx/next +$ git merge async_tx/next +Already up-to-date. @@ -57844,152 +58646,49 @@ index 0000000..e6936a7 +Already up-to-date. +Merging wireless/master +$ git merge wireless/master -+Recorded preimage for 'drivers/net/wireless/iwlwifi/iwl-rx.c' -+Auto-merging drivers/net/wireless/b43/main.c -+Auto-merging drivers/net/wireless/iwlwifi/iwl-4965.c -+Auto-merging drivers/net/wireless/iwlwifi/iwl-rx.c -+CONFLICT (content): Merge conflict in drivers/net/wireless/iwlwifi/iwl-rx.c -+Auto-merging drivers/net/wireless/iwlwifi/iwl3945-base.c -+Automatic merge failed; fix conflicts and then commit the result. -+$ git commit -v -a -+Recorded resolution for 'drivers/net/wireless/iwlwifi/iwl-rx.c'. -+[master 2de9b6c] Merge remote branch 'wireless/master' -+$ git diff -M --stat --summary HEAD^.. -+ drivers/net/wireless/ath/ar9170/usb.c | 2 + -+ drivers/net/wireless/ath/ath9k/calib.c | 23 ++- -+ drivers/net/wireless/ath/ath9k/calib.h | 1 + -+ drivers/net/wireless/ath/ath9k/eeprom_def.c | 4 +- -+ drivers/net/wireless/ath/ath9k/hw.c | 202 ++++++++++++-------- -+ drivers/net/wireless/ath/ath9k/hw.h | 4 +- -+ drivers/net/wireless/ath/ath9k/main.c | 16 +- -+ drivers/net/wireless/ath/ath9k/reg.h | 3 +- -+ drivers/net/wireless/b43/Kconfig | 21 ++- -+ drivers/net/wireless/b43/Makefile | 1 + -+ drivers/net/wireless/b43/b43.h | 23 +-- -+ drivers/net/wireless/b43/debugfs.c | 1 + -+ drivers/net/wireless/b43/debugfs.h | 1 + -+ drivers/net/wireless/b43/dma.c | 4 +- -+ drivers/net/wireless/b43/leds.c | 266 +++++++++++++++++++-------- -+ drivers/net/wireless/b43/leds.h | 33 +++- -+ drivers/net/wireless/b43/main.c | 224 +++++++++++++---------- -+ drivers/net/wireless/b43/phy_lp.c | 12 +- -+ drivers/net/wireless/b43/pio.c | 2 +- -+ drivers/net/wireless/b43/rfkill.c | 2 +- -+ drivers/net/wireless/b43/sdio.c | 202 ++++++++++++++++++++ -+ drivers/net/wireless/b43/sdio.h | 45 +++++ -+ drivers/net/wireless/b43/xmit.c | 5 +- -+ drivers/net/wireless/iwlwifi/iwl-4965.c | 6 + -+ drivers/net/wireless/iwlwifi/iwl-5000.c | 6 + -+ drivers/net/wireless/iwlwifi/iwl-rx.c | 10 +- -+ drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- -+ drivers/net/wireless/iwlwifi/iwl3945-base.c | 9 +- -+ drivers/net/wireless/rt2x00/rt2x00lib.h | 2 +- -+ drivers/net/wireless/wl12xx/Kconfig | 2 +- -+ drivers/net/wireless/zd1211rw/zd_usb.c | 2 +- -+ net/mac80211/scan.c | 4 +- -+ net/wireless/wext-sme.c | 2 +- -+ 33 files changed, 835 insertions(+), 307 deletions(-) -+ create mode 100644 drivers/net/wireless/b43/sdio.c -+ create mode 100644 drivers/net/wireless/b43/sdio.h ++Already up-to-date. +Merging mtd/master +$ git merge mtd/master -+Already up-to-date. ++Auto-merging drivers/mtd/maps/Kconfig ++Merge made by recursive. ++ arch/arm/mach-nomadik/board-nhk8815.c | 11 ++-- ++ drivers/mtd/devices/m25p80.c | 7 ++- ++ drivers/mtd/maps/Kconfig | 1 + ++ drivers/mtd/maps/gpio-addr-flash.c | 5 +- ++ drivers/mtd/nand/nand_base.c | 6 ++ ++ include/linux/mtd/bbm.h | 35 ++++++------ ++ include/linux/mtd/flashchip.h | 7 +++ ++ include/linux/mtd/nand.h | 93 +------------------------------- ++ include/linux/mtd/onenand.h | 19 +------ ++ 9 files changed, 49 insertions(+), 135 deletions(-) +Merging crypto/master +$ git merge crypto/master +Already up-to-date. +Merging sound/for-next +$ git merge sound/for-next -+Already uptodate! +Merge made by recursive. ++ sound/pci/hda/hda_intel.c | 1 + ++ sound/pci/hda/patch_conexant.c | 12 +++++- ++ sound/soc/blackfin/bf5xx-i2s.c | 8 ++-- ++ sound/soc/blackfin/bf5xx-tdm.c | 8 ++-- ++ sound/soc/davinci/davinci-i2s.c | 37 ++++++----------- ++ sound/soc/davinci/davinci-mcasp.c | 80 +++++++++++++------------------------ ++ sound/soc/davinci/davinci-mcasp.h | 7 +++- ++ sound/soc/davinci/davinci-pcm.c | 13 +++--- ++ sound/soc/davinci/davinci-pcm.h | 1 - ++ 9 files changed, 72 insertions(+), 95 deletions(-) +Merging cpufreq/next +$ git merge cpufreq/next +Already up-to-date. +Merging quilt/rr +$ git merge quilt/rr ++Auto-merging arch/powerpc/kernel/setup-common.c ++Auto-merging include/linux/sched.h ++Auto-merging init/main.c +Auto-merging virt/kvm/kvm_main.c +Merge made by recursive. -+ arch/alpha/include/asm/smp.h | 2 +- -+ arch/alpha/include/asm/topology.h | 18 - -+ arch/alpha/kernel/smp.c | 14 +- -+ arch/arm/include/asm/cacheflush.h | 8 +- -+ arch/arm/include/asm/mmu_context.h | 7 +- -+ arch/arm/include/asm/smp.h | 1 - -+ arch/arm/include/asm/tlbflush.h | 4 +- -+ arch/arm/kernel/smp.c | 10 +- -+ arch/arm/mm/context.c | 2 +- -+ arch/arm/mm/flush.c | 10 +- -+ arch/ia64/include/asm/smp.h | 1 - -+ arch/ia64/include/asm/topology.h | 3 - -+ arch/ia64/kernel/smp.c | 2 +- -+ arch/m32r/include/asm/mmu_context.h | 4 +- -+ arch/m32r/include/asm/smp.h | 2 +- -+ arch/m32r/kernel/smp.c | 30 +- -+ arch/m32r/kernel/smpboot.c | 2 +- -+ arch/mips/alchemy/common/time.c | 2 +- -+ arch/mips/include/asm/mach-ip27/topology.h | 2 - -+ arch/mips/include/asm/mmu_context.h | 10 +- -+ arch/mips/include/asm/smp-ops.h | 2 +- -+ arch/mips/include/asm/smp.h | 2 +- -+ arch/mips/kernel/smp-cmp.c | 6 +- -+ arch/mips/kernel/smp-mt.c | 6 +- -+ arch/mips/kernel/smp-up.c | 3 +- -+ arch/mips/kernel/smp.c | 8 +- -+ arch/mips/kernel/smtc.c | 6 +- -+ arch/mips/mipssim/sim_smtc.c | 5 +- -+ arch/mips/mm/c-octeon.c | 2 +- -+ arch/mips/mti-malta/malta-smtc.c | 4 +- -+ arch/mips/pmc-sierra/yosemite/smp.c | 4 +- -+ arch/mips/sgi-ip27/ip27-memory.c | 2 +- -+ arch/mips/sgi-ip27/ip27-smp.c | 4 +- -+ arch/mips/sibyte/bcm1480/smp.c | 5 +- -+ arch/mips/sibyte/sb1250/smp.c | 5 +- -+ arch/mn10300/include/asm/mmu_context.h | 12 +- -+ arch/parisc/include/asm/smp.h | 1 - -+ arch/powerpc/include/asm/smp.h | 2 +- -+ arch/powerpc/include/asm/topology.h | 12 - -+ arch/powerpc/kernel/setup-common.c | 6 +- -+ arch/powerpc/kernel/smp.c | 12 +- -+ arch/powerpc/platforms/powermac/smp.c | 6 +- -+ arch/powerpc/platforms/pseries/hotplug-cpu.c | 6 +- -+ arch/s390/include/asm/smp.h | 2 +- -+ arch/s390/include/asm/topology.h | 1 - -+ arch/s390/kernel/smp.c | 4 +- -+ arch/sh/include/asm/smp.h | 1 - -+ arch/sh/include/asm/topology.h | 1 - -+ arch/sparc/include/asm/smp_64.h | 1 - -+ arch/sparc/include/asm/topology_64.h | 16 - -+ arch/um/include/asm/mmu_context.h | 4 +- -+ arch/um/kernel/smp.c | 2 +- -+ arch/x86/include/asm/mmu_context.h | 6 +- -+ arch/x86/include/asm/smp.h | 1 - -+ arch/x86/kernel/apic/io_apic.c | 7 +- -+ arch/x86/kernel/ldt.c | 4 +- -+ arch/x86/kernel/process.c | 6 +- -+ arch/x86/kernel/smpboot.c | 9 +- -+ arch/x86/kernel/time.c | 1 - -+ arch/x86/mm/tlb.c | 15 +- -+ arch/x86/xen/mmu.c | 4 +- -+ drivers/acpi/osl.c | 2 +- -+ drivers/acpi/processor_perflib.c | 3 +- -+ drivers/acpi/processor_throttling.c | 3 +- -+ drivers/net/sfc/efx.c | 3 +- -+ drivers/net/virtio_net.c | 229 ++++----- -+ drivers/oprofile/buffer_sync.c | 3 +- -+ include/asm-generic/topology.h | 17 - -+ include/linux/cpumask.h | 709 +++++++++----------------- -+ include/linux/interrupt.h | 2 - -+ include/linux/module.h | 17 +- -+ include/linux/sched.h | 3 + -+ include/linux/smp.h | 11 - -+ include/linux/topology.h | 6 - -+ init/main.c | 5 - -+ kernel/module.c | 159 ++++++- -+ kernel/params.c | 7 +- -+ kernel/smp.c | 7 - -+ kernel/trace/trace.c | 7 +- -+ mm/quicklist.c | 3 +- -+ virt/kvm/kvm_main.c | 3 +- -+ 81 files changed, 656 insertions(+), 883 deletions(-) ++ drivers/net/virtio_net.c | 229 ++++++++++++++++++---------------------------- ++ 1 files changed, 88 insertions(+), 141 deletions(-) +Merging mmc/next +$ git merge mmc/next +Already up-to-date. @@ -58001,25 +58700,26 @@ index 0000000..e6936a7 +Already up-to-date. +Merging block/for-next +$ git merge block/for-next -+Auto-merging drivers/block/DAC960.c -+Auto-merging drivers/block/cciss.c +Auto-merging fs/buffer.c ++Auto-merging mm/page-writeback.c ++Auto-merging mm/shmem.c ++Auto-merging mm/vmscan.c +Merge made by recursive. + .../ABI/testing/sysfs-bus-pci-devices-cciss | 28 + + block/blk-core.c | 1 + + block/blk-settings.c | 4 +- + drivers/block/DAC960.c | 156 ++--- -+ drivers/block/cciss.c | 748 ++++++++++++++------ ++ drivers/block/cciss.c | 753 ++++++++++++++------ + drivers/block/cciss.h | 12 +- + drivers/block/cpqarray.c | 63 +- + fs/buffer.c | 10 +- -+ fs/fs-writeback.c | 87 ++- ++ fs/fs-writeback.c | 153 +++-- + include/trace/events/block.h | 33 + + kernel/trace/blktrace.c | 34 + + mm/page-writeback.c | 30 +- + mm/shmem.c | 5 +- + mm/vmscan.c | 8 +- -+ 14 files changed, 839 insertions(+), 380 deletions(-) ++ 14 files changed, 889 insertions(+), 401 deletions(-) +Merging quilt/device-mapper +$ git merge quilt/device-mapper +Merge made by recursive. @@ -58048,33 +58748,50 @@ index 0000000..e6936a7 +$ git merge leds/for-mm +Auto-merging drivers/leds/leds-clevo-mail.c +Merge made by recursive. -+ drivers/leds/Kconfig | 13 +- -+ drivers/leds/Makefile | 1 + ++ drivers/leds/Kconfig | 22 ++- ++ drivers/leds/Makefile | 2 + + drivers/leds/leds-clevo-mail.c | 2 +- + drivers/leds/leds-cobalt-qube.c | 2 +- + drivers/leds/leds-cobalt-raq.c | 4 +- + drivers/leds/leds-gpio.c | 2 +- + drivers/leds/leds-pca9532.c | 12 +- -+ drivers/leds/leds-wm831x-status.c | 341 +++++++++++++++++++++++++++++++++++++ -+ drivers/leds/ledtrig-gpio.c | 28 ++-- ++ drivers/leds/leds-ss4200.c | 551 +++++++++++++++++++++++++++++++++++++ ++ drivers/leds/leds-wm831x-status.c | 341 +++++++++++++++++++++++ ++ drivers/leds/ledtrig-gpio.c | 28 +- + drivers/macintosh/via-pmu-led.c | 2 +- -+ include/linux/mfd/wm831x/status.h | 34 ++++ -+ 11 files changed, 412 insertions(+), 29 deletions(-) ++ include/linux/mfd/wm831x/status.h | 34 +++ ++ 12 files changed, 973 insertions(+), 29 deletions(-) ++ create mode 100644 drivers/leds/leds-ss4200.c + create mode 100644 drivers/leds/leds-wm831x-status.c + create mode 100644 include/linux/mfd/wm831x/status.h +Merging backlight/for-mm +$ git merge backlight/for-mm ++Recorded preimage for 'drivers/video/backlight/da903x_bl.c' ++Auto-merging drivers/acpi/video.c ++Auto-merging drivers/platform/x86/eeepc-laptop.c +Auto-merging drivers/video/backlight/Kconfig -+Merge made by recursive. -+ drivers/video/backlight/Kconfig | 22 +++ -+ drivers/video/backlight/Makefile | 4 +- -+ drivers/video/backlight/adx_bl.c | 178 ++++++++++++++++++++++ ++Auto-merging drivers/video/backlight/da903x_bl.c ++CONFLICT (content): Merge conflict in drivers/video/backlight/da903x_bl.c ++Automatic merge failed; fix conflicts and then commit the result. ++$ git commit -v -a ++Recorded resolution for 'drivers/video/backlight/da903x_bl.c'. ++[master e5178f3] Merge remote branch 'backlight/for-mm' ++$ git diff -M --stat --summary HEAD^.. ++ drivers/acpi/video.c | 4 + ++ drivers/platform/x86/eeepc-laptop.c | 2 +- ++ drivers/video/backlight/Kconfig | 33 +++ ++ drivers/video/backlight/Makefile | 4 + ++ drivers/video/backlight/adp5520_bl.c | 377 +++++++++++++++++++++++++++++++ ++ drivers/video/backlight/adx_bl.c | 178 +++++++++++++++ ++ drivers/video/backlight/backlight.c | 42 ++++ + drivers/video/backlight/hp680_bl.c | 2 +- -+ drivers/video/backlight/lms283gf05.c | 242 ++++++++++++++++++++++++++++++ -+ drivers/video/backlight/mbp_nvidia_bl.c | 36 +++++ -+ drivers/video/backlight/wm831x_bl.c | 250 +++++++++++++++++++++++++++++++ -+ include/linux/spi/lms283gf05.h | 28 ++++ -+ 8 files changed, 760 insertions(+), 2 deletions(-) ++ drivers/video/backlight/lms283gf05.c | 242 ++++++++++++++++++++ ++ drivers/video/backlight/mbp_nvidia_bl.c | 36 +++ ++ drivers/video/backlight/wm831x_bl.c | 250 ++++++++++++++++++++ ++ include/linux/backlight.h | 7 + ++ include/linux/spi/lms283gf05.h | 28 +++ ++ 13 files changed, 1203 insertions(+), 2 deletions(-) ++ create mode 100644 drivers/video/backlight/adp5520_bl.c + create mode 100644 drivers/video/backlight/adx_bl.c + create mode 100644 drivers/video/backlight/lms283gf05.c + create mode 100644 drivers/video/backlight/wm831x_bl.c @@ -58082,6 +58799,7 @@ index 0000000..e6936a7 +Merging kgdb/kgdb-next +$ git merge kgdb/kgdb-next +Auto-merging include/linux/sched.h ++Auto-merging kernel/softlockup.c +Merge made by recursive. + arch/x86/kernel/kgdb.c | 12 ++++++++---- + include/linux/sched.h | 4 ++++ @@ -58123,13 +58841,18 @@ index 0000000..e6936a7 +Already up-to-date. +Merging drm/drm-next +$ git merge drm/drm-next -+Already up-to-date. ++Merge made by recursive. ++ drivers/gpu/drm/drm_edid.c | 40 ++++++++++++++++++++++++++++++++-------- ++ 1 files changed, 32 insertions(+), 8 deletions(-) +Merging voltage/for-next +$ git merge voltage/for-next +Already up-to-date. +Merging security-testing/next +$ git merge security-testing/next -+Already up-to-date. ++Auto-merging drivers/char/tpm/tpm.c ++Merge made by recursive. ++ drivers/char/tpm/tpm.c | 2 +- ++ 1 files changed, 1 insertions(+), 1 deletions(-) +Merging lblnet/master +$ git merge lblnet/master +Already up-to-date. @@ -58142,29 +58865,35 @@ index 0000000..e6936a7 +Merging watchdog/master +$ git merge watchdog/master +Merge made by recursive. ++ drivers/watchdog/Kconfig | 7 + ++ drivers/watchdog/Makefile | 1 + ++ drivers/watchdog/adx_wdt.c | 354 ++++++++++++++++++++++++++++++++++++++++++++ ++ 3 files changed, 362 insertions(+), 0 deletions(-) ++ create mode 100644 drivers/watchdog/adx_wdt.c +Merging bdev/master +$ git merge bdev/master +Already up-to-date. +Merging dwmw2-iommu/master +$ git merge dwmw2-iommu/master -+Already up-to-date. ++Merge made by recursive. ++ drivers/pci/dmar.c | 13 ++++++++++++- ++ 1 files changed, 12 insertions(+), 1 deletions(-) +Merging cputime/cputime +$ git merge cputime/cputime -+Merge made by recursive. -+ fs/proc/uptime.c | 7 ++++++- -+ 1 files changed, 6 insertions(+), 1 deletions(-) ++Already up-to-date. +Merging osd/linux-next +$ git merge osd/linux-next ++Auto-merging fs/exofs/super.c +Merge made by recursive. + Documentation/filesystems/00-INDEX | 2 + + Documentation/filesystems/exofs.txt | 23 ++++++++------- + drivers/scsi/osd/osd_initiator.c | 22 ++++++++++---- + drivers/scsi/osd/osd_uld.c | 53 ++++++++++++++++++++++++++++++++++- + fs/exofs/inode.c | 13 ++++++-- -+ fs/exofs/super.c | 17 +++++++---- ++ fs/exofs/super.c | 11 +++++++ + include/scsi/osd_initiator.h | 53 ++++++++++++++++++++++++++++------ + include/scsi/osd_sense.h | 3 ++ -+ 8 files changed, 148 insertions(+), 38 deletions(-) ++ 8 files changed, 148 insertions(+), 32 deletions(-) +Merging jc_docs/docs-next +$ git merge jc_docs/docs-next +Already up-to-date. @@ -58175,7 +58904,9 @@ index 0000000..e6936a7 +$ git merge trivial/for-next +Merge made by recursive. + Documentation/timers/hpet.txt | 2 +- -+ 1 files changed, 1 insertions(+), 1 deletions(-) ++ drivers/rtc/rtc-ds1511.c | 4 ++-- ++ drivers/watchdog/sb_wdog.c | 4 ++-- ++ 3 files changed, 5 insertions(+), 5 deletions(-) +Merging audit/for-next +$ git merge audit/for-next +Already up-to-date. @@ -58200,8 +58931,12 @@ index 0000000..e6936a7 +Auto-merging fs/exec.c +Auto-merging fs/nfsd/vfs.c +Auto-merging fs/open.c ++Auto-merging fs/read_write.c +Auto-merging init/Kconfig +Auto-merging kernel/Makefile ++Auto-merging kernel/audit.c ++Auto-merging kernel/audit_watch.c ++Auto-merging kernel/auditsc.c +Merge made by recursive. + Documentation/feature-removal-schedule.txt | 7 + + fs/compat.c | 5 +- @@ -58222,11 +58957,11 @@ index 0000000..e6936a7 + kernel/Makefile | 5 +- + kernel/audit.c | 1 - + kernel/audit.h | 26 ++- -+ kernel/audit_tree.c | 223 ++++++++++++--------- -+ kernel/audit_watch.c | 296 ++++++++++++++++------------ ++ kernel/audit_tree.c | 223 ++++++++++++---------- ++ kernel/audit_watch.c | 294 ++++++++++++++++------------ + kernel/auditfilter.c | 39 ++--- -+ kernel/auditsc.c | 15 +- -+ 23 files changed, 730 insertions(+), 526 deletions(-) ++ kernel/auditsc.c | 9 +- ++ 23 files changed, 726 insertions(+), 522 deletions(-) +Merging irda/for-next +$ git merge irda/for-next +Auto-merging drivers/net/irda/irda-usb.c @@ -58322,21 +59057,12 @@ index 0000000..e6936a7 +Already up-to-date. +Merging tip/auto-latest +$ git merge tip/auto-latest -+Recorded preimage for 'fs/proc/array.c' -+Auto-merging arch/x86/Kconfig +Auto-merging arch/x86/kernel/apic/io_apic.c +Auto-merging arch/x86/kernel/head_32.S +Auto-merging arch/x86/kernel/head_64.S -+Auto-merging drivers/pci/intr_remapping.c -+Auto-merging fs/proc/array.c -+CONFLICT (content): Merge conflict in fs/proc/array.c -+Auto-merging include/linux/poison.h -+Auto-merging kernel/fork.c -+Automatic merge failed; fix conflicts and then commit the result. -+$ git commit -v -a -+Recorded resolution for 'fs/proc/array.c'. -+[master 576aeed] Merge remote branch 'tip/auto-latest' -+$ git diff -M --stat --summary HEAD^.. ++Auto-merging arch/x86/kernel/traps.c ++Auto-merging kernel/cpuset.c ++Merge made by recursive. + arch/x86/Kconfig | 5 ++ + arch/x86/boot/compressed/head_32.S | 3 +- + arch/x86/boot/compressed/head_64.S | 3 +- @@ -58381,80 +59107,7 @@ index 0000000..e6936a7 + 1 files changed, 8 insertions(+), 6 deletions(-) +Merging hwpoison/hwpoison +$ git merge hwpoison/hwpoison -+Auto-merging Documentation/sysctl/vm.txt -+Auto-merging arch/x86/mm/fault.c -+Auto-merging fs/btrfs/inode.c -+Auto-merging fs/ext3/inode.c -+Auto-merging fs/ext4/inode.c -+Auto-merging fs/ocfs2/aops.c -+Auto-merging fs/proc/meminfo.c -+Auto-merging fs/xfs/linux-2.6/xfs_aops.c -+Auto-merging include/asm-generic/mman-common.h -+Auto-merging include/linux/fs.h -+Auto-merging include/linux/mm.h -+Auto-merging include/linux/page-flags.h -+Auto-merging include/linux/prctl.h -+Auto-merging include/linux/rmap.h -+Auto-merging include/linux/sched.h -+Auto-merging include/linux/swap.h -+Auto-merging kernel/sys.c -+Auto-merging kernel/sysctl.c -+Auto-merging mm/Kconfig -+Auto-merging mm/Makefile -+Auto-merging mm/filemap.c -+Auto-merging mm/madvise.c -+Auto-merging mm/memory.c -+Auto-merging mm/migrate.c -+Auto-merging mm/page-writeback.c -+Auto-merging mm/page_alloc.c -+Auto-merging mm/rmap.c -+Auto-merging mm/shmem.c -+Auto-merging mm/swapfile.c -+Auto-merging mm/vmscan.c -+Merge made by recursive. -+ Documentation/filesystems/vfs.txt | 7 + -+ Documentation/sysctl/vm.txt | 41 ++- -+ arch/x86/mm/fault.c | 19 +- -+ fs/btrfs/inode.c | 1 + -+ fs/ext2/inode.c | 2 + -+ fs/ext3/inode.c | 3 + -+ fs/ext4/inode.c | 4 + -+ fs/gfs2/aops.c | 3 + -+ fs/nfs/file.c | 1 + -+ fs/ntfs/aops.c | 2 + -+ fs/ocfs2/aops.c | 1 + -+ fs/proc/meminfo.c | 9 +- -+ fs/xfs/linux-2.6/xfs_aops.c | 1 + -+ include/asm-generic/mman-common.h | 1 + -+ include/asm-generic/siginfo.h | 8 +- -+ include/linux/fs.h | 1 + -+ include/linux/mm.h | 15 +- -+ include/linux/page-flags.h | 17 +- -+ include/linux/prctl.h | 2 + -+ include/linux/rmap.h | 21 +- -+ include/linux/sched.h | 2 + -+ include/linux/swap.h | 34 ++- -+ include/linux/swapops.h | 38 ++ -+ kernel/sys.c | 22 + -+ kernel/sysctl.c | 25 ++ -+ mm/Kconfig | 14 + -+ mm/Makefile | 2 + -+ mm/filemap.c | 4 + -+ mm/hwpoison-inject.c | 41 ++ -+ mm/madvise.c | 30 ++ -+ mm/memory-failure.c | 832 +++++++++++++++++++++++++++++++++++++ -+ mm/memory.c | 24 +- -+ mm/migrate.c | 2 +- -+ mm/page-writeback.c | 7 + -+ mm/page_alloc.c | 20 +- -+ mm/rmap.c | 60 ++- -+ mm/shmem.c | 5 +- -+ mm/swapfile.c | 4 +- -+ mm/truncate.c | 72 +++- -+ mm/vmscan.c | 2 +- -+ 40 files changed, 1331 insertions(+), 68 deletions(-) -+ create mode 100644 mm/hwpoison-inject.c -+ create mode 100644 mm/memory-failure.c ++Already up-to-date. +Merging quilt/driver-core +$ git merge quilt/driver-core +Already up-to-date. @@ -58463,10 +59116,19 @@ index 0000000..e6936a7 +Already up-to-date. +Merging quilt/usb +$ git merge quilt/usb ++Recorded preimage for 'drivers/usb/serial/sierra.c' +Auto-merging MAINTAINERS +Auto-merging drivers/usb/Kconfig ++Auto-merging drivers/usb/gadget/u_audio.c ++Auto-merging drivers/usb/gadget/u_ether.c +Auto-merging drivers/usb/host/ohci-pxa27x.c -+Merge made by recursive. ++Auto-merging drivers/usb/serial/sierra.c ++CONFLICT (content): Merge conflict in drivers/usb/serial/sierra.c ++Automatic merge failed; fix conflicts and then commit the result. ++$ git commit -v -a ++Recorded resolution for 'drivers/usb/serial/sierra.c'. ++[master a5a3357] Merge branch 'quilt/usb' ++$ git diff -M --stat --summary HEAD^.. +Merging quilt/staging +$ git merge quilt/staging +Auto-merging drivers/staging/Kconfig @@ -58523,6 +59185,12 @@ index 0000000..e6936a7 + delete mode 100644 drivers/staging/agnx/xmit.h +Merging scsi-post-merge/master +$ git merge scsi-post-merge/master ++Recorded preimage for 'drivers/scsi/fcoe/fcoe.c' ++Recorded preimage for 'drivers/scsi/fcoe/fcoe.h' ++Recorded preimage for 'drivers/scsi/libfc/fc_elsct.c' ++Recorded preimage for 'drivers/scsi/libfc/fc_lport.c' ++Recorded preimage for 'include/scsi/fc_encode.h' ++Recorded preimage for 'include/scsi/libfc.h' +Resolved 'MAINTAINERS' using previous resolution. +Resolved 'drivers/scsi/Makefile' using previous resolution. +Resolved 'drivers/scsi/pmcraid.c' using previous resolution. @@ -58536,7 +59204,19 @@ index 0000000..e6936a7 +Auto-merging drivers/scsi/Makefile +CONFLICT (content): Merge conflict in drivers/scsi/Makefile +Auto-merging drivers/scsi/device_handler/scsi_dh_rdac.c ++Auto-merging drivers/scsi/fcoe/fcoe.c ++CONFLICT (content): Merge conflict in drivers/scsi/fcoe/fcoe.c ++Auto-merging drivers/scsi/fcoe/fcoe.h ++CONFLICT (content): Merge conflict in drivers/scsi/fcoe/fcoe.h +Auto-merging drivers/scsi/fcoe/libfcoe.c ++Auto-merging drivers/scsi/libfc/fc_disc.c ++Auto-merging drivers/scsi/libfc/fc_elsct.c ++CONFLICT (content): Merge conflict in drivers/scsi/libfc/fc_elsct.c ++Auto-merging drivers/scsi/libfc/fc_exch.c ++Auto-merging drivers/scsi/libfc/fc_fcp.c ++Auto-merging drivers/scsi/libfc/fc_lport.c ++CONFLICT (content): Merge conflict in drivers/scsi/libfc/fc_lport.c ++Auto-merging drivers/scsi/libfc/fc_rport.c +Auto-merging drivers/scsi/pmcraid.c +CONFLICT (add/add): Merge conflict in drivers/scsi/pmcraid.c +Auto-merging drivers/scsi/qla2xxx/qla_def.h @@ -58544,11 +59224,22 @@ index 0000000..e6936a7 +Auto-merging drivers/scsi/sg.c +Auto-merging include/linux/interrupt.h +Auto-merging include/linux/libata.h ++Auto-merging include/scsi/fc/fc_gs.h ++Auto-merging include/scsi/fc_encode.h ++CONFLICT (content): Merge conflict in include/scsi/fc_encode.h ++Auto-merging include/scsi/libfc.h ++CONFLICT (content): Merge conflict in include/scsi/libfc.h +Auto-merging kernel/sysctl.c +CONFLICT (content): Merge conflict in kernel/sysctl.c +Automatic merge failed; fix conflicts and then commit the result. +$ git commit -v -a -+[master 2859854] Merge remote branch 'scsi-post-merge/master' ++Recorded resolution for 'drivers/scsi/fcoe/fcoe.c'. ++Recorded resolution for 'drivers/scsi/fcoe/fcoe.h'. ++Recorded resolution for 'drivers/scsi/libfc/fc_elsct.c'. ++Recorded resolution for 'drivers/scsi/libfc/fc_lport.c'. ++Recorded resolution for 'include/scsi/fc_encode.h'. ++Recorded resolution for 'include/scsi/libfc.h'. ++[master 876d54c] Merge remote branch 'scsi-post-merge/master' +$ git diff -M --stat --summary HEAD^.. + MAINTAINERS | 8 + + drivers/ata/ahci.c | 54 +- @@ -58572,9 +59263,7 @@ index 0000000..e6936a7 + drivers/scsi/qla2xxx/qla_gbl.h | 1 + + drivers/scsi/qla2xxx/qla_os.c | 36 + + include/linux/libata.h | 2 + -+ include/scsi/Kbuild | 1 + -+ include/scsi/fc/Kbuild | 4 + -+ 24 files changed, 7337 insertions(+), 72 deletions(-) ++ 22 files changed, 7332 insertions(+), 72 deletions(-) + create mode 100644 drivers/scsi/be2iscsi/Kconfig + create mode 100644 drivers/scsi/be2iscsi/Makefile + create mode 100644 drivers/scsi/be2iscsi/be.h @@ -58586,77 +59275,24 @@ index 0000000..e6936a7 + create mode 100644 drivers/scsi/be2iscsi/be_main.h + create mode 100644 drivers/scsi/be2iscsi/be_mgmt.c + create mode 100644 drivers/scsi/be2iscsi/be_mgmt.h -+ create mode 100644 include/scsi/fc/Kbuild -+$ git am -3 ../patches/0001-powerpc-kvm-build-fix-for-new-BUILD_BUG_ON.patch -+Applying: powerpc/kvm: build fix for new BUILD_BUG_ON diff --git a/Next/quilt-import.log b/Next/quilt-import.log new file mode 100644 -index 0000000..0050bca +index 0000000..e32b71e --- /dev/null +++ b/Next/quilt-import.log -@@ -0,0 +1,316 @@ +@@ -0,0 +1,59 @@ +Importing driver-core.current based on 2.6.31-git12 -+ quilt series is empty -+$ git update-ref refs/heads/quilt/driver-core.current 7fa07729e439a6184bd824746d06a49cca553f15 ++Unchanged quilt series driver-core.current +Importing tty.current based on quilt/driver-core.current -+ quilt series is empty -+$ git update-ref refs/heads/quilt/tty.current 7fa07729e439a6184bd824746d06a49cca553f15 ++Unchanged quilt series tty.current +Importing usb.current based on quilt/tty.current ++Unchanged quilt series usb.current ++Importing i2c based on 2.6.31-git13 +$ git clone -s -l -n -q . ../quilt-tmp +$ cd ../quilt-tmp -+$ git reset --hard 7fa07729e439a6184bd824746d06a49cca553f15 -+HEAD is now at 7fa0772 Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip -+$ git quiltimport --author Greg KH --patches ../quilt/usb.current -+usb-storage-fix-a-resume-path-gfp_noio-must-be-used.patch -+usb-serial-ftdi_sio-new-hardware-support-hameg-power-supply.patch -+usb-serial-pl2303-new-hardware-support-sanwa-multimeter.patch -+usb-option.c-add-support-for-zte-ac2726-evdo-modem.patch -+usb-option-telit-uc864g-support.patch -+usb-cdc-wdm-driver-doesn-t-support-non-blocking-reads.patch -+usb-fix-cdc-acm-regression-in-open.patch -+usb-add-pids-for-ftdi-based-opendcc-hardware.patch -+usb-sl811-hcd-fix-device-disconnect.patch -+usb-serial-ftdi-handle-gnice-jtag-adaptors.patch -+usb-xhci-work-around-for-chain-bit-in-link-trbs.patch -+usb-xhci-fix-slot-and-endpoint-context-debugging.patch -+usb-xhci-configure-endpoint-code-refactoring.patch -+usb-xhci-set-correct-max-packet-size-for-hs-fs-control-endpoints.patch -+usb-xhci-support-full-speed-devices.patch -+usb-xhci-handle-stalled-control-endpoints.patch -+usb-xhci-add-quirk-for-fresco-logic-xhci-hardware.patch -+usb-xhci-make-trb-completion-code-comparison-readable.patch -+usb-xhci-handle-babbling-endpoints-correctly.patch -+usb-xhci-don-t-touch-xhci_td-after-it-s-freed.patch -+usb-xhci-check-urb-s-actual-transfer-buffer-size.patch -+usb-xhci-check-urb_short_not_ok-before-setting-short-packet-status.patch -+usb-xhci-set-eremoteio-when-xhc-gives-bad-transfer-length.patch -+usb-xhci-support-interrupt-transfers.patch -+usb-fix-ss-endpoint-companion-descriptor-parsing.patch -+$ cd ../next -+$ git fetch -f ../quilt-tmp master:quilt/usb.current -+From ../quilt-tmp -+ + c700413...28640c0 master -> quilt/usb.current (forced update) -+Importing i2c based on 2.6.31-git12 -+$ cd ../quilt-tmp -+$ git reset --hard 7fa07729e439a6184bd824746d06a49cca553f15 -+HEAD is now at 7fa0772 Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip ++$ git reset --hard 0dd52d0df02733dfc2d5f3824e41b96492305384 ++HEAD is now at 0dd52d0 Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input +$ git quiltimport --author Jean Delvare --patches ../quilt/i2c -+i2c-drop-i2c_driver-id.patch -+i2c-taos-evm-switch-echo-off.patch -+i2c-tsl2550-simpify-IO.patch -+i2c-core-01-client-as-device-type.patch -+i2c-core-02-adapters-as-bus-devices.patch -+i2c-core-03-i2c-adapter-compatibility-class-2.patch -+i2c-scx200_acb-provide-more-information-on-bus-errors.patch -+gpio-pcf857x-copy-i2c_device_id-from-old-pcf8574-driver.patch -+i2c-chips-remove-deprecated-pcf8575-driver.patch -+i2c-chips-remove-deprecated-pca9539-driver.patch -+i2c-chips-remove-deprecated-pcf8574-driver.patch -+i2c-piix4-add-amd-SB900-smbus-device-id.patch -+maintainers-add-maintainer-for-at24-and-pca9564-pca9665.patch -+i2c-pnx-correct-use-of-request_mem_region.patch -+i2c-add-driver-for-smbus-control-method-interface.patch -+i2c-list-acpi-drivers-as-such.patch +i2c-move-legacy-documentation.patch +i2c-voodoo3-delete.patch +misc-eeprom-max6875-no-detect.patch @@ -58666,91 +59302,19 @@ index 0000000..0050bca +$ cd ../next +$ git fetch -f ../quilt-tmp master:quilt/i2c +From ../quilt-tmp -+ + 3d3db2c...5e9f18d master -> quilt/i2c (forced update) -+Importing jdelvare-hwmon based on 2.6.31-git12 -+$ cd ../quilt-tmp -+$ git reset --hard 7fa07729e439a6184bd824746d06a49cca553f15 -+HEAD is now at 7fa0772 Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip -+$ git quiltimport --author Jean Delvare --patches ../quilt/jdelvare-hwmon -+hwmon-adm1031-add-sysfs-files-for-temperature-offsets.patch -+hwmon-remove-deprecated-fsc-drivers.patch -+hwmon-coretemp-add-atom-support.patch -+hwmon-coretemp-add-mobile-penryn-support.patch -+hwmon-coretemp-add-lynnfield-support.patch -+hwmon-ltc4215-clear-faults-at-startup.patch -+hwmon-ltc4245-clear-faults-at-startup.patch -+$ cd ../next -+$ git fetch -f ../quilt-tmp master:quilt/jdelvare-hwmon -+From ../quilt-tmp -+ + af663ff...862f219 master -> quilt/jdelvare-hwmon (forced update) ++ + 5e9f18d...66d155e master -> quilt/i2c (forced update) ++Importing jdelvare-hwmon based on 2.6.31-git13 ++ quilt series is empty ++$ git update-ref refs/heads/quilt/jdelvare-hwmon 0dd52d0df02733dfc2d5f3824e41b96492305384 +Importing kernel-doc based on origin/master + quilt series is empty -+$ git update-ref refs/heads/quilt/kernel-doc 0dd52d0df02733dfc2d5f3824e41b96492305384 ++$ git update-ref refs/heads/quilt/kernel-doc 94e0fb086fc5663c38bbc0fe86d698be8314f82f +Importing rr based on v2.6.31-8246-ga724ead -+$ cd ../quilt-tmp -+$ git reset --hard a724eada8c2a7b62463b73ccf73fd0bb6e928aeb -+HEAD is now at a724ead Merge branch 'ixp4xx' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6 -+$ git quiltimport --author Rusty Russell --patches ../quilt/rr -+cpumask:use_zalloc_cpumask_var_where_possible.patch -+cpumask:remove-pcibus_to_cpumask-alpha.patch -+cpumask:remove-pcibus_to_cpumask-mips.patch -+cpumask:remove-pcibus_to_cpumask-powerpc.patch -+cpumask:remove-node_to_cpumask.patch -+cpumask:remove-CPU_MASK_ALL_PTR.patch -+cpumask:remove-address-of-CPU_MASK_ALL-mips.patch -+cpumask:remove-cpu_mask_all.patch -+cpumask:remove-last-remaining-irqaction-mask.patch -+cpumask:irqaction-remove-mask.patch -+cpumask:remove_mask_field_from_comments.patch -+cpumask:set_cpus_allowed-acpi-removal.patch -+cpumask:remove-set_cpus_allowed.patch -+cpumask:ia64-smp_call_function_many.patch -+cpumask:remove-smp_call_function_mask.patch -+cpumask:remove-topology_core_siblings-and-topology_thread_siblings-core.patch -+cpumask:remove-topology_core_siblings-and-topology_thread_siblings-sparc.patch -+cpumask:remove-topology_core_siblings-and-topology_thread_siblings-s390.patch -+cpumask:remove-topology_core_siblings-and-topology_thread_siblings-powerpc.patch -+cpumask:remove-topology_core_siblings-and-topology_thread_siblings-ia64.patch -+cpumask:arch_send_call_function_ipi_mask-alpha.patch -+cpumask:arch_send_call_function_ipi_mask-m32r.patch -+cpumask:arch_send_call_function_ipi_mask-mips.patch -+cpumask:arch_send_call_function_ipi_mask-powerpc.patch -+cpumask:arch_send_call_function_ipi_mask-s390.patch -+cpumask:remove-arch_send_call_function_ipi.patch -+cpumask:use-cpumap-accessors-m32r.patch -+cpumask:use-cpumap-accessors-mips.patch -+cpumask:use-cpumap-accessors-powerpc.patch -+cpumask:use-cpumap-accessors-um.patch -+cpumask:use-mm_cpumask-arm.patch -+cpumask:use-mm_cpumask-m32r.patch -+cpumask:use-mm_cpumask-m32r-fix.patch -+cpumask:use-mm_cpumask-mn10300.patch -+cpumask:use-mm_cpumask-mips.patch -+cpumask:use-mm_cpumask-um.patch -+cpumask:use-mm_cpumask-x86.patch -+cpumask:mm_quicklist-new-cpumask-ops.patch -+cpumask:remove-unused-deprecated-functions.patch -+cpumask:move-obsolete-functions-to-end-of-header.patch -+virtio:net-skb_orphan-and-nf_reset.patch -+virtio:net-return-NETDEV_TX_BUSY.patch -+virtio:net-no-xmit-free-timer.patch -+virtio:net-struct-skb_vnet_hdr.patch -+virtio:net-stop_queue-before-full.patch -+virtio:net_check_for_room_in_the_vq_before_adding_buffer.patch -+module:reduce_symbol_table_for_loaded_s_v2.patch -+module:reduce_string_table_for_loaded_s_v2.patch -+param:allow_whitespace_as_kernel_parameter_separator.patch -+module:preferred_way_to_use_MODULE_AUTHOR.patch -+module:remove-attribute-memory-leak.patch -+module:no-percpu_modfree-on-NULL.patch -+$ cd ../next -+$ git fetch -f ../quilt-tmp master:quilt/rr -+From ../quilt-tmp -+ + d3eae8d...bb10e83 master -> quilt/rr (forced update) ++Unchanged quilt series rr +Importing device-mapper based on block/for-next +$ cd ../quilt-tmp -+$ git reset --hard f72873839e6805254acd18f9b546d1b8f0f2f21d -+HEAD is now at f728738 Merge branch 'writeback' into for-next ++$ git reset --hard 1e6697c4add13b3818be445b8e4406947d4824cc ++HEAD is now at 1e6697c Merge branch 'writeback' into for-next +$ git quiltimport --author Alasdair G Kergon --patches ../quilt/device-mapper +dm-log-fix-cn_ulog_callback-declaration.patch +dm-log-userspace-fix-incorrect-luid-cast-in-userspace_ctr.patch @@ -58765,152 +59329,17 @@ index 0000000..0050bca +$ cd ../next +$ git fetch -f ../quilt-tmp master:quilt/device-mapper +From ../quilt-tmp -+ + 38cffa8...eb12874 master -> quilt/device-mapper (forced update) ++ + eb12874...48b17e1 master -> quilt/device-mapper (forced update) +Importing aoe based on v2.6.31-rc9 +Unchanged quilt series aoe +Importing driver-core based on quilt/usb.current -+ quilt series is empty -+$ git update-ref refs/heads/quilt/driver-core 28640c0b4caf0d045ffa1dc12e3b46bdfd2bb6e0 ++Unchanged quilt series driver-core +Importing tty based on quilt/driver-core -+ quilt series is empty -+$ git update-ref refs/heads/quilt/tty 28640c0b4caf0d045ffa1dc12e3b46bdfd2bb6e0 ++Unchanged quilt series tty +Importing usb based on quilt/tty -+$ cd ../quilt-tmp -+$ git reset --hard 28640c0b4caf0d045ffa1dc12e3b46bdfd2bb6e0 -+HEAD is now at 28640c0 USB: Fix SS endpoint companion descriptor parsing. -+$ git quiltimport --author Greg KH --patches ../quilt/usb -+usb-ehci-dbg.c-no-need-for-checking-it-before-call-vfree.patch -+usb-sisusbvga-drop-usb_buffer_alloc.patch -+usb-usbmon-drop-kconfig-defaults.patch -+usb-usbmon-touch-up-the-documentation.patch -+usb-usbmon-end-ugly-tricks-with-dma-peeking.patch -+usb-let-usb_sg_init-to-set-transfer_buffer-more-often.patch -+usb-move-endpoint-sync-type-definitions-from-usb-audio.h-to-usb-ch9.h.patch -+usb-move-vendor-subclass-definition-from-usb-audio.h-to-usb-ch9.h.patch -+usb-audio-gadget-prefix-all-macro-definitions-with-uac_-in-linux-usb-audio.h.patch -+usb-audio-gadget-un-inline-generic_et_cmd.patch -+usb-add-nuvoton-ehci-driver-for-w90p910-platform.patch -+usb-whci-hcd-make-endpoint_reset-method-async.patch -+usb-add-api-for-userspace-drivers-to-claim-ports.patch -+usb-make-intf.pm_usage-an-atomic_t.patch -+usb-make-the-usbfs_snoop-log-more-pertinent.patch -+usb-gadget-pxa25x-basic-transceiver-support.patch -+usb-serial-full-autosuspend-support-for-the-option-driver.patch -+usb-usb-serial-remove-unused-variables.patch -+usb-usbtmc-can-do-io-to-device-after-disconnect.patch -+usb-suspend-resume-support-for-usbtmc.patch -+usb-legousbtower-make-poll-notice-disconnect.patch -+usb-ldusb-should-signal-an-error-in-poll-if-the-device-is-disconnected.patch -+usb-gadget-drop-null-test-on-list_entry-result.patch -+usb-gadget-s3c-hsotg-missing-parentheses.patch -+usb-full-power-management-support-for-the-idmouse-driver.patch -+usb-full-autosuspend-and-power-management-support-for-usbsevseg.patch -+usb-ehci-add-need_io_watchdog-flag-to-ehci_hcd.patch -+usb-ehci-split-ehci_qh-into-hw-and-sw-parts.patch -+usb-ehci-add-intel-moorestown-ehci-controller-hostpcx-extensions-and-support-phy-low-power-mode.patch -+usb-isp1760-allow-platform-devices-to-customize-devflags.patch -+usb-serial-spelling-correction-in-motorola-usb-phone-driver.patch -+usb-storage-drop-an-unneeded-a-null-test.patch -+usb-au1xxx-add-dev_pm_ops.patch -+usb-fix-wrong-order-of-events-in-usb-serial-suspension.patch -+usb-check-for-hub-driver-not-bound-to-root-hub-device.patch -+usb-don-t-lose-mode-switch-events-on-suspended-devices.patch -+usb-dummy-hcd-accept-mismatch-between-wlength-and-transfer-length.patch -+usb-nxp-isp1362-usb-host-driver.patch -+usb-usbtmc-sanity-checks-for-dev_dep_msg_in-urbs.patch -+usb-usbtmc-fix-printk-format-warnings.patch -+usb-uhci-rm-repeatedly-evaluation-for-urbp-qh.patch -+usb-at91-add-usb-ehci-driver-for-at91sam9g45-series.patch -+usb-at91-add-usb-gadget-driver-selection-for-at91sam9g45-series.patch -+usb-at91-modify-ohci-driver-to-allow-shared-interrupts.patch -+usb-audio-guard-kernel-only-code-with-__kernel__.patch -+usb-ehci-ohci-remove-unnecessary-includes-of-reboot.h.patch -+usb-ohci-pxa27x-allow-nocp-and-ocpm-to-be-cleared.patch -+usb-ark3116-add-irda-support-for-gembird-uir-22.patch -+usb-usb-storage-fails-to-attach-to-huawei-datacard-cdrom-device.patch -+usb-gadget-read-buffer-overflow.patch -+usb-gadget-audio-driver-seg-fault-fix.patch -+usb-isp1362-fix-pulldown-register-defines-and-conf-logic.patch -+usb-increase-usbdevfs-max-isoc-buffer-size.patch -+usb-work-around-bios-bugs-by-quiescing-usb-controllers-earlier.patch -+usb-musb-fix-put_device-call-sequence.patch -+usb-otg-twl4030-usb.c-mark-.init-as-subsys_initcall_sync.patch -+usb-ehci-ensure-all-watchdog-timer-events-are-deleted-when-suspending-usb.patch -+usb-isp1362-correct-use-of-and.patch -+usb-gadget-update-freescale-udc-entry-in-maintainers.patch -+usb-fix-cdc-eem-host-driver-sentinel-crc-validation.patch -+usb-otg-fix-twl4030-usb-build.patch -+usb-ohci-ep93xx.c-remove-unused-variable.patch -+usb-use-kfifo-to-buffer-usb-generic-serial-writes.patch -+usb-remove-unneeded-printks-from-microtek-driver.patch -+usb-gadget-add-eem-gadget-driver.patch -+usb-s3c2410-unregister-should-call-unbind-not-disconnect.patch -+usb-break-support-for-winchiphead-ch341-340-usb-serial-chip.patch -+usb-usbtmc-fix-short-reads-in-usbtmc_read.patch -+usb-usbtmc-inhibit-corruption.patch -+usb-usbtmc-correct-termination-condition-for-reads.patch -+usb-iuu_phoenix-don-t-reset-the-device-at-close.patch -+usb-iuu_phoenix-clean-up-parameter-s-descriptions.patch -+usb-iuu_phoenix-add-support-for-changing-vcc.patch -+usb-iuu_phoenix-increment-version-number.patch -+usb-iuu_phoenix-add-a-way-to-select-the-default-vcc.patch -+usb-serial-pl2303-fix-baud-rate-handling-in-case-of-unsupported-values.patch -+usb-serial-pl2303-add-space-mark-parity.patch -+usb-serial-pl2303-use-1.5-instead-of-2-stop-bits-with-5-data-bits.patch -+usb-fsl_qe_udc-add-fsl-mpc8323-qe-usb-compatible-entry.patch -+usb-ehci-rescan-the-queue-after-an-unlink.patch -+usb-ehci-change-deschedule-logic-for-interrupt-qhs.patch -+usb-make-usb_buffer_map_sg-consistent-with-doc.patch -+usb-double-put_tty_driver-in-gserial_setup.patch -+usb-clean-up-root-hub-string-descriptors.patch -+usb-gadget-double-free_irq-in-at91udc_probe.patch -+usb-omap-isp1301-compile-fix.patch -+usb-fix-paths-in-usbmon-documentation.patch -+usb-unusual_devs.h-drop-some-unneeded-floppy-entries.patch -+usb-ehci-dbgp-early_printk-split-ehci-debug-driver-from-early_printk.c.patch -+usb-dbgp-insert-cr-prior-to-nl-as-needed.patch -+usb-ehci-dbgp-execute-early-bios-hand-off.patch -+usb-dbgp-ehci-debug-controller-initialization-delays.patch -+early_printk-allow-more-than-one-early-console.patch -+usb-ehci-dbgp-stability-improvements-and-external-re-init.patch -+usb-ehci-dbgp-ehci-allow-early-or-late-use-of-the-dbgp-device.patch -+usb-ehci-dbgp-errata-for-ehci-debug-controller-initialization.patch -+usb-ehci-dbgp-errata-for-ehci-debug-host-controller-synchronization.patch -+usb-ehci-dbgp-documentation-documentation-updates-for-ehci-dbgp.patch -+usb-ehci-dbgp-ehci-allow-dbpg-to-work-with-suspend-resume.patch -+usb-support-for-autosuspend-in-sierra-while-online.patch -+usb-usbfs-add-usbdevfs_urb_bulk_continuation-flag.patch -+usb-fix-missing-error-check-in-probing.patch -+usb-fix-usbtmc-get_capabilities-success-handling.patch -+usb-gadget-ether-needs-to-select-crc32.patch -+usb-xhci-endpoint-representation-refactoring.patch -+usb-xhci-refactor-input-device-context-setup.patch -+usb-xhci-change-how-xhci-commands-are-handled.patch -+usb-xhci-fix-command-wait-list-handling.patch -+usb-xhci-set-route-string-for-all-devices.patch -+usb-xhci-set-multi-tt-field-for-ls-fs-devices-under-hubs.patch -+usb-xhci-support-usb-hubs.patch -+usb-add-hub-descriptor-update-hook-for-xhci.patch -+usb-skel_read-really-sucks-royally.patch -+usb-make-usb-skeleton-honor-o_nonblock-in-write-path.patch -+usb-o_nonblock-in-read-path-of-skeleton.patch -+usb-skeleton-fix-coding-style-issues.patch -+usb-fix-sysfs-paths-in-documentation.patch -+$ cd ../next -+$ git fetch -f ../quilt-tmp master:quilt/usb -+From ../quilt-tmp -+ + 3f5a8f6...e3e26b0 master -> quilt/usb (forced update) ++Unchanged quilt series usb +Importing staging based on quilt/usb -+$ cd ../quilt-tmp -+$ git reset --hard e3e26b02648f9f4ed34de39aeda66a4830125c17 -+HEAD is now at e3e26b0 USB: Fix sysfs paths in documentation -+$ git quiltimport --author Greg KH --patches ../quilt/staging -+staging-remove-agnx-driver.patch -+staging-w35und-fix-beacon_int-breakage.patch -+$ cd ../next -+$ git fetch -f ../quilt-tmp master:quilt/staging -+From ../quilt-tmp -+ + 3f5a8f6...586f9ab master -> quilt/staging (forced update) ++Unchanged quilt series staging diff --git a/arch/Kconfig b/arch/Kconfig index 99193b1..7f418bb 100644 --- a/arch/Kconfig @@ -58989,6 +59418,19 @@ index 26c1791..a94d48b 100644 /* GATT allocation. Returns/accepts GATT kernel virtual address. */ #define alloc_gatt_pages(order) \ ((char *)__get_free_pages(GFP_KERNEL, (order))) +diff --git a/arch/alpha/include/asm/fcntl.h b/arch/alpha/include/asm/fcntl.h +index 25da001..e42823e 100644 +--- a/arch/alpha/include/asm/fcntl.h ++++ b/arch/alpha/include/asm/fcntl.h +@@ -26,6 +26,8 @@ + #define F_GETOWN 6 /* for sockets. */ + #define F_SETSIG 10 /* for sockets. */ + #define F_GETSIG 11 /* for sockets. */ ++#define F_SETOWN_EX 12 ++#define F_GETOWN_EX 13 + + /* for posix fcntl() and lockf() */ + #define F_RDLCK 1 diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h index 8897146..242c09b 100644 --- a/arch/alpha/include/asm/hardirq.h @@ -59264,8 +59706,47 @@ index b4f284c..36b3a30 100644 #define cpumask_of_pcibus(bus) (cpu_online_mask) #endif /* !CONFIG_NUMA */ +diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c +index e302dae..8e059e5 100644 +--- a/arch/alpha/kernel/core_marvel.c ++++ b/arch/alpha/kernel/core_marvel.c +@@ -1016,7 +1016,7 @@ marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *m + { + struct marvel_agp_aperture *aper = agp->aperture.sysdata; + return iommu_bind(aper->arena, aper->pg_start + pg_start, +- mem->page_count, mem->memory); ++ mem->page_count, mem->pages); + } + + static int +diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c +index 319fcb7..7668649 100644 +--- a/arch/alpha/kernel/core_titan.c ++++ b/arch/alpha/kernel/core_titan.c +@@ -680,7 +680,7 @@ titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *me + { + struct titan_agp_aperture *aper = agp->aperture.sysdata; + return iommu_bind(aper->arena, aper->pg_start + pg_start, +- mem->page_count, mem->memory); ++ mem->page_count, mem->pages); + } + + static int +diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h +index 00edd04..85457b2 100644 +--- a/arch/alpha/kernel/pci_impl.h ++++ b/arch/alpha/kernel/pci_impl.h +@@ -198,7 +198,7 @@ extern unsigned long size_for_memory(unsigned long max); + + extern int iommu_reserve(struct pci_iommu_arena *, long, long); + extern int iommu_release(struct pci_iommu_arena *, long, long); +-extern int iommu_bind(struct pci_iommu_arena *, long, long, unsigned long *); ++extern int iommu_bind(struct pci_iommu_arena *, long, long, struct page **); + extern int iommu_unbind(struct pci_iommu_arena *, long, long); + + diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c -index bfb880a..d15aedf 100644 +index bfb880a..8449504 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c @@ -268,11 +268,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size, @@ -59281,6 +59762,36 @@ index bfb880a..d15aedf 100644 return 0; } +@@ -880,7 +876,7 @@ iommu_release(struct pci_iommu_arena *arena, long pg_start, long pg_count) + + int + iommu_bind(struct pci_iommu_arena *arena, long pg_start, long pg_count, +- unsigned long *physaddrs) ++ struct page **pages) + { + unsigned long flags; + unsigned long *ptes; +@@ -900,7 +896,7 @@ iommu_bind(struct pci_iommu_arena *arena, long pg_start, long pg_count, + } + + for(i = 0, j = pg_start; i < pg_count; i++, j++) +- ptes[j] = mk_iommu_pte(physaddrs[i]); ++ ptes[j] = mk_iommu_pte(page_to_phys(pages[i])); + + spin_unlock_irqrestore(&arena->lock, flags); + +diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c +index 3a2fb7a..289039b 100644 +--- a/arch/alpha/kernel/process.c ++++ b/arch/alpha/kernel/process.c +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index df65eaa..0932dbb 100644 --- a/arch/alpha/kernel/signal.c @@ -80909,6 +81420,18 @@ index 9f444e5..20b7411 100644 int (*fn)(struct stackframe *, void *), void *data) { while (1) { +diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c +index b3ec641..78ecaac 100644 +--- a/arch/arm/kernel/sys_arm.c ++++ b/arch/arm/kernel/sys_arm.c +@@ -25,7 +25,6 @@ + #include + #include + #include +-#include + #include + #include + diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c new file mode 100644 index 0000000..e503038 @@ -82517,7 +83040,7 @@ index 3acd7d7..4ecf379 100644 pm_power_off = at91sam9261_poweroff; at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c -index b7f2332..55719a9 100644 +index b7f2332..fb5c23a 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -707,9 +707,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) @@ -82552,7 +83075,7 @@ index b7f2332..55719a9 100644 { if (!data) return; -@@ -750,11 +750,11 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) +@@ -750,13 +750,49 @@ void __init at91_add_device_ac97(struct atmel_ac97_data *data) if (data->reset_pin) at91_set_gpio_output(data->reset_pin, 0); @@ -82565,7 +83088,45 @@ index b7f2332..55719a9 100644 +void __init at91_add_device_ac97(struct ac97c_platform_data *data) {} #endif ++/* -------------------------------------------------------------------- ++ * CAN Controller ++ * -------------------------------------------------------------------- */ ++ ++#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE) ++static struct resource can_resources[] = { ++ [0] = { ++ .start = AT91SAM9263_BASE_CAN, ++ .end = AT91SAM9263_BASE_CAN + SZ_16K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = AT91SAM9263_ID_CAN, ++ .end = AT91SAM9263_ID_CAN, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device at91sam9263_can_device = { ++ .name = "at91_can", ++ .id = -1, ++ .resource = can_resources, ++ .num_resources = ARRAY_SIZE(can_resources), ++}; ++ ++void __init at91_add_device_can(struct at91_can_data *data) ++{ ++ at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */ ++ at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */ ++ at91sam9263_can_device.dev.platform_data = data; ++ ++ platform_device_register(&at91sam9263_can_device); ++} ++#else ++void __init at91_add_device_can(struct at91_can_data *data) {} ++#endif + /* -------------------------------------------------------------------- + * LCD Controller diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c new file mode 100644 index 0000000..85166b7 @@ -85157,7 +85718,7 @@ index d5266da..c4c8865 100644 .phys_io = AT91_BASE_SYS, .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c -index 57d5252..26f1aa6 100644 +index 57d5252..2d867fb 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c @@ -57,7 +57,7 @@ static void __init ek_map_io(void) @@ -85181,6 +85742,39 @@ index 57d5252..26f1aa6 100644 }; +@@ -400,6 +400,23 @@ static struct gpio_led ek_pwm_led[] = { + } + }; + ++/* ++ * CAN ++ */ ++static void sam9263ek_transceiver_switch(int on) ++{ ++ if (on) { ++ at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */ ++ at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */ ++ } else { ++ at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */ ++ at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */ ++ } ++} ++ ++static struct at91_can_data ek_can_data = { ++ .transceiver_switch = sam9263ek_transceiver_switch, ++}; + + static void __init ek_board_init(void) + { +@@ -431,6 +448,8 @@ static void __init ek_board_init(void) + /* LEDs */ + at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds)); + at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led)); ++ /* CAN */ ++ at91_add_device_can(&ek_can_data); + } + + MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c new file mode 100644 index 0000000..a28e53f @@ -86579,7 +87173,7 @@ index 0000000..c972d60 + +#endif diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h -index e6afff8..583f38a 100644 +index e6afff8..2f4fced 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -37,6 +37,8 @@ @@ -86651,6 +87245,19 @@ index e6afff8..583f38a 100644 /* ISI */ extern void __init at91_add_device_isi(void); +@@ -179,6 +188,12 @@ extern void __init at91_add_device_isi(void); + /* Touchscreen Controller */ + extern void __init at91_add_device_tsadcc(void); + ++/* CAN */ ++struct at91_can_data { ++ void (*transceiver_switch)(int on); ++}; ++extern void __init at91_add_device_can(struct at91_can_data *data); ++ + /* LEDs */ + extern void __init at91_init_leds(u8 cpu_led, u8 timer_led); + extern void __init at91_gpio_leds(struct gpio_led *leds, int nr); diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index c554c3e..34a9502 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h @@ -121659,10 +122266,10 @@ index 0000000..c7e75ac + diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c new file mode 100644 -index 0000000..6bfd537 +index 0000000..781b915 --- /dev/null +++ b/arch/arm/mach-nomadik/board-nhk8815.c -@@ -0,0 +1,266 @@ +@@ -0,0 +1,267 @@ +/* + * linux/arch/arm/mach-nomadik/board-8815nhk.c + * @@ -121683,6 +122290,7 @@ index 0000000..6bfd537 +#include +#include +#include ++#include +#include +#include +#include @@ -121807,7 +122415,7 @@ index 0000000..6bfd537 + } +}; + -+static struct flash_platform_data nhk8815_onenand_data = { ++static struct onenand_platform_data nhk8815_onenand_data = { + .parts = nhk8815_onenand_partitions, + .nr_parts = ARRAY_SIZE(nhk8815_onenand_partitions), +}; @@ -121821,7 +122429,7 @@ index 0000000..6bfd537 +}; + +static struct platform_device nhk8815_onenand_device = { -+ .name = "onenand", ++ .name = "onenand-flash", + .id = -1, + .dev = { + .platform_data = &nhk8815_onenand_data, @@ -121832,10 +122440,10 @@ index 0000000..6bfd537 + +static void __init nhk8815_onenand_init(void) +{ -+#ifdef CONFIG_ONENAND ++#ifdef CONFIG_MTD_ONENAND + /* Set up SMCS0 for OneNand */ -+ writel(0x000030db, FSMC_BCR0); -+ writel(0x02100551, FSMC_BTR0); ++ writel(0x000030db, FSMC_BCR(0)); ++ writel(0x02100551, FSMC_BTR(0)); +#endif +} + @@ -167492,7 +168100,7 @@ index f5a3c30..e565aae 100644 .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, }; diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c -index dc0dd9b..c66f380 100644 +index dc0dd9b..383a18c 100644 --- a/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/arch/blackfin/mach-bf548/boards/ezkit.c @@ -99,8 +99,8 @@ static struct platform_device bfin_isp1760_device = { @@ -167506,7 +168114,15 @@ index dc0dd9b..c66f380 100644 .xres = {480, 480, 480}, .yres = {272, 272, 272}, .bpp = {24, 24, 24}, -@@ -702,7 +702,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { +@@ -208,7 +208,6 @@ static struct platform_device bfin_rotary_device = { + #endif + + #if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) +-#include + #include + static const struct adxl34x_platform_data adxl34x_info = { + .x_axis_offset = 0, +@@ -702,7 +701,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) { @@ -167515,7 +168131,7 @@ index dc0dd9b..c66f380 100644 .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 1, .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, -@@ -783,7 +783,7 @@ static struct resource bfin_spi1_resource[] = { +@@ -783,7 +782,7 @@ static struct resource bfin_spi1_resource[] = { /* SPI controller data */ static struct bfin5xx_spi_master bf54x_spi_master_info0 = { @@ -167524,7 +168140,7 @@ index dc0dd9b..c66f380 100644 .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0}, }; -@@ -799,7 +799,7 @@ static struct platform_device bf54x_spi_master0 = { +@@ -799,7 +798,7 @@ static struct platform_device bf54x_spi_master0 = { }; static struct bfin5xx_spi_master bf54x_spi_master_info1 = { @@ -167533,7 +168149,7 @@ index dc0dd9b..c66f380 100644 .enable_dma = 1, /* master has the ability to do dma transfer */ .pin_req = {P_SPI1_SCK, P_SPI1_MISO, P_SPI1_MOSI, 0}, }; -@@ -869,7 +869,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { +@@ -869,7 +868,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info1[] = { I2C_BOARD_INFO("pcf8574_lcd", 0x22), }, #endif @@ -170114,6 +170730,67 @@ index 1d3df1d..3c3e0b3 100644 /* * Initial task structure. +diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c +index be722fc..0d4d3e3 100644 +--- a/arch/frv/kernel/pm.c ++++ b/arch/frv/kernel/pm.c +@@ -150,7 +150,7 @@ static int user_atoi(char __user *ubuf, size_t len) + /* + * Send us to sleep. + */ +-static int sysctl_pm_do_suspend(ctl_table *ctl, int write, struct file *filp, ++static int sysctl_pm_do_suspend(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *fpos) + { + int retval, mode; +@@ -198,13 +198,13 @@ static int try_set_cmode(int new_cmode) + } + + +-static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, ++static int cmode_procctl(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *fpos) + { + int new_cmode; + + if (!write) +- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos); ++ return proc_dointvec(ctl, write, buffer, lenp, fpos); + + new_cmode = user_atoi(buffer, *lenp); + +@@ -301,13 +301,13 @@ static int try_set_cm(int new_cm) + return 0; + } + +-static int p0_procctl(ctl_table *ctl, int write, struct file *filp, ++static int p0_procctl(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *fpos) + { + int new_p0; + + if (!write) +- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos); ++ return proc_dointvec(ctl, write, buffer, lenp, fpos); + + new_p0 = user_atoi(buffer, *lenp); + +@@ -345,13 +345,13 @@ static int p0_sysctl(ctl_table *table, + return 1; + } + +-static int cm_procctl(ctl_table *ctl, int write, struct file *filp, ++static int cm_procctl(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *fpos) + { + int new_cm; + + if (!write) +- return proc_dointvec(ctl, write, filp, buffer, lenp, fpos); ++ return proc_dointvec(ctl, write, buffer, lenp, fpos); + + new_cm = user_atoi(buffer, *lenp); + diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c index 0de50df..9042559 100644 --- a/arch/frv/kernel/process.c @@ -170145,6 +170822,18 @@ index 4a7a62c..6b0a2b6 100644 } } /* end do_notify_resume() */ +diff --git a/arch/frv/kernel/sys_frv.c b/arch/frv/kernel/sys_frv.c +index baadc97..2b6b528 100644 +--- a/arch/frv/kernel/sys_frv.c ++++ b/arch/frv/kernel/sys_frv.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + #include + diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index 22d9787..cbe811f 100644 --- a/arch/frv/kernel/vmlinux.lds.S @@ -170512,6 +171201,18 @@ index cf3472f..af842c3 100644 + key_replace_session_keyring(); + } } +diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c +index 2745656..8cb5d73 100644 +--- a/arch/h8300/kernel/sys_h8300.c ++++ b/arch/h8300/kernel/sys_h8300.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + #include + #include + diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c index e7c6e61..2193a2e 100644 --- a/arch/h8300/kernel/timer/tpu.c @@ -177071,6 +177772,18 @@ index 72bad65..41230c5 100644 /* initial task structure */ struct task_struct init_task = INIT_TASK(init_task); +diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c +index 7f54efa..7deb402 100644 +--- a/arch/m68k/kernel/sys_m68k.c ++++ b/arch/m68k/kernel/sys_m68k.c +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + + #include diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c index 54d9807..17dc2a3 100644 --- a/arch/m68k/kernel/time.c @@ -177462,6 +178175,18 @@ index ef70ca0..4d38289 100644 } long arch_ptrace(struct task_struct *child, long request, long addr, long data) +diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c +index 7002816..efdd090 100644 +--- a/arch/m68knommu/kernel/sys_m68k.c ++++ b/arch/m68knommu/kernel/sys_m68k.c +@@ -17,7 +17,6 @@ + #include + #include + #include +-#include + #include + #include + diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S index 0ae123e..23535cc 100644 --- a/arch/m68knommu/kernel/syscalltable.S @@ -182318,10 +183043,97 @@ index 0000000..cb2b537 +.incbin "arch/microblaze/boot/system.dtb" + diff --git a/arch/microblaze/configs/mmu_defconfig b/arch/microblaze/configs/mmu_defconfig -index 09c3296..ccfc52f 100644 +index 09c3296..bb7c374 100644 --- a/arch/microblaze/configs/mmu_defconfig +++ b/arch/microblaze/configs/mmu_defconfig -@@ -682,7 +682,7 @@ CONFIG_DEBUG_INFO=y +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.31-rc6 +-# Tue Aug 18 11:00:02 2009 ++# Linux kernel version: 2.6.31 ++# Thu Sep 24 10:28:50 2009 + # + CONFIG_MICROBLAZE=y + # CONFIG_SWAP is not set +@@ -42,11 +42,12 @@ CONFIG_SYSVIPC_SYSCTL=y + # + # RCU Subsystem + # +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set ++CONFIG_TREE_RCU=y ++# CONFIG_TREE_PREEMPT_RCU is not set ++# CONFIG_RCU_TRACE is not set ++CONFIG_RCU_FANOUT=32 ++# CONFIG_RCU_FANOUT_EXACT is not set + # CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=17 +@@ -260,6 +261,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_NETFILTER is not set + # CONFIG_IP_DCCP is not set + # CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +@@ -357,12 +359,10 @@ CONFIG_NET_ETHERNET=y + # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set + # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_KS8842 is not set ++CONFIG_XILINX_EMACLITE=y + CONFIG_NETDEV_1000=y + CONFIG_NETDEV_10000=y +- +-# +-# Wireless LAN +-# ++CONFIG_WLAN=y + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + +@@ -460,6 +460,7 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y + # CONFIG_DISPLAY_SUPPORT is not set + # CONFIG_SOUND is not set + # CONFIG_USB_SUPPORT is not set ++CONFIG_USB_ARCH_HAS_EHCI=y + # CONFIG_MMC is not set + # CONFIG_MEMSTICK is not set + # CONFIG_NEW_LEDS is not set +@@ -488,6 +489,7 @@ CONFIG_EXT2_FS=y + # CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set + # CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set + CONFIG_FILE_LOCKING=y + CONFIG_FSNOTIFY=y + # CONFIG_DNOTIFY is not set +@@ -546,7 +548,6 @@ CONFIG_MISC_FILESYSTEMS=y + # CONFIG_ROMFS_FS is not set + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set +-# CONFIG_NILFS2_FS is not set + CONFIG_NETWORK_FILESYSTEMS=y + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y +@@ -671,18 +672,20 @@ CONFIG_DEBUG_INFO=y + # CONFIG_DEBUG_LIST is not set + # CONFIG_DEBUG_SG is not set + # CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS 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_DEBUG_FORCE_WEAK_PER_CPU is not set + # CONFIG_FAULT_INJECTION is not set + # CONFIG_SYSCTL_SYSCALL_CHECK is not set + # CONFIG_PAGE_POISONING is not set # CONFIG_SAMPLES is not set # CONFIG_KMEMCHECK is not set CONFIG_EARLY_PRINTK=y @@ -182330,11 +183142,153 @@ index 09c3296..ccfc52f 100644 CONFIG_DEBUG_BOOTMEM=y # +@@ -697,7 +700,6 @@ CONFIG_CRYPTO=y + # + # Crypto core or helper + # +-# CONFIG_CRYPTO_FIPS is not set + # CONFIG_CRYPTO_MANAGER is not set + # CONFIG_CRYPTO_MANAGER2 is not set + # CONFIG_CRYPTO_GF128MUL is not set +@@ -729,11 +731,13 @@ CONFIG_CRYPTO=y + # + # CONFIG_CRYPTO_HMAC is not set + # CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set + + # + # Digest + # + # CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_GHASH is not set + # CONFIG_CRYPTO_MD4 is not set + # CONFIG_CRYPTO_MD5 is not set + # CONFIG_CRYPTO_MICHAEL_MIC is not set diff --git a/arch/microblaze/configs/nommu_defconfig b/arch/microblaze/configs/nommu_defconfig -index 8b63861..4fafa06 100644 +index 8b63861..adb839b 100644 --- a/arch/microblaze/configs/nommu_defconfig +++ b/arch/microblaze/configs/nommu_defconfig -@@ -721,7 +721,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y +@@ -1,7 +1,7 @@ + # + # Automatically generated make config: don't edit +-# Linux kernel version: 2.6.31-rc6 +-# Tue Aug 18 10:35:30 2009 ++# Linux kernel version: 2.6.31 ++# Thu Sep 24 10:29:43 2009 + # + CONFIG_MICROBLAZE=y + # CONFIG_SWAP is not set +@@ -44,11 +44,12 @@ CONFIG_BSD_PROCESS_ACCT_V3=y + # + # RCU Subsystem + # +-CONFIG_CLASSIC_RCU=y +-# CONFIG_TREE_RCU is not set +-# CONFIG_PREEMPT_RCU is not set ++CONFIG_TREE_RCU=y ++# CONFIG_TREE_PREEMPT_RCU is not set ++# CONFIG_RCU_TRACE is not set ++CONFIG_RCU_FANOUT=32 ++# CONFIG_RCU_FANOUT_EXACT is not set + # CONFIG_TREE_RCU_TRACE is not set +-# CONFIG_PREEMPT_RCU_TRACE is not set + CONFIG_IKCONFIG=y + CONFIG_IKCONFIG_PROC=y + CONFIG_LOG_BUF_SHIFT=17 +@@ -243,6 +244,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_NETFILTER is not set + # CONFIG_IP_DCCP is not set + # CONFIG_IP_SCTP is not set ++# CONFIG_RDS is not set + # CONFIG_TIPC is not set + # CONFIG_ATM is not set + # CONFIG_BRIDGE is not set +@@ -272,6 +274,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" + # CONFIG_AF_RXRPC is not set + CONFIG_WIRELESS=y + # CONFIG_CFG80211 is not set ++CONFIG_CFG80211_DEFAULT_PS_VALUE=0 + CONFIG_WIRELESS_OLD_REGULATORY=y + # CONFIG_WIRELESS_EXT is not set + # CONFIG_LIB80211 is not set +@@ -279,7 +282,6 @@ CONFIG_WIRELESS_OLD_REGULATORY=y + # + # CFG80211 needs to be enabled for MAC80211 + # +-CONFIG_MAC80211_DEFAULT_PS_VALUE=0 + # CONFIG_WIMAX is not set + # CONFIG_RFKILL is not set + # CONFIG_NET_9P is not set +@@ -304,6 +306,7 @@ CONFIG_MTD_PARTITIONS=y + # CONFIG_MTD_TESTS is not set + # CONFIG_MTD_REDBOOT_PARTS is not set + CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_OF_PARTS is not set + # CONFIG_MTD_AR7_PARTS is not set + + # +@@ -349,6 +352,7 @@ CONFIG_MTD_RAM=y + # + # CONFIG_MTD_COMPLEX_MAPPINGS is not set + # CONFIG_MTD_PHYSMAP is not set ++# CONFIG_MTD_PHYSMAP_OF is not set + CONFIG_MTD_UCLINUX=y + # CONFIG_MTD_PLATRAM is not set + +@@ -429,12 +433,10 @@ CONFIG_NET_ETHERNET=y + # CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set + # CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set + # CONFIG_KS8842 is not set ++# CONFIG_XILINX_EMACLITE is not set + CONFIG_NETDEV_1000=y + CONFIG_NETDEV_10000=y +- +-# +-# Wireless LAN +-# ++CONFIG_WLAN=y + # CONFIG_WLAN_PRE80211 is not set + # CONFIG_WLAN_80211 is not set + +@@ -535,7 +537,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=y + CONFIG_USB_SUPPORT=y + CONFIG_USB_ARCH_HAS_HCD=y + # CONFIG_USB_ARCH_HAS_OHCI is not set +-# CONFIG_USB_ARCH_HAS_EHCI is not set ++CONFIG_USB_ARCH_HAS_EHCI=y + # CONFIG_USB is not set + # CONFIG_USB_OTG_WHITELIST is not set + # CONFIG_USB_OTG_BLACKLIST_HUB is not set +@@ -579,6 +581,7 @@ CONFIG_FS_POSIX_ACL=y + # CONFIG_GFS2_FS is not set + # CONFIG_OCFS2_FS is not set + # CONFIG_BTRFS_FS is not set ++# CONFIG_NILFS2_FS is not set + CONFIG_FILE_LOCKING=y + CONFIG_FSNOTIFY=y + # CONFIG_DNOTIFY is not set +@@ -639,7 +642,6 @@ CONFIG_ROMFS_BACKED_BY_BLOCK=y + CONFIG_ROMFS_ON_BLOCK=y + # CONFIG_SYSV_FS is not set + # CONFIG_UFS_FS is not set +-# CONFIG_NILFS2_FS is not set + CONFIG_NETWORK_FILESYSTEMS=y + CONFIG_NFS_FS=y + CONFIG_NFS_V3=y +@@ -710,18 +712,20 @@ CONFIG_DEBUG_INFO=y + CONFIG_DEBUG_LIST=y + CONFIG_DEBUG_SG=y + # CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_CREDENTIALS 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_DEBUG_FORCE_WEAK_PER_CPU is not set + # CONFIG_FAULT_INJECTION is not set + CONFIG_SYSCTL_SYSCALL_CHECK=y + # CONFIG_PAGE_POISONING is not set # CONFIG_DYNAMIC_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_EARLY_PRINTK=y @@ -182343,6 +183297,28 @@ index 8b63861..4fafa06 100644 # CONFIG_DEBUG_BOOTMEM is not set # +@@ -736,7 +740,6 @@ CONFIG_CRYPTO=y + # + # Crypto core or helper + # +-# CONFIG_CRYPTO_FIPS is not set + # CONFIG_CRYPTO_MANAGER is not set + # CONFIG_CRYPTO_MANAGER2 is not set + # CONFIG_CRYPTO_GF128MUL is not set +@@ -768,11 +771,13 @@ CONFIG_CRYPTO=y + # + # CONFIG_CRYPTO_HMAC is not set + # CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_VMAC is not set + + # + # Digest + # + # CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_GHASH is not set + # CONFIG_CRYPTO_MD4 is not set + # CONFIG_CRYPTO_MD5 is not set + # CONFIG_CRYPTO_MICHAEL_MIC is not set diff --git a/arch/microblaze/include/asm/asm-compat.h b/arch/microblaze/include/asm/asm-compat.h new file mode 100644 index 0000000..e7bc9dc @@ -182974,6 +183950,18 @@ index 2a97bf5..8c1e0f4 100644 for (src = __ivt_start; src < __ivt_end; src++, dst++) *dst = *src; +diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c +index b96f168..07cabed 100644 +--- a/arch/microblaze/kernel/sys_microblaze.c ++++ b/arch/microblaze/kernel/sys_microblaze.c +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index 4572160..ecec191 100644 --- a/arch/microblaze/kernel/syscall_table.S @@ -196522,11 +197510,45 @@ index 52cb143..c6fd96f 100644 int rtc_mips_set_mmss(unsigned long time) diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c -index 8f88886..3f04d4c 100644 +index 8f88886..b3deed8 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c -@@ -92,10 +92,12 @@ static int rtctmp; - int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, +@@ -56,12 +56,12 @@ int sysctl_lasatstring(ctl_table *table, + + + /* And the same for proc */ +-int proc_dolasatstring(ctl_table *table, int write, struct file *filp, ++int proc_dolasatstring(ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int r; + +- r = proc_dostring(table, write, filp, buffer, lenp, ppos); ++ r = proc_dostring(table, write, buffer, lenp, ppos); + if ((!write) || r) + return r; + +@@ -71,12 +71,12 @@ int proc_dolasatstring(ctl_table *table, int write, struct file *filp, + } + + /* proc function to write EEPROM after changing int entry */ +-int proc_dolasatint(ctl_table *table, int write, struct file *filp, ++int proc_dolasatint(ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int r; + +- r = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ r = proc_dointvec(table, write, buffer, lenp, ppos); + if ((!write) || r) + return r; + +@@ -89,18 +89,20 @@ int proc_dolasatint(ctl_table *table, int write, struct file *filp, + static int rtctmp; + + /* proc function to read/write RealTime Clock */ +-int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, ++int proc_dolasatrtc(ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) { + struct timespec ts; @@ -196539,6 +197561,12 @@ index 8f88886..3f04d4c 100644 /* check for time < 0 and set to 0 */ if (rtctmp < 0) rtctmp = 0; + } +- r = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ r = proc_dointvec(table, write, buffer, lenp, ppos); + if (r) + return r; + @@ -134,9 +136,11 @@ int sysctl_lasat_rtc(ctl_table *table, void *oldval, size_t *oldlenp, void *newval, size_t newlen) @@ -196552,6 +197580,30 @@ index 8f88886..3f04d4c 100644 if (rtctmp < 0) rtctmp = 0; r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); +@@ -150,7 +154,7 @@ int sysctl_lasat_rtc(ctl_table *table, + #endif + + #ifdef CONFIG_INET +-int proc_lasat_ip(ctl_table *table, int write, struct file *filp, ++int proc_lasat_ip(ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + unsigned int ip; +@@ -227,12 +231,12 @@ static int sysctl_lasat_prid(ctl_table *table, + return 0; + } + +-int proc_lasat_prid(ctl_table *table, int write, struct file *filp, ++int proc_lasat_prid(ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int r; + +- r = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ r = proc_dointvec(table, write, buffer, lenp, ppos); + if (r < 0) + return r; + if (write) { diff --git a/arch/mips/lemote/lm2e/Makefile b/arch/mips/lemote/lm2e/Makefile deleted file mode 100644 index d34671d..0000000 @@ -200710,6 +201762,18 @@ index feb2f2e..a21f43b 100644 + key_replace_session_keyring(); } } +diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c +index 3e52a10..8ca5af0 100644 +--- a/arch/mn10300/kernel/sys_mn10300.c ++++ b/arch/mn10300/kernel/sys_mn10300.c +@@ -19,7 +19,6 @@ + #include + #include + #include +-#include + #include + + #include diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S index f4aa079..76f41bd 100644 --- a/arch/mn10300/kernel/vmlinux.lds.S @@ -200800,6 +201864,19 @@ index 9c802eb..b12dfc9 100644 #define ELF_EXEC_PAGESIZE 4096 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical +diff --git a/arch/parisc/include/asm/fcntl.h b/arch/parisc/include/asm/fcntl.h +index 1e1c824..5f39d55 100644 +--- a/arch/parisc/include/asm/fcntl.h ++++ b/arch/parisc/include/asm/fcntl.h +@@ -28,6 +28,8 @@ + #define F_SETOWN 12 /* for sockets. */ + #define F_SETSIG 13 /* for sockets. */ + #define F_GETSIG 14 /* for sockets. */ ++#define F_GETOWN_EX 15 ++#define F_SETOWN_EX 16 + + /* for posix fcntl() and lockf() */ + #define F_RDLCK 01 diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h index ce93133..0d68184 100644 --- a/arch/parisc/include/asm/hardirq.h @@ -201780,6 +202857,18 @@ index f825442..c5f3d82 100644 + key_replace_session_keyring(); + } } +diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c +index 92a0aca..561388b 100644 +--- a/arch/parisc/kernel/sys_parisc32.c ++++ b/arch/parisc/kernel/sys_parisc32.c +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 59fc1a4..f5f9602 100644 --- a/arch/parisc/kernel/syscall.S @@ -201891,7 +202980,7 @@ index b0831d9..d5aca31 100644 codesize >> 10, reservedpages << (PAGE_SHIFT-10), diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig -index d00131c..4fd4790 100644 +index d00131c..10a0a54 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -49,6 +49,9 @@ config GENERIC_HARDIRQS_NO__DO_IRQ @@ -201931,7 +203020,23 @@ index d00131c..4fd4790 100644 config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC) -@@ -472,7 +472,7 @@ config PPC_16K_PAGES +@@ -385,9 +385,15 @@ config NUMA + + config NODES_SHIFT + int ++ default "8" if PPC64 + default "4" + depends on NEED_MULTIPLE_NODES + ++config MAX_ACTIVE_REGIONS ++ int ++ default "256" if PPC64 ++ default "32" ++ + config ARCH_SELECT_MEMORY_MODEL + def_bool y + depends on PPC64 +@@ -472,7 +478,7 @@ config PPC_16K_PAGES bool "16k page size" if 44x config PPC_64K_PAGES @@ -201940,7 +203045,7 @@ index d00131c..4fd4790 100644 select PPC_HAS_HASH_64K if PPC_STD_MMU_64 config PPC_256K_PAGES -@@ -492,16 +492,16 @@ endchoice +@@ -492,16 +498,16 @@ endchoice config FORCE_MAX_ZONEORDER int "Maximum zone order" @@ -201968,7 +203073,7 @@ index d00131c..4fd4790 100644 default "11" help diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile -index bc35f4e..aacf629 100644 +index bc35f4e..1a54a3b 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -77,7 +77,7 @@ CPP = $(CC) -E $(KBUILD_CFLAGS) @@ -201980,7 +203085,7 @@ index bc35f4e..aacf629 100644 ifeq ($(CONFIG_POWER4_ONLY),y) ifeq ($(CONFIG_ALTIVEC),y) -@@ -158,8 +158,6 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ +@@ -158,14 +158,23 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ # Default to zImage, override when needed all: zImage @@ -201989,7 +203094,24 @@ index bc35f4e..aacf629 100644 BOOT_TARGETS = zImage zImage.initrd uImage zImage% dtbImage% treeImage.% cuImage.% simpleImage.% PHONY += $(BOOT_TARGETS) -@@ -182,8 +180,8 @@ define archhelp + + boot := arch/$(ARCH)/boot + ++ifeq ($(CONFIG_RELOCATABLE),y) ++quiet_cmd_relocs_check = CALL $< ++ cmd_relocs_check = perl $< "$(OBJDUMP)" "$(obj)/vmlinux" ++ ++PHONY += relocs_check ++relocs_check: arch/powerpc/relocs_check.pl vmlinux ++ $(call cmd,relocs_check) ++ ++zImage: relocs_check ++endif ++ + $(BOOT_TARGETS): vmlinux + $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) + +@@ -182,8 +191,8 @@ define archhelp @echo ' simpleImage.
- Firmware independent image.' @echo ' treeImage.
- Support for older IBM 4xx firmware (not U-Boot)' @echo ' install - Install kernel using' @@ -209904,7 +211026,7 @@ index f42e623..fa19f3f 100644 { cputime_t ct; diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h -index 7d2277c..9dade15 100644 +index 7d2277c..6d94d27 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -6,7 +6,7 @@ @@ -209916,20 +211038,30 @@ index 7d2277c..9dade15 100644 struct device_node; struct dev_archdata { -@@ -14,8 +14,11 @@ struct dev_archdata { +@@ -14,8 +14,20 @@ struct dev_archdata { struct device_node *of_node; /* DMA operations on that device */ - struct dma_mapping_ops *dma_ops; +- void *dma_data; + struct dma_map_ops *dma_ops; - void *dma_data; ++ ++ /* ++ * When an iommu is in use, dma_data is used as a ptr to the base of the ++ * iommu_table. Otherwise, it is a simple numerical offset. ++ */ ++ union { ++ dma_addr_t dma_offset; ++ void *iommu_table_base; ++ } dma_data; ++ +#ifdef CONFIG_SWIOTLB + dma_addr_t max_direct_dma_addr; +#endif }; static inline void dev_archdata_set_node(struct dev_archdata *ad, -@@ -30,4 +33,7 @@ dev_archdata_get_node(const struct dev_archdata *ad) +@@ -30,4 +42,7 @@ dev_archdata_get_node(const struct dev_archdata *ad) return ad->of_node; } @@ -209938,7 +211070,7 @@ index 7d2277c..9dade15 100644 + #endif /* _ASM_POWERPC_DEVICE_H */ diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h -index b44aaab..cb2ca41 100644 +index b44aaab..e281dae 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -14,6 +14,7 @@ @@ -209949,7 +211081,15 @@ index b44aaab..cb2ca41 100644 #include #include -@@ -64,58 +65,14 @@ static inline unsigned long device_to_mask(struct device *dev) +@@ -25,7 +26,6 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size, + extern void dma_direct_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +-extern unsigned long get_dma_direct_offset(struct device *dev); + + #ifdef CONFIG_NOT_COHERENT_CACHE + /* +@@ -64,58 +64,14 @@ static inline unsigned long device_to_mask(struct device *dev) } /* @@ -210011,7 +211151,7 @@ index b44aaab..cb2ca41 100644 { /* We don't handle the NULL dev case for ISA for now. We could * do it via an out of line call but it is not needed for now. The -@@ -128,14 +85,19 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) +@@ -128,14 +84,41 @@ static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) return dev->archdata.dma_ops; } @@ -210021,6 +211161,28 @@ index b44aaab..cb2ca41 100644 dev->archdata.dma_ops = ops; } ++/* ++ * get_dma_offset() ++ * ++ * Get the dma offset on configurations where the dma address can be determined ++ * from the physical address by looking at a simple offset. Direct dma and ++ * swiotlb use this function, but it is typically not used by implementations ++ * with an iommu. ++ */ ++static inline dma_addr_t get_dma_offset(struct device *dev) ++{ ++ if (dev) ++ return dev->archdata.dma_data.dma_offset; ++ ++ return PCI_DRAM_OFFSET; ++} ++ ++static inline void set_dma_offset(struct device *dev, dma_addr_t off) ++{ ++ if (dev) ++ dev->archdata.dma_data.dma_offset = off; ++} ++ +/* this will be removed soon */ +#define flush_write_buffers() + @@ -210033,7 +211195,7 @@ index b44aaab..cb2ca41 100644 if (unlikely(dma_ops == NULL)) return 0; -@@ -149,7 +111,7 @@ static inline int dma_supported(struct device *dev, u64 mask) +@@ -149,7 +132,7 @@ static inline int dma_supported(struct device *dev, u64 mask) static inline int dma_set_mask(struct device *dev, u64 dma_mask) { @@ -210042,7 +211204,7 @@ index b44aaab..cb2ca41 100644 if (unlikely(dma_ops == NULL)) return -EIO; -@@ -161,267 +123,70 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) +@@ -161,267 +144,70 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) return 0; } @@ -210192,24 +211354,26 @@ index b44aaab..cb2ca41 100644 - enum dma_data_direction direction) -{ - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); -- -- BUG_ON(!dma_ops); -- -- if (dma_ops->sync_single_range_for_cpu) -- dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, -- size, direction); --} -- --static inline void dma_sync_single_for_device(struct device *dev, -- dma_addr_t dma_handle, size_t size, -- enum dma_data_direction direction) --{ -- struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + struct dma_map_ops *dma_ops = get_dma_ops(dev); + void *cpu_addr; BUG_ON(!dma_ops); +- if (dma_ops->sync_single_range_for_cpu) +- dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, +- size, direction); +-} ++ cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag); + +-static inline void dma_sync_single_for_device(struct device *dev, +- dma_addr_t dma_handle, size_t size, +- enum dma_data_direction direction) +-{ +- struct dma_mapping_ops *dma_ops = get_dma_ops(dev); ++ debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); + +- BUG_ON(!dma_ops); +- - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(dev, dma_handle, - 0, size, direction); @@ -210220,11 +211384,9 @@ index b44aaab..cb2ca41 100644 - enum dma_data_direction direction) -{ - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); -+ cpu_addr = dma_ops->alloc_coherent(dev, size, dma_handle, flag); - +- - BUG_ON(!dma_ops); -+ debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr); - +- - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); + return cpu_addr; @@ -210250,10 +211412,10 @@ index b44aaab..cb2ca41 100644 - enum dma_data_direction direction) -{ - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); -- -- BUG_ON(!dma_ops); + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); +- BUG_ON(!dma_ops); +- - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(dev, dma_handle, - offset, size, direction); @@ -210326,7 +211488,7 @@ index b44aaab..cb2ca41 100644 - enum dma_data_direction direction) +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) { -+ return paddr + get_dma_direct_offset(dev); ++ return paddr + get_dma_offset(dev); } -#endif @@ -210338,7 +211500,7 @@ index b44aaab..cb2ca41 100644 -#else - return 0; -#endif -+ return daddr - get_dma_direct_offset(dev); ++ return daddr - get_dma_offset(dev); } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) @@ -211377,7 +212539,7 @@ index 8b505ea..abbc2aa 100644 #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_HW_IRQ_H */ diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h -index 7ead7c1..7464c0d 100644 +index 7ead7c1..edfc980 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -35,16 +35,6 @@ @@ -211397,6 +212559,23 @@ index 7ead7c1..7464c0d 100644 /* Boot time flags */ extern int iommu_is_off; extern int iommu_force_on; +@@ -80,6 +70,16 @@ struct iommu_table { + + struct scatterlist; + ++static inline void set_iommu_table_base(struct device *dev, void *base) ++{ ++ dev->archdata.dma_data.iommu_table_base = base; ++} ++ ++static inline void *get_iommu_table_base(struct device *dev) ++{ ++ return dev->archdata.dma_data.iommu_table_base; ++} ++ + /* Frees table for an individual device node */ + extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); + diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index 0a51376..bbcd1aa 100644 --- a/arch/powerpc/include/asm/irq.h @@ -212738,7 +213917,7 @@ index eb17da7..2a5da06 100644 *ptep = pte; #endif diff --git a/arch/powerpc/include/asm/pmc.h b/arch/powerpc/include/asm/pmc.h -index d6a616a..ccc68b5 100644 +index d6a616a..5a9ede4 100644 --- a/arch/powerpc/include/asm/pmc.h +++ b/arch/powerpc/include/asm/pmc.h @@ -27,10 +27,22 @@ extern perf_irq_t perf_irq; @@ -212746,10 +213925,8 @@ index d6a616a..ccc68b5 100644 int reserve_pmc_hardware(perf_irq_t new_perf_irq); void release_pmc_hardware(void); +void ppc_enable_pmcs(void); - - #ifdef CONFIG_PPC64 --void power4_enable_pmcs(void); --void pasemi_enable_pmcs(void); ++ ++#ifdef CONFIG_PPC_BOOK3S_64 +#include + +static inline void ppc_set_pmu_inuse(int inuse) @@ -212762,7 +213939,10 @@ index d6a616a..ccc68b5 100644 +#else /* CONFIG_PPC64 */ + +static inline void ppc_set_pmu_inuse(int inuse) { } -+ + +-#ifdef CONFIG_PPC64 +-void power4_enable_pmcs(void); +-void pasemi_enable_pmcs(void); #endif #endif /* __KERNEL__ */ @@ -212884,10 +214064,14 @@ index f972952..498fe09 100644 #define FIX_SRR1(ra, rb) #ifndef CONFIG_40x diff --git a/arch/powerpc/include/asm/pte-40x.h b/arch/powerpc/include/asm/pte-40x.h -index 07630fa..6c3e1f4 100644 +index 07630fa..ec0b0b0 100644 --- a/arch/powerpc/include/asm/pte-40x.h +++ b/arch/powerpc/include/asm/pte-40x.h -@@ -46,7 +46,7 @@ +@@ -43,10 +43,11 @@ + #define _PAGE_NO_CACHE 0x004 /* I: caching is inhibited */ + #define _PAGE_WRITETHRU 0x008 /* W: caching is write-through */ + #define _PAGE_USER 0x010 /* matches one of the zone permission bits */ ++#define _PAGE_SPECIAL 0x020 /* software: Special page */ #define _PAGE_RW 0x040 /* software: Writes permitted */ #define _PAGE_DIRTY 0x080 /* software: dirty page */ #define _PAGE_HWWRITE 0x100 /* hardware: Dirty & RW, set in exception */ @@ -212910,10 +214094,15 @@ index 37e98bc..4192b9b 100644 #define _PAGE_DIRTY 0x00000010 /* S: Page dirty */ #define _PAGE_SPECIAL 0x00000020 /* S: Special page */ diff --git a/arch/powerpc/include/asm/pte-8xx.h b/arch/powerpc/include/asm/pte-8xx.h -index 8c6e312..94e9797 100644 +index 8c6e312..dd5ea95 100644 --- a/arch/powerpc/include/asm/pte-8xx.h +++ b/arch/powerpc/include/asm/pte-8xx.h -@@ -36,7 +36,6 @@ +@@ -32,11 +32,11 @@ + #define _PAGE_FILE 0x0002 /* when !present: nonlinear file mapping */ + #define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ + #define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ ++#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */ + /* These five software bits must be masked out when the entry is loaded * into the TLB. */ @@ -213012,7 +214201,7 @@ index 0000000..082d515 +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_PTE_FSL_BOOKE_H */ diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h -index a7e210b..c3b6507 100644 +index a7e210b..f2b3701 100644 --- a/arch/powerpc/include/asm/pte-common.h +++ b/arch/powerpc/include/asm/pte-common.h @@ -13,9 +13,6 @@ @@ -213025,7 +214214,13 @@ index a7e210b..c3b6507 100644 #ifndef _PAGE_EXEC #define _PAGE_EXEC 0 #endif -@@ -34,6 +31,9 @@ +@@ -28,12 +25,12 @@ + #ifndef _PAGE_WRITETHRU + #define _PAGE_WRITETHRU 0 + #endif +-#ifndef _PAGE_SPECIAL +-#define _PAGE_SPECIAL 0 +-#endif #ifndef _PAGE_4K_PFN #define _PAGE_4K_PFN 0 #endif @@ -213035,7 +214230,7 @@ index a7e210b..c3b6507 100644 #ifndef _PAGE_PSIZE #define _PAGE_PSIZE 0 #endif -@@ -45,10 +45,16 @@ +@@ -45,10 +42,16 @@ #define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() #endif #ifndef _PAGE_KERNEL_RO @@ -213054,7 +214249,7 @@ index a7e210b..c3b6507 100644 #endif #ifndef _PAGE_HPTEFLAGS #define _PAGE_HPTEFLAGS _PAGE_HASHPTE -@@ -93,8 +99,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); +@@ -93,8 +96,7 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); #define PAGE_PROT_BITS (_PAGE_GUARDED | _PAGE_COHERENT | _PAGE_NO_CACHE | \ _PAGE_WRITETHRU | _PAGE_ENDIAN | _PAGE_4K_PFN | \ _PAGE_USER | _PAGE_ACCESSED | \ @@ -213064,7 +214259,7 @@ index a7e210b..c3b6507 100644 /* * We define 2 sets of base prot bits, one for basic pages (ie, -@@ -151,11 +156,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); +@@ -151,11 +153,9 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); _PAGE_NO_CACHE) #define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ _PAGE_NO_CACHE | _PAGE_GUARDED) @@ -213078,6 +214273,14 @@ index a7e210b..c3b6507 100644 /* Protection used for kernel text. We want the debuggers to be able to * set breakpoints anywhere, so don't write protect the kernel text +@@ -176,7 +176,5 @@ extern unsigned long bad_call_to_PMD_PAGE_SIZE(void); + #define HAVE_PAGE_AGP + + /* Advertise support for _PAGE_SPECIAL */ +-#ifdef _PAGE_SPECIAL + #define __HAVE_ARCH_PTE_SPECIAL +-#endif + diff --git a/arch/powerpc/include/asm/pte-fsl-booke.h b/arch/powerpc/include/asm/pte-fsl-booke.h index 10820f5..2c12be5 100644 --- a/arch/powerpc/include/asm/pte-fsl-booke.h @@ -214030,9 +215233,73 @@ index 4a24a2f..0b9c913 100644 static struct cpu_spec the_cpu_spec; diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c -index 2983ada..87ddb3f 100644 +index 2983ada..37771a5 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c +@@ -18,7 +18,7 @@ + static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) + { +- return iommu_alloc_coherent(dev, dev->archdata.dma_data, size, ++ return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, + dma_handle, device_to_mask(dev), flag, + dev_to_node(dev)); + } +@@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, + static void dma_iommu_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) + { +- iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle); ++ iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle); + } + + /* Creates TCEs for a user provided buffer. The user buffer must be +@@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, + enum dma_data_direction direction, + struct dma_attrs *attrs) + { +- return iommu_map_page(dev, dev->archdata.dma_data, page, offset, size, +- device_to_mask(dev), direction, attrs); ++ return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, ++ size, device_to_mask(dev), direction, attrs); + } + + +@@ -48,7 +48,7 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction, + struct dma_attrs *attrs) + { +- iommu_unmap_page(dev->archdata.dma_data, dma_handle, size, direction, ++ iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction, + attrs); + } + +@@ -57,7 +57,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) + { +- return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems, ++ return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems, + device_to_mask(dev), direction, attrs); + } + +@@ -65,14 +65,14 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction, + struct dma_attrs *attrs) + { +- iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction, ++ iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction, + attrs); + } + + /* We support DMA to/from any memory page via the iommu */ + static int dma_iommu_dma_supported(struct device *dev, u64 mask) + { +- struct iommu_table *tbl = dev->archdata.dma_data; ++ struct iommu_table *tbl = get_iommu_table_base(dev); + + if (!tbl || tbl->it_offset > mask) { + printk(KERN_INFO @@ -89,7 +89,7 @@ static int dma_iommu_dma_supported(struct device *dev, u64 mask) return 1; } @@ -214182,7 +215449,7 @@ index 68ccf11..e96cbbd 100644 if (dma_get_mask(dev) < lmb_end_of_DRAM()) set_dma_ops(dev, &swiotlb_dma_ops); diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c -index ccf129d..21b784d 100644 +index ccf129d..6215062 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -7,6 +7,7 @@ @@ -214193,7 +215460,57 @@ index ccf129d..21b784d 100644 #include #include #include -@@ -140,7 +141,7 @@ static inline void dma_direct_sync_single_range(struct device *dev, +@@ -20,13 +21,6 @@ + * default the offset is PCI_DRAM_OFFSET. + */ + +-unsigned long get_dma_direct_offset(struct device *dev) +-{ +- if (dev) +- return (unsigned long)dev->archdata.dma_data; +- +- return PCI_DRAM_OFFSET; +-} + + void *dma_direct_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +@@ -36,7 +30,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, + ret = __dma_alloc_coherent(dev, size, dma_handle, flag); + if (ret == NULL) + return NULL; +- *dma_handle += get_dma_direct_offset(dev); ++ *dma_handle += get_dma_offset(dev); + return ret; + #else + struct page *page; +@@ -50,7 +44,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, + return NULL; + ret = page_address(page); + memset(ret, 0, size); +- *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); ++ *dma_handle = virt_to_abs(ret) + get_dma_offset(dev); + + return ret; + #endif +@@ -74,7 +68,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, + int i; + + for_each_sg(sgl, sg, nents, i) { +- sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); ++ sg->dma_address = sg_phys(sg) + get_dma_offset(dev); + sg->dma_length = sg->length; + __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); + } +@@ -109,7 +103,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, + { + BUG_ON(dir == DMA_NONE); + __dma_sync_page(page, offset, size, dir); +- return page_to_phys(page) + offset + get_dma_direct_offset(dev); ++ return page_to_phys(page) + offset + get_dma_offset(dev); + } + + static inline void dma_direct_unmap_page(struct device *dev, +@@ -140,7 +134,7 @@ static inline void dma_direct_sync_single_range(struct device *dev, } #endif @@ -214202,7 +215519,7 @@ index ccf129d..21b784d 100644 .alloc_coherent = dma_direct_alloc_coherent, .free_coherent = dma_direct_free_coherent, .map_sg = dma_direct_map_sg, -@@ -156,3 +157,13 @@ struct dma_mapping_ops dma_direct_ops = { +@@ -156,3 +150,13 @@ struct dma_mapping_ops dma_direct_ops = { #endif }; EXPORT_SYMBOL(dma_direct_ops); @@ -214611,10 +215928,10 @@ index 43e0734..900e0ee 100644 ld r0,16(r1) diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S new file mode 100644 -index 0000000..9048f96 +index 0000000..24dcc0e --- /dev/null +++ b/arch/powerpc/kernel/exceptions-64e.S -@@ -0,0 +1,1001 @@ +@@ -0,0 +1,1000 @@ +/* + * Boot code and exception vectors for Book3E processors + * @@ -214634,7 +215951,6 @@ index 0000000..9048f96 +#include +#include +#include -+#include +#include +#include +#include @@ -217193,7 +218509,7 @@ index e9962c7..d16b1ea 100644 new_paca->lock_token = 0x8000; new_paca->paca_index = cpu; diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c -index 5a56e97..e9f4840 100644 +index 5a56e97..bb8209e 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -50,14 +50,14 @@ resource_size_t isa_mem_base; @@ -217241,6 +218557,15 @@ index 5a56e97..e9f4840 100644 } char __devinit *pcibios_setup(char *str) +@@ -1125,7 +1117,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) + + /* Hook up default DMA ops */ + sd->dma_ops = pci_dma_ops; +- sd->dma_data = (void *)PCI_DRAM_OFFSET; ++ set_dma_offset(&dev->dev, PCI_DRAM_OFFSET); + + /* Additional platform DMA/iommu setup */ + if (ppc_md.pci_dma_dev_setup) @@ -1626,3 +1618,122 @@ void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) } @@ -221493,7 +222818,7 @@ index 75dccb7..4795744 100644 #include diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c -index 892a9f2..0a32164 100644 +index 892a9f2..1168c5f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -284,14 +284,13 @@ int set_dabr(unsigned long dabr) @@ -221550,8 +222875,32 @@ index 892a9f2..0a32164 100644 kregs->nip = *((unsigned long *)ret_from_fork); #else kregs->nip = (unsigned long)ret_from_fork; +@@ -1163,7 +1165,22 @@ static inline unsigned long brk_rnd(void) + + unsigned long arch_randomize_brk(struct mm_struct *mm) + { +- unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); ++ unsigned long base = mm->brk; ++ unsigned long ret; ++ ++#ifdef CONFIG_PPC64 ++ /* ++ * If we are using 1TB segments and we are allowed to randomise ++ * the heap, we can put it above 1TB so it is backed by a 1TB ++ * segment. Otherwise the heap will be in the bottom 1TB ++ * which always uses 256MB segments and this may result in a ++ * performance penalty. ++ */ ++ if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T)) ++ base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T); ++#endif ++ ++ ret = PAGE_ALIGN(base + brk_rnd()); + + if (ret < mm->brk) + return mm->brk; diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c -index a538824..864334b 100644 +index a538824..bafac2e 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -190,6 +190,8 @@ static int __initdata of_platform; @@ -221658,7 +223007,24 @@ index a538824..864334b 100644 } #ifdef CONFIG_PPC_PSERIES -@@ -1027,6 +1098,29 @@ static void __init prom_init_mem(void) +@@ -729,7 +800,7 @@ static void __init prom_send_capabilities(void) + root = call_prom("open", 1, 1, ADDR("/")); + if (root != 0) { + /* try calling the ibm,client-architecture-support method */ +- prom_printf("Calling ibm,client-architecture..."); ++ prom_printf("Calling ibm,client-architecture-support..."); + if (call_prom_ret("call-method", 3, 2, &ret, + ADDR("ibm,client-architecture-support"), + root, +@@ -743,6 +814,7 @@ static void __init prom_send_capabilities(void) + return; + } + call_prom("close", 1, 0, root); ++ prom_printf(" not implemented\n"); + } + + /* no ibm,client-architecture-support call, try the old way */ +@@ -1027,6 +1099,29 @@ static void __init prom_init_mem(void) } /* @@ -221688,7 +223054,7 @@ index a538824..864334b 100644 * Setup our top alloc point, that is top of RMO or top of * segment 0 when running non-LPAR. * Some RS64 machines have buggy firmware where claims up at -@@ -1041,6 +1135,7 @@ static void __init prom_init_mem(void) +@@ -1041,6 +1136,7 @@ static void __init prom_init_mem(void) RELOC(alloc_top_high) = RELOC(ram_top); prom_printf("memory layout at init:\n"); @@ -221696,7 +223062,7 @@ index a538824..864334b 100644 prom_printf(" alloc_bottom : %x\n", RELOC(alloc_bottom)); prom_printf(" alloc_top : %x\n", RELOC(alloc_top)); prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); -@@ -1259,10 +1354,6 @@ static void __init prom_initialize_tce_table(void) +@@ -1259,10 +1355,6 @@ static void __init prom_initialize_tce_table(void) * * -- Cort */ @@ -221707,7 +223073,7 @@ index a538824..864334b 100644 /* * We want to reference the copy of __secondary_hold_* in the * 0 - 0x100 address range -@@ -2399,6 +2490,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, +@@ -2399,6 +2491,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, /* * Fill in some infos for use by the kernel later on */ @@ -221757,10 +223123,18 @@ index c434823..bf90361 100644 printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n", smp_processor_id(), rc); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c -index 02fed27..9837d91 100644 +index 02fed27..4271f7a 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c -@@ -328,7 +328,7 @@ static void c_stop(struct seq_file *m, void *v) +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -328,7 +327,7 @@ static void c_stop(struct seq_file *m, void *v) { } @@ -221769,7 +223143,7 @@ index 02fed27..9837d91 100644 .start =c_start, .next = c_next, .stop = c_stop, -@@ -432,9 +432,9 @@ void __init smp_setup_cpu_maps(void) +@@ -432,9 +431,9 @@ void __init smp_setup_cpu_maps(void) for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { DBG(" thread %d -> cpu %d (hard id %d)\n", j, cpu, intserv[j]); @@ -221781,7 +223155,7 @@ index 02fed27..9837d91 100644 cpu++; } } -@@ -480,7 +480,7 @@ void __init smp_setup_cpu_maps(void) +@@ -480,7 +479,7 @@ void __init smp_setup_cpu_maps(void) maxcpus); for (cpu = 0; cpu < maxcpus; cpu++) @@ -222066,10 +223440,18 @@ index 0b47de0..9b86a74 100644 set_cpus_allowed(current, old_mask); diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c -index bb1cfcf..1cc5e9e 100644 +index bb1cfcf..b97c2d6 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c -@@ -343,6 +343,18 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -343,6 +342,18 @@ off_t ppc32_lseek(unsigned int fd, u32 offset, unsigned int origin) return sys_lseek(fd, (int)offset, origin); } @@ -222316,7 +223698,7 @@ index acb74a1..b4b167b 100644 * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp * diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c -index ad06d5c..3faaf29 100644 +index ad06d5c..94e2df3 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -1,3 +1,4 @@ @@ -222347,6 +223729,35 @@ index ad06d5c..3faaf29 100644 } #else vdso_pagelist = vdso32_pagelist; +@@ -235,6 +241,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) + } + + /* ++ * Put vDSO base into mm struct. We need to do this before calling ++ * install_special_mapping or the perf counter mmap tracking code ++ * will fail to recognise it as a vDSO (since arch_vma_name fails). ++ */ ++ current->mm->context.vdso_base = vdso_base; ++ ++ /* + * our vma flags don't have VM_WRITE so by default, the process isn't + * allowed to write those pages. + * gdb can break that with ptrace interface, and thus trigger COW on +@@ -254,11 +267,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + vdso_pagelist); +- if (rc) ++ if (rc) { ++ current->mm->context.vdso_base = 0; + goto fail_mmapsem; +- +- /* Put vDSO base into mm struct */ +- current->mm->context.vdso_base = vdso_base; ++ } + + up_write(&mm->mmap_sem); + return 0; diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile index c3d57bd..51ead52 100644 --- a/arch/powerpc/kernel/vdso32/Makefile @@ -222423,7 +223834,7 @@ index ea4d646..67b6916 100644 #else ld r4,PACACURRENT(r13) diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c -index 819e59f..bc7b41e 100644 +index 819e59f..77f6421 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -601,7 +601,7 @@ static void vio_dma_iommu_unmap_sg(struct device *dev, @@ -222435,11 +223846,37 @@ index 819e59f..bc7b41e 100644 .alloc_coherent = vio_dma_iommu_alloc_coherent, .free_coherent = vio_dma_iommu_free_coherent, .map_sg = vio_dma_iommu_map_sg, +@@ -1054,6 +1054,8 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) + return NULL; + + tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); ++ if (tbl == NULL) ++ return NULL; + + of_parse_dma_window(dev->dev.archdata.of_node, dma_window, + &tbl->it_index, &offset, &size); +@@ -1233,7 +1235,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) + vio_cmo_set_dma_ops(viodev); + else + viodev->dev.archdata.dma_ops = &dma_iommu_ops; +- viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); ++ set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev)); + set_dev_node(&viodev->dev, of_node_to_nid(of_node)); + + /* init generic 'struct device' fields: */ diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S -index 8ef8a14..58da407 100644 +index 8ef8a14..f564293 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S -@@ -37,12 +37,6 @@ jiffies = jiffies_64 + 4; +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + ENTRY(_stext) + +@@ -37,12 +38,6 @@ jiffies = jiffies_64 + 4; #endif SECTIONS { @@ -222452,7 +223889,80 @@ index 8ef8a14..58da407 100644 . = KERNELBASE; /* -@@ -245,10 +239,6 @@ SECTIONS +@@ -77,12 +72,7 @@ SECTIONS + /* Read-only data */ + RODATA + +- /* Exception & bug tables */ +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { +- __start___ex_table = .; +- *(__ex_table) +- __stop___ex_table = .; +- } ++ EXCEPTION_TABLE(0) + + NOTES :kernel :notes + +@@ -99,12 +89,7 @@ SECTIONS + */ + . = ALIGN(PAGE_SIZE); + __init_begin = .; +- +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { +- _sinittext = .; +- INIT_TEXT +- _einittext = .; +- } :kernel ++ INIT_TEXT_SECTION(PAGE_SIZE) :kernel + + /* .exit.text is discarded at runtime, not link time, + * to deal with references from __bug_table +@@ -128,23 +113,16 @@ SECTIONS + #endif + } + +- . = ALIGN(16); + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { +- __setup_start = .; +- *(.init.setup) +- __setup_end = .; ++ INIT_SETUP(16) + } + + .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { +- __initcall_start = .; +- INITCALLS +- __initcall_end = .; +- } ++ INIT_CALLS ++ } + + .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { +- __con_initcall_start = .; +- *(.con_initcall.init) +- __con_initcall_end = .; ++ CON_INITCALL + } + + SECURITY_INIT +@@ -175,14 +153,10 @@ SECTIONS + __stop___fw_ftr_fixup = .; + } + #endif +-#ifdef CONFIG_BLK_DEV_INITRD +- . = ALIGN(PAGE_SIZE); + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { +- __initramfs_start = .; +- *(.init.ramfs) +- __initramfs_end = .; ++ INIT_RAM_FS + } +-#endif ++ + PERCPU(PAGE_SIZE) + + . = ALIGN(8); +@@ -245,57 +219,41 @@ SECTIONS } #endif @@ -222461,10 +223971,41 @@ index 8ef8a14..58da407 100644 - PROVIDE32 (edata = .); - /* The initial task and kernel stack */ - #ifdef CONFIG_PPC32 - . = ALIGN(8192); -@@ -282,6 +272,10 @@ SECTIONS - __nosave_end = .; +-#ifdef CONFIG_PPC32 +- . = ALIGN(8192); +-#else +- . = ALIGN(16384); +-#endif + .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { +- *(.data.init_task) ++ INIT_TASK_DATA(THREAD_SIZE) + } + +- . = ALIGN(PAGE_SIZE); + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { +- *(.data.page_aligned) ++ PAGE_ALIGNED_DATA(PAGE_SIZE) + } + +- . = ALIGN(L1_CACHE_BYTES); + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { +- *(.data.cacheline_aligned) ++ CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) + } + +- . = ALIGN(L1_CACHE_BYTES); + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { +- *(.data.read_mostly) ++ READ_MOSTLY_DATA(L1_CACHE_BYTES) + } + +- . = ALIGN(PAGE_SIZE); + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { +- __nosave_begin = .; +- *(.data.nosave) +- . = ALIGN(PAGE_SIZE); +- __nosave_end = .; ++ NOSAVE_DATA } + . = ALIGN(PAGE_SIZE); @@ -222474,7 +224015,17 @@ index 8ef8a14..58da407 100644 /* * And finally the bss */ -@@ -298,4 +292,7 @@ SECTIONS + +- .bss : AT(ADDR(.bss) - LOAD_OFFSET) { +- __bss_start = .; +- *(.sbss) *(.scommon) +- *(.dynbss) +- *(.bss) +- *(COMMON) +- __bss_stop = .; +- } ++ BSS_SECTION(0, 0, 0) + . = ALIGN(PAGE_SIZE); _end = . ; PROVIDE32 (end = .); @@ -223673,13 +225224,15 @@ index d1f9c62..d2e5321 100644 extern unsigned long ioremap_bot; extern unsigned long __max_low_memory; diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c -index 627767d..83f1551 100644 +index 627767d..5304093 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c -@@ -30,6 +30,16 @@ +@@ -30,6 +30,18 @@ #include #include ++#include "mmu_decl.h" ++ +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); + +#ifdef CONFIG_SMP @@ -223693,7 +225246,7 @@ index 627767d..83f1551 100644 static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur); static unsigned long pte_freelist_forced_free; -@@ -116,27 +126,7 @@ void pte_free_finish(void) +@@ -116,27 +128,7 @@ void pte_free_finish(void) *batchp = NULL; } @@ -223722,7 +225275,7 @@ index 627767d..83f1551 100644 static inline int is_exec_fault(void) { -@@ -145,49 +135,139 @@ static inline int is_exec_fault(void) +@@ -145,49 +137,150 @@ static inline int is_exec_fault(void) /* We only try to do i/d cache coherency on stuff that looks like * reasonably "normal" PTEs. We currently require a PTE to be present @@ -223737,9 +225290,8 @@ index 627767d..83f1551 100644 - (_PAGE_PRESENT); + (_PAGE_PRESENT | _PAGE_SPECIAL | _PAGE_NO_CACHE | _PAGE_USER)) == + (_PAGE_PRESENT | _PAGE_USER); - } - --#if defined(CONFIG_PPC_STD_MMU) ++} ++ +struct page * maybe_pte_to_page(pte_t pte) +{ + unsigned long pfn = pte_pfn(pte); @@ -223751,8 +225303,9 @@ index 627767d..83f1551 100644 + if (PageReserved(page)) + return NULL; + return page; -+} -+ + } + +-#if defined(CONFIG_PPC_STD_MMU) +#if defined(CONFIG_PPC_STD_MMU) || _PAGE_EXEC == 0 + /* Server-style MMU handles coherency when hashing if HW exec permission @@ -223764,7 +225317,7 @@ index 627767d..83f1551 100644 */ -static inline int pte_need_exec_flush(pte_t pte, int set_pte) + -+static pte_t set_pte_filter(pte_t pte) ++static pte_t set_pte_filter(pte_t pte, unsigned long addr) { - return set_pte && pte_looks_normal(pte) && - !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) || @@ -223776,6 +225329,17 @@ index 627767d..83f1551 100644 + if (!pg) + return pte; + if (!test_bit(PG_arch_1, &pg->flags)) { ++#ifdef CONFIG_8xx ++ /* On 8xx, cache control instructions (particularly ++ * "dcbst" from flush_dcache_icache) fault as write ++ * operation if there is an unpopulated TLB entry ++ * for the address in question. To workaround that, ++ * we invalidate the TLB here, thus avoiding dcbst ++ * misbehaviour. ++ */ ++ /* 8xx doesn't care about PID, size or ind args */ ++ _tlbil_va(addr, 0, 0, 0); ++#endif /* CONFIG_8xx */ + flush_dcache_icache_page(pg); + set_bit(PG_arch_1, &pg->flags); + } @@ -223805,7 +225369,7 @@ index 627767d..83f1551 100644 + * instead we "filter out" the exec permission for non clean pages. */ -static inline int pte_need_exec_flush(pte_t pte, int set_pte) -+static pte_t set_pte_filter(pte_t pte) ++static pte_t set_pte_filter(pte_t pte, unsigned long addr) { - return pte_looks_normal(pte) && is_exec_fault() && - !(pte_val(pte) & _PAGE_HWEXEC); @@ -223886,18 +225450,18 @@ index 627767d..83f1551 100644 { #ifdef CONFIG_DEBUG_VM WARN_ON(pte_present(*ptep)); -@@ -196,9 +276,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte +@@ -196,9 +289,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte * this context might not have been activated yet when this * is called. */ - pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); - if (pte_need_exec_flush(pte, 1)) - pte = do_dcache_icache_coherency(pte); -+ pte = set_pte_filter(pte); ++ pte = set_pte_filter(pte, addr); /* Perform the setting of the PTE */ __set_pte_at(mm, addr, ptep, pte, 0); -@@ -215,8 +293,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, +@@ -215,8 +306,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t entry, int dirty) { int changed; @@ -223907,7 +225471,7 @@ index 627767d..83f1551 100644 changed = !pte_same(*(ptep), entry); if (changed) { if (!(vma->vm_flags & VM_HUGETLB)) -@@ -242,7 +319,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr) +@@ -242,7 +332,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr) BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, addr); BUG_ON(!pmd_present(*pmd)); @@ -224282,10 +225846,10 @@ index 937eb90..2b2f35f 100644 * from the hash table (and the TLB). But keeps diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S new file mode 100644 -index 0000000..ef1cccf +index 0000000..f288279 --- /dev/null +++ b/arch/powerpc/mm/tlb_low_64e.S -@@ -0,0 +1,770 @@ +@@ -0,0 +1,769 @@ +/* + * Low leve TLB miss handlers for Book3E + * @@ -224306,7 +225870,6 @@ index 0000000..ef1cccf +#include +#include +#include -+#include +#include +#include + @@ -226465,6 +228028,19 @@ index 50f17bd..48cd7d2 100644 config SPU_BASE bool default n +diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c +index 93b0efd..39d361c 100644 +--- a/arch/powerpc/platforms/cell/beat_iommu.c ++++ b/arch/powerpc/platforms/cell/beat_iommu.c +@@ -77,7 +77,7 @@ static void __init celleb_init_direct_mapping(void) + static void celleb_dma_dev_setup(struct device *dev) + { + dev->archdata.dma_ops = get_pci_dma_ops(); +- dev->archdata.dma_data = (void *)celleb_dma_direct_offset; ++ set_dma_offset(dev, celleb_dma_direct_offset); + } + + static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) diff --git a/arch/powerpc/platforms/cell/celleb_setup.c b/arch/powerpc/platforms/cell/celleb_setup.c index 07c234f..e538455 100644 --- a/arch/powerpc/platforms/cell/celleb_setup.c @@ -226480,7 +228056,7 @@ index 07c234f..e538455 100644 } diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c -index 5b34fc2..416db17 100644 +index 5b34fc2..ca5bfdf 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -642,7 +642,7 @@ static int dma_fixed_dma_supported(struct device *dev, u64 mask) @@ -226492,6 +228068,37 @@ index 5b34fc2..416db17 100644 .alloc_coherent = dma_fixed_alloc_coherent, .free_coherent = dma_fixed_free_coherent, .map_sg = dma_fixed_map_sg, +@@ -657,15 +657,13 @@ static void cell_dma_dev_setup_fixed(struct device *dev); + + static void cell_dma_dev_setup(struct device *dev) + { +- struct dev_archdata *archdata = &dev->archdata; +- + /* Order is important here, these are not mutually exclusive */ + if (get_dma_ops(dev) == &dma_iommu_fixed_ops) + cell_dma_dev_setup_fixed(dev); + else if (get_pci_dma_ops() == &dma_iommu_ops) +- archdata->dma_data = cell_get_iommu_table(dev); ++ set_iommu_table_base(dev, cell_get_iommu_table(dev)); + else if (get_pci_dma_ops() == &dma_direct_ops) +- archdata->dma_data = (void *)cell_dma_direct_offset; ++ set_dma_offset(dev, cell_dma_direct_offset); + else + BUG(); + } +@@ -973,11 +971,10 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask) + + static void cell_dma_dev_setup_fixed(struct device *dev) + { +- struct dev_archdata *archdata = &dev->archdata; + u64 addr; + + addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; +- archdata->dma_data = (void *)addr; ++ set_dma_offset(dev, addr); + + dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); + } diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index bc97fad..f774530 100644 --- a/arch/powerpc/platforms/cell/smp.c @@ -227093,6 +228700,19 @@ index ced45a8..bae3fba 100644 EXCEPTION_PROLOG_1(PACA_EXGEN); \ lbz r10,PACASOFTIRQEN(r13); \ cmpwi 0,r10,0; \ +diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c +index 6c1e101..9d53cb4 100644 +--- a/arch/powerpc/platforms/iseries/iommu.c ++++ b/arch/powerpc/platforms/iseries/iommu.c +@@ -193,7 +193,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev) + pdn->iommu_table = iommu_init_table(tbl, -1); + else + kfree(tbl); +- pdev->dev.archdata.dma_data = pdn->iommu_table; ++ set_iommu_table_base(&pdev->dev, pdn->iommu_table); + } + #else + #define pci_dma_dev_setup_iseries NULL diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index fef4d51..0d9343d 100644 --- a/arch/powerpc/platforms/iseries/mf.c @@ -227119,6 +228739,19 @@ index 43911d8..75b296b 100644 if (!strcmp(modes[i].name, p)) { current_mode = i; break; +diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c +index a0ff03a..7b1d608 100644 +--- a/arch/powerpc/platforms/pasemi/iommu.c ++++ b/arch/powerpc/platforms/pasemi/iommu.c +@@ -189,7 +189,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev) + } + #endif + +- dev->dev.archdata.dma_data = &iommu_table_iobmap; ++ set_iommu_table_base(&dev->dev, &iommu_table_iobmap); + } + + static void pci_dma_bus_setup_null(struct pci_bus *b) { } diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index 65c585b..08d94e4 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -227419,6 +229052,46 @@ index eae51ef..3631a4f 100644 .start = hc_start, .next = hc_next, .stop = hc_stop, +diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c +index 661c8e0..1a0000a 100644 +--- a/arch/powerpc/platforms/pseries/iommu.c ++++ b/arch/powerpc/platforms/pseries/iommu.c +@@ -482,7 +482,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) + phb->node); + iommu_table_setparms(phb, dn, tbl); + PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); +- dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; ++ set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); + return; + } + +@@ -494,7 +494,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) + dn = dn->parent; + + if (dn && PCI_DN(dn)) +- dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; ++ set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); + else + printk(KERN_WARNING "iommu: Device %s has no iommu table\n", + pci_name(dev)); +@@ -538,7 +538,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) + */ + if (dma_window == NULL || pdn->parent == NULL) { + pr_debug(" no dma window for device, linking to parent\n"); +- dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; ++ set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table); + return; + } + +@@ -554,7 +554,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) + pr_debug(" found DMA window, table: %p\n", pci->iommu_table); + } + +- dev->dev.archdata.dma_data = pci->iommu_table; ++ set_iommu_table_base(&dev->dev, pci->iommu_table); + } + #else /* CONFIG_PCI */ + #define pci_dma_bus_setup_pSeries NULL diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index ad152a0..b6fa3e4 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -227489,6 +229162,68 @@ index 1f8f6cf..440000c 100644 /** * smp_startup_cpu() - start the given cpu * +diff --git a/arch/powerpc/relocs_check.pl b/arch/powerpc/relocs_check.pl +new file mode 100755 +index 0000000..d257109 +--- /dev/null ++++ b/arch/powerpc/relocs_check.pl +@@ -0,0 +1,56 @@ ++#!/usr/bin/perl ++ ++# Copyright © 2009 IBM Corporation ++ ++# This program is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License ++# as published by the Free Software Foundation; either version ++# 2 of the License, or (at your option) any later version. ++ ++# This script checks the relcoations of a vmlinux for "suspicious" ++# relocations. ++ ++use strict; ++use warnings; ++ ++if ($#ARGV != 1) { ++ die "$0 [path to objdump] [path to vmlinux]\n"; ++} ++ ++# Have Kbuild supply the path to objdump so we handle cross compilation. ++my $objdump = shift; ++my $vmlinux = shift; ++my $bad_relocs_count = 0; ++my $bad_relocs = ""; ++my $old_binutils = 0; ++ ++open(FD, "$objdump -R $vmlinux|") or die; ++while () { ++ study $_; ++ ++ # Only look at relcoation lines. ++ next if (!/\s+R_/); ++ ++ # These relocations are okay ++ next if (/R_PPC64_RELATIVE/ or /R_PPC64_NONE/ or ++ /R_PPC64_ADDR64\s+mach_/); ++ ++ # If we see this type of relcoation it's an idication that ++ # we /may/ be using an old version of binutils. ++ if (/R_PPC64_UADDR64/) { ++ $old_binutils++; ++ } ++ ++ $bad_relocs_count++; ++ $bad_relocs .= $_; ++} ++ ++if ($bad_relocs_count) { ++ print "WARNING: $bad_relocs_count bad relocations\n"; ++ print $bad_relocs; ++} ++ ++if ($old_binutils) { ++ print "WARNING: You need at binutils >= 2.19 to build a ". ++ "CONFIG_RELCOATABLE kernel\n"; ++} diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c index a477991..88f4ae7 100644 --- a/arch/powerpc/sysdev/axonram.c @@ -227502,6 +229237,19 @@ index a477991..88f4ae7 100644 .owner = THIS_MODULE, .direct_access = axon_ram_direct_access }; +diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c +index 89639ec..ae3c4db 100644 +--- a/arch/powerpc/sysdev/dart_iommu.c ++++ b/arch/powerpc/sysdev/dart_iommu.c +@@ -297,7 +297,7 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev) + /* We only have one iommu table on the mac for now, which makes + * things simple. Setup all PCI devices to point to this table + */ +- dev->dev.archdata.dma_data = &iommu_table_dart; ++ set_iommu_table_base(&dev->dev, &iommu_table_dart); + } + + static void pci_dma_bus_setup_dart(struct pci_bus *bus) diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index cbb3bed..757a83f 100644 --- a/arch/powerpc/sysdev/fsl_rio.c @@ -227779,10 +229527,54 @@ index 85ab97a..faa81b6 100644 EXTRA_CFLAGS += -mno-minimal-toc endif diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c -index e1f33a8..0e09a45 100644 +index e1f33a8..c6f0a71 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c -@@ -2570,7 +2570,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, +@@ -335,6 +335,16 @@ int cpus_are_in_xmon(void) + } + #endif + ++static inline int unrecoverable_excp(struct pt_regs *regs) ++{ ++#ifdef CONFIG_4xx ++ /* We have no MSR_RI bit on 4xx, so we simply return false */ ++ return 0; ++#else ++ return ((regs->msr & MSR_RI) == 0); ++#endif ++} ++ + static int xmon_core(struct pt_regs *regs, int fromipi) + { + int cmd = 0; +@@ -388,7 +398,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) + bp = NULL; + if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) + bp = at_breakpoint(regs->nip); +- if (bp || (regs->msr & MSR_RI) == 0) ++ if (bp || unrecoverable_excp(regs)) + fromipi = 0; + + if (!fromipi) { +@@ -399,7 +409,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) + cpu, BP_NUM(bp)); + xmon_print_symbol(regs->nip, " ", ")\n"); + } +- if ((regs->msr & MSR_RI) == 0) ++ if (unrecoverable_excp(regs)) + printf("WARNING: exception is not recoverable, " + "can't continue\n"); + release_output_lock(); +@@ -490,7 +500,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi) + printf("Stopped at breakpoint %x (", BP_NUM(bp)); + xmon_print_symbol(regs->nip, " ", ")\n"); + } +- if ((regs->msr & MSR_RI) == 0) ++ if (unrecoverable_excp(regs)) + printf("WARNING: exception is not recoverable, " + "can't continue\n"); + remove_bpts(); +@@ -2570,7 +2580,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid, printf("%s", after); } @@ -227842,6 +229634,49 @@ index 0ff387c..fc8fb20 100644 libs-y += arch/s390/lib/ drivers-y += drivers/s390/ +diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c +index 264528e..b55fd7e 100644 +--- a/arch/s390/appldata/appldata_base.c ++++ b/arch/s390/appldata/appldata_base.c +@@ -50,10 +50,9 @@ static struct platform_device *appldata_pdev; + * /proc entries (sysctl) + */ + static const char appldata_proc_name[APPLDATA_PROC_NAME_LENGTH] = "appldata"; +-static int appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, ++static int appldata_timer_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + static int appldata_interval_handler(ctl_table *ctl, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos); + +@@ -247,7 +246,7 @@ __appldata_vtimer_setup(int cmd) + * Start/Stop timer, show status of timer (0 = not active, 1 = active) + */ + static int +-appldata_timer_handler(ctl_table *ctl, int write, struct file *filp, ++appldata_timer_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int len; +@@ -289,7 +288,7 @@ out: + * current timer interval. + */ + static int +-appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, ++appldata_interval_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int len, interval; +@@ -335,7 +334,7 @@ out: + * monitoring (0 = not in process, 1 = in process) + */ + static int +-appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, ++appldata_generic_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct appldata_ops *ops = NULL, *tmp_ops; diff --git a/arch/s390/boot/install.sh b/arch/s390/boot/install.sh index d4026f6..aed3069 100644 --- a/arch/s390/boot/install.sh @@ -229019,6 +230854,25 @@ index 31ed568..18124b7 100644 extern debug_entry_t * debug_sprintf_exception(debug_info_t* id,int level,char *string,...) __attribute__ ((format(printf, 3, 4))); +diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h +index a356c95..8a096b8 100644 +--- a/arch/s390/include/asm/delay.h ++++ b/arch/s390/include/asm/delay.h +@@ -14,10 +14,11 @@ + #ifndef _S390_DELAY_H + #define _S390_DELAY_H + +-extern void __udelay(unsigned long usecs); +-extern void udelay_simple(unsigned long usecs); ++extern void __udelay(unsigned long long usecs); ++extern void udelay_simple(unsigned long long usecs); + extern void __delay(unsigned long loops); + +-#define udelay(n) __udelay(n) ++#define udelay(n) __udelay((unsigned long long) (n)) ++#define mdelay(n) __udelay((unsigned long long) (n) * 1000) + + #endif /* defined(_S390_DELAY_H) */ diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 89ec705..498bc38 100644 --- a/arch/s390/include/asm/hardirq.h @@ -230669,10 +232523,18 @@ index fa9905c..63e4643 100644 return 0; } diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c -index 9ab188d..5519cb7 100644 +index 9ab188d..0debcec 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c -@@ -443,66 +443,28 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -443,66 +442,28 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) * sys32_execve() executes a new program after the asm stub has set * things up for us. This should basically do what I want it to. */ @@ -230753,7 +232615,7 @@ index 9ab188d..5519cb7 100644 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count, u32 poshi, u32 poslo) { -@@ -801,23 +763,6 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count) +@@ -801,23 +762,6 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count) return sys_write(fd, buf, count); } @@ -230800,9 +232662,18 @@ index 836a288..c07f9ca 100644 long sys32_fadvise64_64(struct fadvise64_64_args __user *args); long sys32_sigaction(int sig, const struct old_sigaction32 __user *act, diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S -index 88a8336..682fb69 100644 +index 88a8336..cbd9901 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S +@@ -409,7 +409,7 @@ sys32_munmap_wrapper: + .globl sys32_truncate_wrapper + sys32_truncate_wrapper: + llgtr %r2,%r2 # const char * +- llgfr %r3,%r3 # unsigned long ++ lgfr %r3,%r3 # long + jg sys_truncate # branch to system call + + .globl sys32_ftruncate_wrapper @@ -568,18 +568,18 @@ compat_sys_sigprocmask_wrapper: llgtr %r4,%r4 # compat_old_sigset_t * jg compat_sys_sigprocmask # branch to system call @@ -230860,7 +232731,7 @@ index 88a8336..682fb69 100644 + llgtr %r4,%r4 # compat_uptr_t * + jg sys32_execve # branch to system call diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c -index be8bcea..4c51256 100644 +index be8bcea..20f282c 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -63,8 +63,6 @@ typedef struct @@ -230872,6 +232743,20 @@ index be8bcea..4c51256 100644 /* internal function prototyes */ static int debug_init(void); +@@ -883,11 +881,11 @@ static int debug_active=1; + * if debug_active is already off + */ + static int +-s390dbf_procactive(ctl_table *table, int write, struct file *filp, ++s390dbf_procactive(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + if (!write || debug_stoppable || !debug_active) +- return proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ return proc_dointvec(table, write, buffer, lenp, ppos); + else + return 0; + } @@ -1450,17 +1448,13 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, int area, debug_entry_t * entry, char *out_buf) { @@ -231222,10 +233107,20 @@ index f6618e9..a6f7b20 100644 # diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c -index 3e298e6..57bdcb1 100644 +index 3e298e6..f5fe34d 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c -@@ -220,6 +220,29 @@ struct syscall_metadata *syscall_nr_to_meta(int nr) +@@ -185,9 +185,6 @@ unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent) + { + struct ftrace_graph_ent trace; + +- /* Nmi's are currently unsupported. */ +- if (unlikely(in_nmi())) +- goto out; + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + goto out; + if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) +@@ -220,6 +217,29 @@ struct syscall_metadata *syscall_nr_to_meta(int nr) return syscalls_metadata[nr]; } @@ -231255,7 +233150,7 @@ index 3e298e6..57bdcb1 100644 static struct syscall_metadata *find_syscall_meta(unsigned long syscall) { struct syscall_metadata *start; -@@ -237,24 +260,19 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) +@@ -237,24 +257,19 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) return NULL; } @@ -231906,10 +233801,15 @@ index 0000000..c37211c + +#endif diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c -index 5a43f27..59fe6ec 100644 +index 5a43f27..5417eb5 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c -@@ -32,6 +32,7 @@ +@@ -27,11 +27,11 @@ + #include + #include + #include +-#include + #include #include #include #include @@ -231917,7 +233817,7 @@ index 5a43f27..59fe6ec 100644 #include #include #include -@@ -230,17 +231,11 @@ SYSCALL_DEFINE0(fork) +@@ -230,17 +230,11 @@ SYSCALL_DEFINE0(fork) return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); } @@ -231937,7 +233837,7 @@ index 5a43f27..59fe6ec 100644 if (!newsp) newsp = regs->gprs[15]; return do_fork(clone_flags, newsp, regs, 0, -@@ -274,30 +269,25 @@ asmlinkage void execve_tail(void) +@@ -274,30 +268,25 @@ asmlinkage void execve_tail(void) /* * sys_execve() executes a new program. */ @@ -233562,6 +235462,81 @@ index 0ef81d6..40c8c67 100644 break; case SIGP_SET_ARCH: vcpu->stat.instruction_sigp_arch++; +diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c +index 97c1eca..752b362 100644 +--- a/arch/s390/lib/delay.c ++++ b/arch/s390/lib/delay.c +@@ -25,13 +25,13 @@ void __delay(unsigned long loops) + asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); + } + +-static void __udelay_disabled(unsigned long usecs) ++static void __udelay_disabled(unsigned long long usecs) + { + unsigned long mask, cr0, cr0_saved; + u64 clock_saved; + + clock_saved = local_tick_disable(); +- set_clock_comparator(get_clock() + ((u64) usecs << 12)); ++ set_clock_comparator(get_clock() + (usecs << 12)); + __ctl_store(cr0_saved, 0, 0); + cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; + __ctl_load(cr0 , 0, 0); +@@ -46,20 +46,25 @@ static void __udelay_disabled(unsigned long usecs) + set_clock_comparator(S390_lowcore.clock_comparator); + } + +-static void __udelay_enabled(unsigned long usecs) ++static void __udelay_enabled(unsigned long long usecs) + { + unsigned long mask; +- u64 end, time; ++ u64 clock_saved; ++ u64 end; + + mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; +- end = get_clock() + ((u64) usecs << 12); ++ end = get_clock() + (usecs << 12); + do { +- time = end < S390_lowcore.clock_comparator ? +- end : S390_lowcore.clock_comparator; +- set_clock_comparator(time); ++ clock_saved = 0; ++ if (end < S390_lowcore.clock_comparator) { ++ clock_saved = local_tick_disable(); ++ set_clock_comparator(end); ++ } + trace_hardirqs_on(); + __load_psw_mask(mask); + local_irq_disable(); ++ if (clock_saved) ++ local_tick_enable(clock_saved); + } while (get_clock() < end); + set_clock_comparator(S390_lowcore.clock_comparator); + } +@@ -67,7 +72,7 @@ static void __udelay_enabled(unsigned long usecs) + /* + * Waits for 'usecs' microseconds using the TOD clock comparator. + */ +-void __udelay(unsigned long usecs) ++void __udelay(unsigned long long usecs) + { + unsigned long flags; + +@@ -101,11 +106,11 @@ EXPORT_SYMBOL(__udelay); + * Simple udelay variant. To be used on startup and reboot + * when the interrupt handler isn't working. + */ +-void udelay_simple(unsigned long usecs) ++void udelay_simple(unsigned long long usecs) + { + u64 end; + +- end = get_clock() + ((u64) usecs << 12); ++ end = get_clock() + (usecs << 12); + while (get_clock() < end) + cpu_relax(); + } diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index db05661..eec0544 100644 --- a/arch/s390/mm/Makefile @@ -233576,6 +235551,28 @@ index db05661..eec0544 100644 obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_PAGE_STATES) += page-states.o +diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c +index 413c240..b201135 100644 +--- a/arch/s390/mm/cmm.c ++++ b/arch/s390/mm/cmm.c +@@ -262,7 +262,7 @@ cmm_skip_blanks(char *cp, char **endp) + static struct ctl_table cmm_table[]; + + static int +-cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, ++cmm_pages_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char buf[16], *p; +@@ -303,7 +303,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, + } + + static int +-cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp, ++cmm_timeout_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char buf[64], *p; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e5e119f..6d50746 100644 --- a/arch/s390/mm/fault.c @@ -244246,10 +246243,10 @@ index 0000000..51f8521 \ No newline at end of file diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c new file mode 100644 -index 0000000..96bc169 +index 0000000..5f9881e --- /dev/null +++ b/arch/sh/boards/mach-ecovec24/setup.c -@@ -0,0 +1,670 @@ +@@ -0,0 +1,671 @@ +/* + * Copyright (C) 2009 Renesas Solutions Corp. + * @@ -244373,6 +246370,7 @@ index 0000000..96bc169 +struct sh_eth_plat_data sh_eth_plat = { + .phy = 0x1f, /* SMSC LAN8700 */ + .edmac_endian = EDMAC_LITTLE_ENDIAN, ++ .ether_link_active_low = 1 +}; + +static struct platform_device sh_eth_device = { @@ -260323,10 +262321,10 @@ index 0000000..6f5ad15 +} diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c new file mode 100644 -index 0000000..bc4d8d7 +index 0000000..03b3616 --- /dev/null +++ b/arch/sh/kernel/dwarf.c -@@ -0,0 +1,972 @@ +@@ -0,0 +1,971 @@ +/* + * Copyright (C) 2009 Matt Fleming + * @@ -260353,7 +262351,6 @@ index 0000000..bc4d8d7 +#include +#include +#include -+#include +#include + +/* Reserve enough memory for two stack frames */ @@ -262951,6 +264948,30 @@ index 90d00e4..8aa5d1c 100644 asmlinkage int sys_uname(struct old_utsname __user *name) { int err; +diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c +index 63ba128..eb68bfd 100644 +--- a/arch/sh/kernel/sys_sh32.c ++++ b/arch/sh/kernel/sys_sh32.c +@@ -9,7 +9,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/arch/sh/kernel/sys_sh64.c b/arch/sh/kernel/sys_sh64.c +index 91fb844..2872357 100644 +--- a/arch/sh/kernel/sys_sh64.c ++++ b/arch/sh/kernel/sys_sh64.c +@@ -23,7 +23,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index f9e21fa..19fd11d 100644 --- a/arch/sh/kernel/syscalls_32.S @@ -263135,7 +265156,7 @@ index b3e0067..a8396f3 100644 + nmi_exit(); +} diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c -index 2b77277..6aba9af 100644 +index 2b77277..69bb165 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c @@ -24,6 +24,7 @@ @@ -263254,7 +265275,7 @@ index 2b77277..6aba9af 100644 ret = -EFAULT; switch (instruction>>12) { case 0: /* mov.[bwl] to/from memory via r0+rn */ -@@ -358,15 +446,8 @@ static inline int handle_delayslot(struct pt_regs *regs, +@@ -358,31 +446,28 @@ static inline int handle_delayslot(struct pt_regs *regs, #define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4) #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) @@ -263271,7 +265292,13 @@ index 2b77277..6aba9af 100644 { u_int rm; int ret, index; -@@ -374,15 +455,13 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, + ++ /* ++ * XXX: We can't handle mixed 16/32-bit instructions yet ++ */ ++ if (instruction_size(instruction) != 2) ++ return -EINVAL; ++ index = (instruction>>8)&15; /* 0x0F00 */ rm = regs->regs[index]; @@ -263291,18 +265318,27 @@ index 2b77277..6aba9af 100644 ret = -EFAULT; switch (instruction&0xF000) { -@@ -538,6 +617,36 @@ asmlinkage void do_address_error(struct pt_regs *regs, +@@ -538,24 +623,44 @@ asmlinkage void do_address_error(struct pt_regs *regs, local_irq_enable(); +- /* bad PC is not something we can fix */ +- if (regs->pc & 1) { +- si_code = BUS_ADRALN; +- goto uspace_segv; +- } + se_user += 1; -+ -+#ifndef CONFIG_CPU_SH2A -+ set_fs(USER_DS); -+ if (copy_from_user(&instruction, (u16 *)(regs->pc & ~1), 2)) { -+ set_fs(oldfs); -+ goto uspace_segv; -+ } + + set_fs(USER_DS); +- if (copy_from_user(&instruction, (void __user *)(regs->pc), ++ if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), + sizeof(instruction))) { +- /* Argh. Fault on the instruction itself. +- This should never happen non-SMP +- */ + set_fs(oldfs); + goto uspace_segv; + } + set_fs(oldfs); + + /* shout about userspace fixups */ @@ -263311,11 +265347,10 @@ index 2b77277..6aba9af 100644 + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + current->comm, current->pid, (void *)regs->pc, + instruction); -+#endif + + if (se_usermode & 2) + goto fixup; -+ + + if (se_usermode & 4) + goto uspace_segv; + else { @@ -263325,54 +265360,45 @@ index 2b77277..6aba9af 100644 + } + +fixup: - /* bad PC is not something we can fix */ - if (regs->pc & 1) { - si_code = BUS_ADRALN; -@@ -545,17 +654,8 @@ asmlinkage void do_address_error(struct pt_regs *regs, - } - - set_fs(USER_DS); -- if (copy_from_user(&instruction, (void __user *)(regs->pc), -- sizeof(instruction))) { -- /* Argh. Fault on the instruction itself. -- This should never happen non-SMP -- */ -- set_fs(oldfs); -- goto uspace_segv; -- } -- ++ /* bad PC is not something we can fix */ ++ if (regs->pc & 1) { ++ si_code = BUS_ADRALN; ++ goto uspace_segv; ++ } ++ ++ set_fs(USER_DS); tmp = handle_unaligned_access(instruction, regs, - &user_mem_access); + &user_mem_access, 0); set_fs(oldfs); if (tmp==0) -@@ -571,6 +671,14 @@ uspace_segv: +@@ -571,6 +676,8 @@ uspace_segv: info.si_addr = (void __user *)address; force_sig_info(SIGBUS, &info, current); } else { + se_sys += 1; + + if (regs->pc & 1) + die("unaligned program counter", regs, error_code); + +@@ -584,7 +691,14 @@ uspace_segv: + die("insn faulting in do_address_error", regs, 0); + } + +- handle_unaligned_access(instruction, regs, &user_mem_access); + if (se_kernmode_warn) + printk(KERN_NOTICE "Unaligned kernel access " + "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + current->comm, current->pid, (void *)regs->pc, + instruction); + - if (regs->pc & 1) - die("unaligned program counter", regs, error_code); - -@@ -584,7 +692,8 @@ uspace_segv: - die("insn faulting in do_address_error", regs, 0); - } - -- handle_unaligned_access(instruction, regs, &user_mem_access); + handle_unaligned_access(instruction, regs, + &user_mem_access, 0); set_fs(oldfs); } } -@@ -858,30 +967,6 @@ void __init trap_init(void) +@@ -858,30 +972,6 @@ void __init trap_init(void) per_cpu_trap_init(); } @@ -263403,7 +265429,7 @@ index 2b77277..6aba9af 100644 void show_stack(struct task_struct *tsk, unsigned long *sp) { unsigned long stack; -@@ -904,3 +989,38 @@ void dump_stack(void) +@@ -904,3 +994,38 @@ void dump_stack(void) show_stack(NULL, NULL); } EXPORT_SYMBOL(dump_stack); @@ -272418,6 +274444,18 @@ index aed9486..e706113 100644 SIGN3(sys32_socket, sys_socket, %o0, %o1, %o2) SIGN2(sys32_connect, sys_connect, %o0, %o2) SIGN2(sys32_bind, sys_bind, %o0, %o2) +diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c +index f5000a4..04e28b2 100644 +--- a/arch/sparc/kernel/sys_sparc32.c ++++ b/arch/sparc/kernel/sys_sparc32.c +@@ -16,7 +16,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index d28f496..ca39c60 100644 --- a/arch/sparc/kernel/sysfs.c @@ -272430,6 +274468,23 @@ index d28f496..ca39c60 100644 #include #include #include +diff --git a/arch/sparc/kernel/systbls.h b/arch/sparc/kernel/systbls.h +index 15c2d75..a63c5d2 100644 +--- a/arch/sparc/kernel/systbls.h ++++ b/arch/sparc/kernel/systbls.h +@@ -3,10 +3,11 @@ + + #include + #include +-#include + #include + #include + ++struct new_utsname; ++ + extern asmlinkage unsigned long sys_getpagesize(void); + extern asmlinkage unsigned long sparc_brk(unsigned long brk); + extern asmlinkage long sparc_pipe(struct pt_regs *regs); diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 6909016..0f1658d 100644 --- a/arch/sparc/kernel/systbls_32.S @@ -276169,10 +278224,16 @@ index a51ada8..4365ffd 100644 #ifdef CONFIG_COMPAT diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h -index c86e5ed..e63cf7d 100644 +index c86e5ed..139d4c1 100644 --- a/arch/x86/include/asm/nmi.h +++ b/arch/x86/include/asm/nmi.h -@@ -45,8 +45,8 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, +@@ -40,13 +40,12 @@ extern unsigned int nmi_watchdog; + #define NMI_INVALID 3 + + struct ctl_table; +-struct file; +-extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, ++extern int proc_nmi_enabled(struct ctl_table *, int , void __user *, size_t *, loff_t *); extern int unknown_nmi_panic; @@ -282188,7 +284249,7 @@ index 6ef00ba..08385e0 100644 apicid = hard_smp_processor_id(); diff --git a/arch/x86/kernel/apic/nmi.c b/arch/x86/kernel/apic/nmi.c -index b3025b4..cb66a22 100644 +index b3025b4..7ff61d6 100644 --- a/arch/x86/kernel/apic/nmi.c +++ b/arch/x86/kernel/apic/nmi.c @@ -39,7 +39,7 @@ @@ -282237,6 +284298,23 @@ index b3025b4..cb66a22 100644 } /* Could check oops_in_progress here too, but it's safer not to */ +@@ -506,14 +508,14 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) + /* + * proc handler for /proc/sys/kernel/nmi + */ +-int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, ++int proc_nmi_enabled(struct ctl_table *table, int write, + void __user *buffer, size_t *length, loff_t *ppos) + { + int old_state; + + nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; + old_state = nmi_watchdog_enabled; +- proc_dointvec(table, write, file, buffer, length, ppos); ++ proc_dointvec(table, write, buffer, length, ppos); + if (!!old_state == !!nmi_watchdog_enabled) + return 0; + @@ -552,14 +554,18 @@ int do_nmi_callback(struct pt_regs *regs, int cpu) return 0; } @@ -293696,6 +295774,30 @@ index c840571..2d8a371 100644 #include +diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c +index bca5fba..f7dd2a7 100644 +--- a/arch/x86/kernel/dumpstack_32.c ++++ b/arch/x86/kernel/dumpstack_32.c +@@ -5,7 +5,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c +index 54b0a32..a071e6b 100644 +--- a/arch/x86/kernel/dumpstack_64.c ++++ b/arch/x86/kernel/dumpstack_64.c +@@ -5,7 +5,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 5cb5725..85419bb 100644 --- a/arch/x86/kernel/e820.c @@ -298456,10 +300558,18 @@ index cddfb8d..596d54c 100644 ENTRY(trampoline_data) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c -index 5204332..8351175 100644 +index 5204332..7e37dce 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c -@@ -59,12 +59,12 @@ +@@ -14,7 +14,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -59,12 +58,12 @@ #include #ifdef CONFIG_X86_64 @@ -298473,7 +300583,7 @@ index 5204332..8351175 100644 asmlinkage int system_call(void); -@@ -73,11 +73,9 @@ char ignore_fpu_irq; +@@ -73,11 +72,9 @@ char ignore_fpu_irq; /* * The IDT has to be page-aligned to simplify the Pentium @@ -298487,7 +300597,7 @@ index 5204332..8351175 100644 #endif DECLARE_BITMAP(used_vectors, NR_VECTORS); -@@ -786,33 +784,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) +@@ -786,33 +783,34 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) #endif } @@ -298542,7 +300652,7 @@ index 5204332..8351175 100644 } /* -@@ -846,17 +845,8 @@ asmlinkage void math_state_restore(void) +@@ -846,17 +844,8 @@ asmlinkage void math_state_restore(void) } clts(); /* Allow maths ops (or we recurse) */ @@ -298561,7 +300671,7 @@ index 5204332..8351175 100644 } EXPORT_SYMBOL_GPL(math_state_restore); -@@ -980,7 +970,5 @@ void __init trap_init(void) +@@ -980,7 +969,5 @@ void __init trap_init(void) */ cpu_init(); @@ -299073,7 +301183,7 @@ index 9fc1782..92929fb 100644 diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c -index 25ee06a..cf53a78 100644 +index 25ee06a..8cb4974 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c @@ -87,6 +87,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) @@ -299084,6 +301194,27 @@ index 25ee06a..cf53a78 100644 write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } +@@ -227,19 +228,11 @@ static long __vsyscall(3) venosys_1(void) + } + + #ifdef CONFIG_SYSCTL +- +-static int +-vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, +- void __user *buffer, size_t *lenp, loff_t *ppos) +-{ +- return proc_dointvec(ctl, write, filp, buffer, lenp, ppos); +-} +- + static ctl_table kernel_table2[] = { + { .procname = "vsyscall64", + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = vsyscall_sysctl_change }, ++ .proc_handler = proc_dointvec }, + {} + }; + diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c new file mode 100644 index 0000000..4449a4a @@ -313388,7 +315519,7 @@ index 1658296..c8191de 100644 /* diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c -index 7e600c1..24952fd 100644 +index 7e600c1..dd38bfb 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -12,6 +12,7 @@ @@ -313399,7 +315530,15 @@ index 7e600c1..24952fd 100644 #include #include -@@ -686,7 +687,7 @@ static int cpa_process_alias(struct cpa_data *cpa) +@@ -143,6 +144,7 @@ void clflush_cache_range(void *vaddr, unsigned int size) + + mb(); + } ++EXPORT_SYMBOL_GPL(clflush_cache_range); + + static void __cpa_flush_all(void *arg) + { +@@ -686,7 +688,7 @@ static int cpa_process_alias(struct cpa_data *cpa) { struct cpa_data alias_cpa; unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); @@ -313408,7 +315547,7 @@ index 7e600c1..24952fd 100644 int ret; if (cpa->pfn >= max_pfn_mapped) -@@ -744,24 +745,6 @@ static int cpa_process_alias(struct cpa_data *cpa) +@@ -744,24 +746,6 @@ static int cpa_process_alias(struct cpa_data *cpa) } #endif @@ -313433,7 +315572,7 @@ index 7e600c1..24952fd 100644 return 0; } -@@ -822,6 +805,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, +@@ -822,6 +806,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, { struct cpa_data cpa; int ret, cache, checkalias; @@ -313441,7 +315580,7 @@ index 7e600c1..24952fd 100644 /* * Check, if we are requested to change a not supported -@@ -853,6 +837,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, +@@ -853,6 +838,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, */ WARN_ON_ONCE(1); } @@ -313453,7 +315592,7 @@ index 7e600c1..24952fd 100644 } /* Must avoid aliasing mappings in the highmem code */ -@@ -900,7 +889,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, +@@ -900,7 +890,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, cpa_flush_array(addr, numpages, cache, cpa.flags, pages); } else @@ -332370,7 +334509,7 @@ index f6baa77..e56b2a7 100644 "acpi=force is required to enable ACPI\n" ); return 1; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c -index 2876fc7..135fbfe 100644 +index 2876fc7..7411915 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -38,6 +38,7 @@ @@ -332381,7 +334520,73 @@ index 2876fc7..135fbfe 100644 #include "internal.h" -@@ -141,7 +142,7 @@ int acpi_bus_get_status(struct acpi_device *device) +@@ -93,36 +94,33 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device) + + EXPORT_SYMBOL(acpi_bus_get_device); + +-int acpi_bus_get_status(struct acpi_device *device) ++acpi_status acpi_bus_get_status_handle(acpi_handle handle, ++ unsigned long long *sta) + { +- acpi_status status = AE_OK; +- unsigned long long sta = 0; +- ++ acpi_status status; + +- if (!device) +- return -EINVAL; ++ status = acpi_evaluate_integer(handle, "_STA", NULL, sta); ++ if (ACPI_SUCCESS(status)) ++ return AE_OK; + +- /* +- * Evaluate _STA if present. +- */ +- if (device->flags.dynamic_status) { +- status = +- acpi_evaluate_integer(device->handle, "_STA", NULL, &sta); +- if (ACPI_FAILURE(status)) +- return -ENODEV; +- STRUCT_TO_INT(device->status) = (int)sta; ++ if (status == AE_NOT_FOUND) { ++ *sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | ++ ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; ++ return AE_OK; + } ++ return status; ++} + +- /* +- * According to ACPI spec some device can be present and functional +- * even if the parent is not present but functional. +- * In such conditions the child device should not inherit the status +- * from the parent. +- */ +- else +- STRUCT_TO_INT(device->status) = +- ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | +- ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; ++int acpi_bus_get_status(struct acpi_device *device) ++{ ++ acpi_status status; ++ unsigned long long sta; ++ ++ status = acpi_bus_get_status_handle(device->handle, &sta); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; ++ ++ STRUCT_TO_INT(device->status) = (int) sta; + + if (device->status.functional && !device->status.present) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " +@@ -134,14 +132,12 @@ int acpi_bus_get_status(struct acpi_device *device) + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", + device->pnp.bus_id, + (u32) STRUCT_TO_INT(device->status))); +- + return 0; + } +- EXPORT_SYMBOL(acpi_bus_get_status); void acpi_bus_private_data_handler(acpi_handle handle, @@ -332391,7 +334596,7 @@ index 2876fc7..135fbfe 100644 return; } diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c -index 9195deb..d295bdc 100644 +index 9195deb..9335b87 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -33,6 +33,8 @@ @@ -332403,6 +334608,85 @@ index 9195deb..d295bdc 100644 #define ACPI_BUTTON_CLASS "button" #define ACPI_BUTTON_FILE_INFO "info" #define ACPI_BUTTON_FILE_STATE "state" +@@ -113,6 +115,9 @@ static const struct file_operations acpi_button_state_fops = { + .release = single_release, + }; + ++static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); ++static struct acpi_device *lid_device; ++ + /* -------------------------------------------------------------------------- + FS Interface (/proc) + -------------------------------------------------------------------------- */ +@@ -229,11 +234,38 @@ static int acpi_button_remove_fs(struct acpi_device *device) + /* -------------------------------------------------------------------------- + Driver Interface + -------------------------------------------------------------------------- */ ++int acpi_lid_notifier_register(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_register(&acpi_lid_notifier, nb); ++} ++EXPORT_SYMBOL(acpi_lid_notifier_register); ++ ++int acpi_lid_notifier_unregister(struct notifier_block *nb) ++{ ++ return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb); ++} ++EXPORT_SYMBOL(acpi_lid_notifier_unregister); ++ ++int acpi_lid_open(void) ++{ ++ acpi_status status; ++ unsigned long long state; ++ ++ status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL, ++ &state); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; ++ ++ return !!state; ++} ++EXPORT_SYMBOL(acpi_lid_open); ++ + static int acpi_lid_send_state(struct acpi_device *device) + { + struct acpi_button *button = acpi_driver_data(device); + unsigned long long state; + acpi_status status; ++ int ret; + + status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state); + if (ACPI_FAILURE(status)) +@@ -242,7 +274,12 @@ static int acpi_lid_send_state(struct acpi_device *device) + /* input layer checks if event is redundant */ + input_report_switch(button->input, SW_LID, !state); + input_sync(button->input); +- return 0; ++ ++ ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); ++ if (ret == NOTIFY_DONE) ++ ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, ++ device); ++ return ret; + } + + static void acpi_button_notify(struct acpi_device *device, u32 event) +@@ -364,8 +401,14 @@ static int acpi_button_add(struct acpi_device *device) + error = input_register_device(input); + if (error) + goto err_remove_fs; +- if (button->type == ACPI_BUTTON_TYPE_LID) ++ if (button->type == ACPI_BUTTON_TYPE_LID) { + acpi_lid_send_state(device); ++ /* ++ * This assumes there's only one lid device, or if there are ++ * more we only care about the last one... ++ */ ++ lid_device = device; ++ } + + if (device->wakeup.flags.valid) { + /* Button's GPE is run-wake GPE */ diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 332fe4b..6c9ee68 100644 --- a/drivers/acpi/cm_sbs.c @@ -335301,10 +337585,19 @@ index 0619734..d933980 100644 #define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c -index 781435d..408ebde 100644 +index 781435d..2c4cac5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c -@@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, +@@ -22,6 +22,8 @@ extern struct acpi_device *acpi_root; + #define ACPI_BUS_HID "LNXSYBUS" + #define ACPI_BUS_DEVICE_NAME "System Bus" + ++#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) ++ + static LIST_HEAD(acpi_device_list); + static LIST_HEAD(acpi_bus_id_list); + DEFINE_MUTEX(acpi_device_lock); +@@ -60,13 +62,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, } if (acpi_dev->flags.compatible_ids) { @@ -335320,7 +337613,7 @@ index 781435d..408ebde 100644 if (count < 0 || count >= size) { printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", acpi_dev->pnp.device_name, i); -@@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, +@@ -287,14 +289,14 @@ int acpi_match_device_ids(struct acpi_device *device, } if (device->flags.compatible_ids) { @@ -335337,7 +337630,7 @@ index 781435d..408ebde 100644 return 0; } } -@@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev) +@@ -309,6 +311,10 @@ static void acpi_device_release(struct device *dev) struct acpi_device *acpi_dev = to_acpi_device(dev); kfree(acpi_dev->pnp.cid_list); @@ -335348,7 +337641,7 @@ index 781435d..408ebde 100644 kfree(acpi_dev); } -@@ -366,7 +370,8 @@ static acpi_status acpi_device_notify_fixed(void *data) +@@ -366,22 +372,21 @@ static acpi_status acpi_device_notify_fixed(void *data) { struct acpi_device *device = data; @@ -335358,6 +337651,36 @@ index 781435d..408ebde 100644 return AE_OK; } + static int acpi_device_install_notify_handler(struct acpi_device *device) + { + acpi_status status; +- char *hid; + +- hid = acpi_device_hid(device); +- if (!strcmp(hid, ACPI_BUTTON_HID_POWERF)) ++ if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) + status = + acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_device_notify_fixed, + device); +- else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) ++ else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) + status = + acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_device_notify_fixed, +@@ -399,10 +404,10 @@ static int acpi_device_install_notify_handler(struct acpi_device *device) + + static void acpi_device_remove_notify_handler(struct acpi_device *device) + { +- if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) ++ if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) + acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, + acpi_device_notify_fixed); +- else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) ++ else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) + acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, + acpi_device_notify_fixed); + else @@ -426,9 +431,6 @@ static int acpi_device_probe(struct device * dev) if (acpi_drv->ops.notify) { ret = acpi_device_install_notify_handler(acpi_dev); @@ -335377,7 +337700,65 @@ index 781435d..408ebde 100644 if (acpi_drv->ops.remove) acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); } -@@ -687,7 +687,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) +@@ -474,12 +474,12 @@ struct bus_type acpi_bus_type = { + .uevent = acpi_device_uevent, + }; + +-static int acpi_device_register(struct acpi_device *device, +- struct acpi_device *parent) ++static int acpi_device_register(struct acpi_device *device) + { + int result; + struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; + int found = 0; ++ + /* + * Linkage + * ------- +@@ -524,7 +524,7 @@ static int acpi_device_register(struct acpi_device *device, + mutex_unlock(&acpi_device_lock); + + if (device->parent) +- device->dev.parent = &parent->dev; ++ device->dev.parent = &device->parent->dev; + device->dev.bus = &acpi_bus_type; + device->dev.release = &acpi_device_release; + result = device_register(&device->dev); +@@ -664,6 +664,33 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver); + /* -------------------------------------------------------------------------- + Device Enumeration + -------------------------------------------------------------------------- */ ++static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) ++{ ++ acpi_status status; ++ int ret; ++ struct acpi_device *device; ++ ++ /* ++ * Fixed hardware devices do not appear in the namespace and do not ++ * have handles, but we fabricate acpi_devices for them, so we have ++ * to deal with them specially. ++ */ ++ if (handle == NULL) ++ return acpi_root; ++ ++ do { ++ status = acpi_get_parent(handle, &handle); ++ if (status == AE_NULL_ENTRY) ++ return NULL; ++ if (ACPI_FAILURE(status)) ++ return acpi_root; ++ ++ ret = acpi_bus_get_device(handle, &device); ++ if (ret == 0) ++ return device; ++ } while (1); ++} ++ + acpi_status + acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) + { +@@ -687,7 +714,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) } EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); @@ -335386,7 +337767,7 @@ index 781435d..408ebde 100644 { /* TBD */ -@@ -781,6 +781,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) +@@ -781,6 +808,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) kfree(buffer.pointer); device->wakeup.flags.valid = 1; @@ -335394,15 +337775,55 @@ index 781435d..408ebde 100644 /* Call _PSW/_DSW object to disable its ability to wake the sleeping * system for the ACPI device with the _PRW object. * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. -@@ -999,33 +1000,89 @@ static int acpi_dock_match(struct acpi_device *device) +@@ -917,8 +945,7 @@ static int acpi_bus_get_flags(struct acpi_device *device) + return 0; + } + +-static void acpi_device_get_busid(struct acpi_device *device, +- acpi_handle handle, int type) ++static void acpi_device_get_busid(struct acpi_device *device) + { + char bus_id[5] = { '?', 0 }; + struct acpi_buffer buffer = { sizeof(bus_id), bus_id }; +@@ -930,10 +957,12 @@ static void acpi_device_get_busid(struct acpi_device *device, + * The device's Bus ID is simply the object name. + * TBD: Shouldn't this value be unique (within the ACPI namespace)? + */ +- switch (type) { +- case ACPI_BUS_TYPE_SYSTEM: ++ if (ACPI_IS_ROOT_DEVICE(device)) { + strcpy(device->pnp.bus_id, "ACPI"); +- break; ++ return; ++ } ++ ++ switch (device->device_type) { + case ACPI_BUS_TYPE_POWER_BUTTON: + strcpy(device->pnp.bus_id, "PWRF"); + break; +@@ -941,7 +970,7 @@ static void acpi_device_get_busid(struct acpi_device *device, + strcpy(device->pnp.bus_id, "SLPF"); + break; + default: +- acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer); ++ acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); + /* Clean up trailing underscores (if any) */ + for (i = 3; i > 1; i--) { + if (bus_id[i] == '_') +@@ -999,33 +1028,92 @@ static int acpi_dock_match(struct acpi_device *device) return acpi_get_handle(device->handle, "_DCK", &tmp); } +-static void acpi_device_set_id(struct acpi_device *device, +- struct acpi_device *parent, acpi_handle handle, +- int type) +static struct acpica_device_id_list* +acpi_add_cid( + struct acpi_device_info *info, + struct acpica_device_id *new_cid) -+{ + { +- struct acpi_device_info *info; +- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpica_device_id_list *cid; + char *next_id_string; + acpi_size cid_length; @@ -335456,12 +337877,8 @@ index 781435d..408ebde 100644 + return cid; +} + - static void acpi_device_set_id(struct acpi_device *device, - struct acpi_device *parent, acpi_handle handle, - int type) - { -- struct acpi_device_info *info; -- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; ++static void acpi_device_set_id(struct acpi_device *device) ++{ + struct acpi_device_info *info = NULL; char *hid = NULL; char *uid = NULL; @@ -335471,10 +337888,16 @@ index 781435d..408ebde 100644 + char *cid_add = NULL; acpi_status status; - switch (type) { +- switch (type) { ++ switch (device->device_type) { case ACPI_BUS_TYPE_DEVICE: - status = acpi_get_object_info(handle, &buffer); -+ status = acpi_get_object_info(handle, &info); ++ if (ACPI_IS_ROOT_DEVICE(device)) { ++ hid = ACPI_SYSTEM_HID; ++ break; ++ } ++ ++ status = acpi_get_object_info(device->handle, &info); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); return; @@ -335493,7 +337916,26 @@ index 781435d..408ebde 100644 if (info->valid & ACPI_VALID_ADR) { device->pnp.bus_address = info->address; device->flags.bus_address = 1; -@@ -1076,55 +1133,46 @@ static void acpi_device_set_id(struct acpi_device *device, +@@ -1050,9 +1138,6 @@ static void acpi_device_set_id(struct acpi_device *device, + case ACPI_BUS_TYPE_PROCESSOR: + hid = ACPI_PROCESSOR_OBJECT_HID; + break; +- case ACPI_BUS_TYPE_SYSTEM: +- hid = ACPI_SYSTEM_HID; +- break; + case ACPI_BUS_TYPE_THERMAL: + hid = ACPI_THERMAL_HID; + break; +@@ -1069,87 +1154,77 @@ static void acpi_device_set_id(struct acpi_device *device, + * ---- + * Fix for the system root bus device -- the only root-level device. + */ +- if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) { ++ if (((acpi_handle)device->parent == ACPI_ROOT_OBJECT) && ++ (device->device_type == ACPI_BUS_TYPE_DEVICE)) { + hid = ACPI_BUS_HID; + strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME); + strcpy(device->pnp.device_class, ACPI_BUS_CLASS); } if (hid) { @@ -335578,11 +338020,150 @@ index 781435d..408ebde 100644 + kfree(info); } - static int acpi_device_set_context(struct acpi_device *device, int type) -@@ -1264,16 +1312,6 @@ acpi_add_single_object(struct acpi_device **child, - acpi_device_set_id(device, parent, handle, type); +-static int acpi_device_set_context(struct acpi_device *device, int type) ++static int acpi_device_set_context(struct acpi_device *device) + { +- acpi_status status = AE_OK; +- int result = 0; ++ acpi_status status; ++ + /* + * Context + * ------- + * Attach this 'struct acpi_device' to the ACPI object. This makes +- * resolutions from handle->device very efficient. Note that we need +- * to be careful with fixed-feature devices as they all attach to the +- * root object. ++ * resolutions from handle->device very efficient. Fixed hardware ++ * devices have no handles, so we skip them. + */ +- if (type != ACPI_BUS_TYPE_POWER_BUTTON && +- type != ACPI_BUS_TYPE_SLEEP_BUTTON) { +- status = acpi_attach_data(device->handle, +- acpi_bus_data_handler, device); ++ if (!device->handle) ++ return 0; + +- if (ACPI_FAILURE(status)) { +- printk(KERN_ERR PREFIX "Error attaching device data\n"); +- result = -ENODEV; +- } +- } +- return result; ++ status = acpi_attach_data(device->handle, ++ acpi_bus_data_handler, device); ++ if (ACPI_SUCCESS(status)) ++ return 0; ++ ++ printk(KERN_ERR PREFIX "Error attaching device data\n"); ++ return -ENODEV; + } + + static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) +@@ -1175,17 +1250,14 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) + return 0; + } + +-static int +-acpi_add_single_object(struct acpi_device **child, +- struct acpi_device *parent, acpi_handle handle, int type, +- struct acpi_bus_ops *ops) ++static int acpi_add_single_object(struct acpi_device **child, ++ acpi_handle handle, int type, ++ unsigned long long sta, ++ struct acpi_bus_ops *ops) + { +- int result = 0; +- struct acpi_device *device = NULL; +- +- +- if (!child) +- return -EINVAL; ++ int result; ++ struct acpi_device *device; ++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); + if (!device) { +@@ -1193,65 +1265,25 @@ acpi_add_single_object(struct acpi_device **child, + return -ENOMEM; + } + ++ device->device_type = type; + device->handle = handle; +- device->parent = parent; ++ device->parent = acpi_bus_get_parent(handle); + device->bus_ops = *ops; /* workround for not call .start */ ++ STRUCT_TO_INT(device->status) = sta; + +- +- acpi_device_get_busid(device, handle, type); ++ acpi_device_get_busid(device); /* + * Flags + * ----- +- * Get prior to calling acpi_bus_get_status() so we know whether +- * or not _STA is present. Note that we only look for object +- * handles -- cannot evaluate objects until we know the device is +- * present and properly initialized. ++ * Note that we only look for object handles -- cannot evaluate objects ++ * until we know the device is present and properly initialized. + */ + result = acpi_bus_get_flags(device); + if (result) + goto end; + + /* +- * Status +- * ------ +- * See if the device is present. We always assume that non-Device +- * and non-Processor objects (e.g. thermal zones, power resources, +- * etc.) are present, functioning, etc. (at least when parent object +- * is present). Note that _STA has a different meaning for some +- * objects (e.g. power resources) so we need to be careful how we use +- * it. +- */ +- switch (type) { +- case ACPI_BUS_TYPE_PROCESSOR: +- case ACPI_BUS_TYPE_DEVICE: +- result = acpi_bus_get_status(device); +- if (ACPI_FAILURE(result)) { +- result = -ENODEV; +- goto end; +- } +- /* +- * When the device is neither present nor functional, the +- * device should not be added to Linux ACPI device tree. +- * When the status of the device is not present but functinal, +- * it should be added to Linux ACPI tree. For example : bay +- * device , dock device. +- * In such conditions it is unncessary to check whether it is +- * bay device or dock device. +- */ +- if (!device->status.present && !device->status.functional) { +- result = -ENODEV; +- goto end; +- } +- break; +- default: +- STRUCT_TO_INT(device->status) = +- ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | +- ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; +- break; +- } +- +- /* + * Initialize Device + * ----------------- + * TBD: Synch with Core's enumeration/initialization process. +@@ -1261,17 +1293,7 @@ acpi_add_single_object(struct acpi_device **child, + * Hardware ID, Unique ID, & Bus Address + * ------------------------------------- + */ +- acpi_device_set_id(device, parent, handle, type); +- +- /* - * The ACPI device is attached to acpi handle before getting - * the power/wakeup/peformance flags. Otherwise OS can't get - * the corresponding ACPI device by the acpi handle in the course @@ -335591,33 +338172,357 @@ index 781435d..408ebde 100644 - result = acpi_device_set_context(device, type); - if (result) - goto end; -- -- /* ++ acpi_device_set_id(device); + + /* * Power Management - * ---------------- - */ -@@ -1303,6 +1341,8 @@ acpi_add_single_object(struct acpi_device **child, +@@ -1303,8 +1325,10 @@ acpi_add_single_object(struct acpi_device **child, goto end; } -+ if ((result = acpi_device_set_context(device, type))) ++ if ((result = acpi_device_set_context(device))) + goto end; - result = acpi_device_register(device, parent); +- result = acpi_device_register(device, parent); ++ result = acpi_device_register(device); + + /* + * Bind _ADR-Based Devices when hot add +@@ -1315,130 +1339,122 @@ acpi_add_single_object(struct acpi_device **child, + } -@@ -1317,10 +1357,8 @@ acpi_add_single_object(struct acpi_device **child, end: - if (!result) +- if (!result) ++ if (!result) { ++ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ++ "Adding %s [%s] parent %s\n", dev_name(&device->dev), ++ (char *) buffer.pointer, ++ device->parent ? dev_name(&device->parent->dev) : ++ "(null)")); ++ kfree(buffer.pointer); *child = device; - else { - kfree(device->pnp.cid_list); - kfree(device); - } -+ else ++ } else + acpi_device_release(&device->dev); return result; } + +-static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) ++#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ ++ ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) ++ ++static int acpi_bus_type_and_status(acpi_handle handle, int *type, ++ unsigned long long *sta) + { +- acpi_status status = AE_OK; +- struct acpi_device *parent = NULL; +- struct acpi_device *child = NULL; +- acpi_handle phandle = NULL; +- acpi_handle chandle = NULL; +- acpi_object_type type = 0; +- u32 level = 1; ++ acpi_status status; ++ acpi_object_type acpi_type; + ++ status = acpi_get_type(handle, &acpi_type); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; + +- if (!start) +- return -EINVAL; ++ switch (acpi_type) { ++ case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ ++ case ACPI_TYPE_DEVICE: ++ *type = ACPI_BUS_TYPE_DEVICE; ++ status = acpi_bus_get_status_handle(handle, sta); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; ++ break; ++ case ACPI_TYPE_PROCESSOR: ++ *type = ACPI_BUS_TYPE_PROCESSOR; ++ status = acpi_bus_get_status_handle(handle, sta); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; ++ break; ++ case ACPI_TYPE_THERMAL: ++ *type = ACPI_BUS_TYPE_THERMAL; ++ *sta = ACPI_STA_DEFAULT; ++ break; ++ case ACPI_TYPE_POWER: ++ *type = ACPI_BUS_TYPE_POWER; ++ *sta = ACPI_STA_DEFAULT; ++ break; ++ default: ++ return -ENODEV; ++ } + +- parent = start; +- phandle = start->handle; ++ return 0; ++} + +- /* +- * Parse through the ACPI namespace, identify all 'devices', and +- * create a new 'struct acpi_device' for each. +- */ +- while ((level > 0) && parent) { ++static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, ++ void *context, void **return_value) ++{ ++ struct acpi_bus_ops *ops = context; ++ int type; ++ unsigned long long sta; ++ struct acpi_device *device; ++ acpi_status status; ++ int result; + +- status = acpi_get_next_object(ACPI_TYPE_ANY, phandle, +- chandle, &chandle); ++ result = acpi_bus_type_and_status(handle, &type, &sta); ++ if (result) ++ return AE_OK; + +- /* +- * If this scope is exhausted then move our way back up. +- */ +- if (ACPI_FAILURE(status)) { +- level--; +- chandle = phandle; +- acpi_get_parent(phandle, &phandle); +- if (parent->parent) +- parent = parent->parent; +- continue; +- } ++ if (!(sta & ACPI_STA_DEVICE_PRESENT) && ++ !(sta & ACPI_STA_DEVICE_FUNCTIONING)) ++ return AE_CTRL_DEPTH; + +- status = acpi_get_type(chandle, &type); +- if (ACPI_FAILURE(status)) +- continue; ++ /* ++ * We may already have an acpi_device from a previous enumeration. If ++ * so, we needn't add it again, but we may still have to start it. ++ */ ++ device = NULL; ++ acpi_bus_get_device(handle, &device); ++ if (ops->acpi_op_add && !device) ++ acpi_add_single_object(&device, handle, type, sta, ops); + +- /* +- * If this is a scope object then parse it (depth-first). +- */ +- if (type == ACPI_TYPE_LOCAL_SCOPE) { +- level++; +- phandle = chandle; +- chandle = NULL; +- continue; +- } ++ if (!device) ++ return AE_CTRL_DEPTH; + +- /* +- * We're only interested in objects that we consider 'devices'. +- */ +- switch (type) { +- case ACPI_TYPE_DEVICE: +- type = ACPI_BUS_TYPE_DEVICE; +- break; +- case ACPI_TYPE_PROCESSOR: +- type = ACPI_BUS_TYPE_PROCESSOR; +- break; +- case ACPI_TYPE_THERMAL: +- type = ACPI_BUS_TYPE_THERMAL; +- break; +- case ACPI_TYPE_POWER: +- type = ACPI_BUS_TYPE_POWER; +- break; +- default: +- continue; +- } ++ if (ops->acpi_op_start && !(ops->acpi_op_add)) { ++ status = acpi_start_single_object(device); ++ if (ACPI_FAILURE(status)) ++ return AE_CTRL_DEPTH; ++ } + +- if (ops->acpi_op_add) +- status = acpi_add_single_object(&child, parent, +- chandle, type, ops); +- else +- status = acpi_bus_get_device(chandle, &child); ++ if (!*return_value) ++ *return_value = device; ++ return AE_OK; ++} + +- if (ACPI_FAILURE(status)) +- continue; ++static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, ++ struct acpi_device **child) ++{ ++ acpi_status status; ++ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; ++ void *device = NULL; + +- if (ops->acpi_op_start && !(ops->acpi_op_add)) { +- status = acpi_start_single_object(child); +- if (ACPI_FAILURE(status)) +- continue; +- } ++ acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); ++ printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n", ++ (char *) buffer.pointer); + +- /* +- * If the device is present, enabled, and functioning then +- * parse its scope (depth-first). Note that we need to +- * represent absent devices to facilitate PnP notifications +- * -- but only the subtree head (not all of its children, +- * which will be enumerated when the parent is inserted). +- * +- * TBD: Need notifications and other detection mechanisms +- * in place before we can fully implement this. +- */ +- /* +- * When the device is not present but functional, it is also +- * necessary to scan the children of this device. +- */ +- if (child->status.present || (!child->status.present && +- child->status.functional)) { +- status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, +- NULL, NULL); +- if (ACPI_SUCCESS(status)) { +- level++; +- phandle = chandle; +- chandle = NULL; +- parent = child; +- } +- } +- } ++ status = acpi_bus_check_add(handle, 0, ops, &device); ++ if (ACPI_SUCCESS(status)) ++ acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, ++ acpi_bus_check_add, ops, &device); + ++ if (child) ++ *child = device; + return 0; + } + +@@ -1446,36 +1462,25 @@ int + acpi_bus_add(struct acpi_device **child, + struct acpi_device *parent, acpi_handle handle, int type) + { +- int result; + struct acpi_bus_ops ops; + + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + +- result = acpi_add_single_object(child, parent, handle, type, &ops); +- if (!result) +- result = acpi_bus_scan(*child, &ops); +- +- return result; ++ acpi_bus_scan(handle, &ops, child); ++ return 0; + } + EXPORT_SYMBOL(acpi_bus_add); + + int acpi_bus_start(struct acpi_device *device) + { +- int result; + struct acpi_bus_ops ops; + ++ memset(&ops, 0, sizeof(ops)); ++ ops.acpi_op_start = 1; + +- if (!device) +- return -EINVAL; +- +- result = acpi_start_single_object(device); +- if (!result) { +- memset(&ops, 0, sizeof(ops)); +- ops.acpi_op_start = 1; +- result = acpi_bus_scan(device, &ops); +- } +- return result; ++ acpi_bus_scan(device->handle, &ops, NULL); ++ return 0; + } + EXPORT_SYMBOL(acpi_bus_start); + +@@ -1534,15 +1539,12 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice) + } + EXPORT_SYMBOL_GPL(acpi_bus_trim); + +-static int acpi_bus_scan_fixed(struct acpi_device *root) ++static int acpi_bus_scan_fixed(void) + { + int result = 0; + struct acpi_device *device = NULL; + struct acpi_bus_ops ops; + +- if (!root) +- return -ENODEV; +- + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; +@@ -1551,16 +1553,16 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) + * Enumerate all fixed-feature devices. + */ + if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { +- result = acpi_add_single_object(&device, acpi_root, +- NULL, ++ result = acpi_add_single_object(&device, NULL, + ACPI_BUS_TYPE_POWER_BUTTON, ++ ACPI_STA_DEFAULT, + &ops); + } + + if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { +- result = acpi_add_single_object(&device, acpi_root, +- NULL, ++ result = acpi_add_single_object(&device, NULL, + ACPI_BUS_TYPE_SLEEP_BUTTON, ++ ACPI_STA_DEFAULT, + &ops); + } + +@@ -1583,24 +1585,15 @@ int __init acpi_scan_init(void) + } + + /* +- * Create the root device in the bus's device tree +- */ +- result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, +- ACPI_BUS_TYPE_SYSTEM, &ops); +- if (result) +- goto Done; +- +- /* + * Enumerate devices in the ACPI namespace. + */ +- result = acpi_bus_scan_fixed(acpi_root); ++ result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root); + + if (!result) +- result = acpi_bus_scan(acpi_root, &ops); ++ result = acpi_bus_scan_fixed(); + + if (result) + acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); + +-Done: + return result; + } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 42159a2..a90afcc 100644 --- a/drivers/acpi/sleep.c @@ -335730,7 +338635,7 @@ index f844941..811fec1 100644 ACPI_MODULE_NAME("utils"); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c -index 60ea984..94b1a4c 100644 +index 60ea984..a4fddb2 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -40,10 +40,12 @@ @@ -335910,7 +338815,18 @@ index 60ea984..94b1a4c 100644 if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { video->cap._DOS = 1; } -@@ -2009,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) +@@ -1960,6 +1986,10 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) + + result = acpi_video_device_lcd_set_level(device, level_next); + ++ if (!result) ++ backlight_force_update(device->backlight, ++ BACKLIGHT_UPDATE_HOTKEY); ++ + out: + if (result) + printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); +@@ -2009,13 +2039,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) backlight_device_unregister(device->backlight); device->backlight = NULL; } @@ -338681,6 +341597,129 @@ index 8f98332..f8a91bf 100644 if (!(pi.flags & SIS_FLAG_CFGSCR)) { void __iomem *mmio; +diff --git a/drivers/atm/he.c b/drivers/atm/he.c +index 2de6406..29e66d6 100644 +--- a/drivers/atm/he.c ++++ b/drivers/atm/he.c +@@ -790,11 +790,15 @@ he_init_group(struct he_dev *he_dev, int group) + he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys); + if (he_dev->rbps_base == NULL) { +- hprintk("failed to alloc rbps\n"); +- return -ENOMEM; ++ hprintk("failed to alloc rbps_base\n"); ++ goto out_destroy_rbps_pool; + } + memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp)); + he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL); ++ if (he_dev->rbps_virt == NULL) { ++ hprintk("failed to alloc rbps_virt\n"); ++ goto out_free_rbps_base; ++ } + + for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { + dma_addr_t dma_handle; +@@ -802,7 +806,7 @@ he_init_group(struct he_dev *he_dev, int group) + + cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle); + if (cpuaddr == NULL) +- return -ENOMEM; ++ goto out_free_rbps_virt; + + he_dev->rbps_virt[i].virt = cpuaddr; + he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF); +@@ -827,17 +831,21 @@ he_init_group(struct he_dev *he_dev, int group) + CONFIG_RBPL_BUFSIZE, 8, 0); + if (he_dev->rbpl_pool == NULL) { + hprintk("unable to create rbpl pool\n"); +- return -ENOMEM; ++ goto out_free_rbps_virt; + } + + he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys); + if (he_dev->rbpl_base == NULL) { +- hprintk("failed to alloc rbpl\n"); +- return -ENOMEM; ++ hprintk("failed to alloc rbpl_base\n"); ++ goto out_destroy_rbpl_pool; + } + memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp)); + he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL); ++ if (he_dev->rbpl_virt == NULL) { ++ hprintk("failed to alloc rbpl_virt\n"); ++ goto out_free_rbpl_base; ++ } + + for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { + dma_addr_t dma_handle; +@@ -845,7 +853,7 @@ he_init_group(struct he_dev *he_dev, int group) + + cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle); + if (cpuaddr == NULL) +- return -ENOMEM; ++ goto out_free_rbpl_virt; + + he_dev->rbpl_virt[i].virt = cpuaddr; + he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF); +@@ -870,7 +878,7 @@ he_init_group(struct he_dev *he_dev, int group) + CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys); + if (he_dev->rbrq_base == NULL) { + hprintk("failed to allocate rbrq\n"); +- return -ENOMEM; ++ goto out_free_rbpl_virt; + } + memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq)); + +@@ -894,7 +902,7 @@ he_init_group(struct he_dev *he_dev, int group) + CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), &he_dev->tbrq_phys); + if (he_dev->tbrq_base == NULL) { + hprintk("failed to allocate tbrq\n"); +- return -ENOMEM; ++ goto out_free_rbpq_base; + } + memset(he_dev->tbrq_base, 0, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq)); + +@@ -906,6 +914,39 @@ he_init_group(struct he_dev *he_dev, int group) + he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16)); + + return 0; ++ ++out_free_rbpq_base: ++ pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * ++ sizeof(struct he_rbrq), he_dev->rbrq_base, ++ he_dev->rbrq_phys); ++ i = CONFIG_RBPL_SIZE; ++out_free_rbpl_virt: ++ while (--i) ++ pci_pool_free(he_dev->rbps_pool, he_dev->rbpl_virt[i].virt, ++ he_dev->rbps_base[i].phys); ++ kfree(he_dev->rbpl_virt); ++ ++out_free_rbpl_base: ++ pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * ++ sizeof(struct he_rbp), he_dev->rbpl_base, ++ he_dev->rbpl_phys); ++out_destroy_rbpl_pool: ++ pci_pool_destroy(he_dev->rbpl_pool); ++ ++ i = CONFIG_RBPL_SIZE; ++out_free_rbps_virt: ++ while (--i) ++ pci_pool_free(he_dev->rbpl_pool, he_dev->rbps_virt[i].virt, ++ he_dev->rbpl_base[i].phys); ++ kfree(he_dev->rbps_virt); ++ ++out_free_rbps_base: ++ pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE * ++ sizeof(struct he_rbp), he_dev->rbps_base, ++ he_dev->rbps_phys); ++out_destroy_rbps_pool: ++ pci_pool_destroy(he_dev->rbps_pool); ++ return -ENOMEM; + } + + static int __devinit diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 6b969f8..01ce241 100644 --- a/drivers/atm/horizon.c @@ -338703,11 +341742,97 @@ index 6b969f8..01ce241 100644 break; default: /* round_up */ pre = br/(c<buffers) + (nr)*BUF_SIZE*2) +-#define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE) ++#define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2) ++#define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size)) ++#define FLASH_BUF ((card->buffers) + 4*(card->buffer_size)*2) + + #define RX_DMA_SIZE 2048 + ++#define FPGA_VERSION(a,b) (((a) << 8) + (b)) ++#define LEGACY_BUFFERS 2 ++#define DMA_SUPPORTED 4 ++ + static int reset = 0; + static int atmdebug = 0; + static int firmware_upgrade = 0; + static int fpga_upgrade = 0; ++static int db_firmware_upgrade = 0; ++static int db_fpga_upgrade = 0; + + struct pkt_hdr { + __le16 size; +@@ -116,6 +124,8 @@ struct solos_card { + wait_queue_head_t param_wq; + wait_queue_head_t fw_wq; + int using_dma; ++ int fpga_version; ++ int buffer_size; + }; + + +@@ -136,10 +146,14 @@ MODULE_PARM_DESC(reset, "Reset Solos chips on startup"); + MODULE_PARM_DESC(atmdebug, "Print ATM data"); + MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade"); + MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade"); ++MODULE_PARM_DESC(db_firmware_upgrade, "Initiate daughter board Solos firmware upgrade"); ++MODULE_PARM_DESC(db_fpga_upgrade, "Initiate daughter board FPGA upgrade"); + module_param(reset, int, 0444); + module_param(atmdebug, int, 0644); + module_param(firmware_upgrade, int, 0444); + module_param(fpga_upgrade, int, 0444); ++module_param(db_firmware_upgrade, int, 0444); ++module_param(db_fpga_upgrade, int, 0444); + + static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb, + struct atm_vcc *vcc); +@@ -372,7 +386,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb } snr = next_string(skb); @@ -338716,6 +341841,110 @@ index 9359613..307321b 100644 return -EIO; attn = next_string(skb); if (!attn) +@@ -517,10 +531,32 @@ static int flash_upgrade(struct solos_card *card, int chip) + if (chip == 0) { + fw_name = "solos-FPGA.bin"; + blocksize = FPGA_BLOCK; +- } else { ++ } ++ ++ if (chip == 1) { + fw_name = "solos-Firmware.bin"; + blocksize = SOLOS_BLOCK; + } ++ ++ if (chip == 2){ ++ if (card->fpga_version > LEGACY_BUFFERS){ ++ fw_name = "solos-db-FPGA.bin"; ++ blocksize = FPGA_BLOCK; ++ } else { ++ dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n"); ++ return -EPERM; ++ } ++ } ++ ++ if (chip == 3){ ++ if (card->fpga_version > LEGACY_BUFFERS){ ++ fw_name = "solos-Firmware.bin"; ++ blocksize = SOLOS_BLOCK; ++ } else { ++ dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n"); ++ return -EPERM; ++ } ++ } + + if (request_firmware(&fw, fw_name, &card->dev->dev)) + return -ENOENT; +@@ -536,8 +572,10 @@ static int flash_upgrade(struct solos_card *card, int chip) + data32 = ioread32(card->config_regs + FPGA_MODE); + + /* Set mode to Chip Erase */ +- dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n", +- chip?"Solos":"FPGA"); ++ if(chip == 0 || chip == 2) ++ dev_info(&card->dev->dev, "Set FPGA Flash mode to FPGA Chip Erase\n"); ++ if(chip == 1 || chip == 3) ++ dev_info(&card->dev->dev, "Set FPGA Flash mode to Solos Chip Erase\n"); + iowrite32((chip * 2), card->config_regs + FLASH_MODE); + + +@@ -557,7 +595,10 @@ static int flash_upgrade(struct solos_card *card, int chip) + /* Copy block to buffer, swapping each 16 bits */ + for(i = 0; i < blocksize; i += 4) { + uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i)); +- iowrite32(word, RX_BUF(card, 3) + i); ++ if(card->fpga_version > LEGACY_BUFFERS) ++ iowrite32(word, FLASH_BUF + i); ++ else ++ iowrite32(word, RX_BUF(card, 3) + i); + } + + /* Specify block number and then trigger flash write */ +@@ -630,6 +671,10 @@ void solos_bh(unsigned long card_arg) + memcpy_fromio(header, RX_BUF(card, port), sizeof(*header)); + + size = le16_to_cpu(header->size); ++ if (size > (card->buffer_size - sizeof(*header))){ ++ dev_warn(&card->dev->dev, "Invalid buffer size\n"); ++ continue; ++ } + + skb = alloc_skb(size + 1, GFP_ATOMIC); + if (!skb) { +@@ -1094,12 +1139,18 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + fpga_ver = (data32 & 0x0000FFFF); + major_ver = ((data32 & 0xFF000000) >> 24); + minor_ver = ((data32 & 0x00FF0000) >> 16); ++ card->fpga_version = FPGA_VERSION(major_ver,minor_ver); ++ if (card->fpga_version > LEGACY_BUFFERS) ++ card->buffer_size = BUF_SIZE; ++ else ++ card->buffer_size = OLD_BUF_SIZE; + dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n", + major_ver, minor_ver, fpga_ver); + +- if (0 && fpga_ver > 27) ++ if (card->fpga_version >= DMA_SUPPORTED){ + card->using_dma = 1; +- else { ++ } else { ++ card->using_dma = 0; + /* Set RX empty flag for all ports */ + iowrite32(0xF0, card->config_regs + FLAGS_ADDR); + } +@@ -1131,6 +1182,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) + if (firmware_upgrade) + flash_upgrade(card, 1); + ++ if (db_fpga_upgrade) ++ flash_upgrade(card, 2); ++ ++ if (db_firmware_upgrade) ++ flash_upgrade(card, 3); ++ + err = atm_init(card); + if (err) + goto out_free_irq; diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 8f006f9..ee37727 100644 --- a/drivers/base/Kconfig @@ -341952,7 +345181,7 @@ index 4bf8705..4f68843 100644 .locked_ioctl = brd_ioctl, #ifdef CONFIG_BLK_DEV_XIP diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c -index a52cc7f..4d879b7 100644 +index a52cc7f..78852b1 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -36,9 +36,11 @@ @@ -342013,24 +345242,29 @@ index a52cc7f..4d879b7 100644 .owner = THIS_MODULE, .open = cciss_open, .release = cciss_release, -@@ -245,8 +256,6 @@ static inline void removeQ(CommandList_struct *c) +@@ -245,7 +256,10 @@ static inline void removeQ(CommandList_struct *c) #include "cciss_scsi.c" /* For SCSI tape support */ -#define RAID_UNKNOWN 6 -- ++static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", ++ "UNKNOWN" ++}; ++#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1) + #ifdef CONFIG_PROC_FS - /* -@@ -258,6 +267,7 @@ static inline void removeQ(CommandList_struct *c) - static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", - "UNKNOWN" - }; -+#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1) +@@ -255,9 +269,6 @@ static inline void removeQ(CommandList_struct *c) + #define ENG_GIG 1000000000 + #define ENG_GIG_FACTOR (ENG_GIG/512) + #define ENGAGE_SCSI "engage scsi" +-static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", +- "UNKNOWN" +-}; static struct proc_dir_entry *proc_cciss; -@@ -318,7 +328,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) +@@ -318,7 +329,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) ctlr_info_t *h = seq->private; unsigned ctlr = h->ctlr; loff_t *pos = v; @@ -342039,7 +345273,7 @@ index a52cc7f..4d879b7 100644 if (*pos > h->highest_lun) return 0; -@@ -331,7 +341,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) +@@ -331,7 +342,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v) vol_sz_frac *= 100; sector_div(vol_sz_frac, ENG_GIG_FACTOR); @@ -342048,7 +345282,7 @@ index a52cc7f..4d879b7 100644 drv->raid_level = RAID_UNKNOWN; seq_printf(seq, "cciss/c%dd%d:" "\t%4u.%02uGB\tRAID %s\n", -@@ -363,7 +373,7 @@ static void cciss_seq_stop(struct seq_file *seq, void *v) +@@ -363,7 +374,7 @@ static void cciss_seq_stop(struct seq_file *seq, void *v) h->busy_configuring = 0; } @@ -342057,7 +345291,7 @@ index a52cc7f..4d879b7 100644 .start = cciss_seq_start, .show = cciss_seq_show, .next = cciss_seq_next, -@@ -454,9 +464,19 @@ static void __devinit cciss_procinit(int i) +@@ -454,9 +465,19 @@ static void __devinit cciss_procinit(int i) #define to_hba(n) container_of(n, struct ctlr_info, dev) #define to_drv(n) container_of(n, drive_info_struct, dev) @@ -342080,7 +345314,7 @@ index a52cc7f..4d879b7 100644 static ssize_t dev_show_unique_id(struct device *dev, struct device_attribute *attr, -@@ -560,11 +580,101 @@ static ssize_t dev_show_rev(struct device *dev, +@@ -560,11 +581,101 @@ static ssize_t dev_show_rev(struct device *dev, } DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); @@ -342182,7 +345416,7 @@ index a52cc7f..4d879b7 100644 NULL }; -@@ -572,7 +682,7 @@ static struct attribute_group cciss_dev_attr_group = { +@@ -572,7 +683,7 @@ static struct attribute_group cciss_dev_attr_group = { .attrs = cciss_dev_attrs, }; @@ -342191,7 +345425,7 @@ index a52cc7f..4d879b7 100644 &cciss_dev_attr_group, NULL }; -@@ -580,12 +690,24 @@ static struct attribute_group *cciss_dev_attr_groups[] = { +@@ -580,12 +691,24 @@ static struct attribute_group *cciss_dev_attr_groups[] = { static struct device_type cciss_dev_type = { .name = "cciss_device", .groups = cciss_dev_attr_groups, @@ -342216,7 +345450,7 @@ index a52cc7f..4d879b7 100644 /* * Initialize sysfs entry for each controller. This sets up and registers -@@ -609,6 +731,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) +@@ -609,6 +732,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h) static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) { device_del(&h->dev); @@ -342233,7 +345467,7 @@ index a52cc7f..4d879b7 100644 } /* -@@ -617,24 +749,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) +@@ -617,24 +750,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) * /sys/bus/pci/devices/bd_disk->disk_name); #endif /* CCISS_DEBUG */ @@ -342292,7 +345526,7 @@ index a52cc7f..4d879b7 100644 return -EBUSY; /* * Root is allowed to open raw volume zero even if it's not configured -@@ -767,7 +914,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) +@@ -767,7 +915,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) if (MINOR(bdev->bd_dev) & 0x0f) { return -ENXIO; /* if it is, make sure we have a LUN ID */ @@ -342302,7 +345536,7 @@ index a52cc7f..4d879b7 100644 return -ENXIO; } } -@@ -1132,12 +1280,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, +@@ -1132,12 +1281,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, case CCISS_DEREGDISK: case CCISS_REGNEWD: case CCISS_REVALIDVOLS: @@ -342318,7 +345552,7 @@ index a52cc7f..4d879b7 100644 luninfo.num_opens = drv->usage_count; luninfo.num_parts = 0; if (copy_to_user(argp, &luninfo, -@@ -1475,7 +1624,10 @@ static void cciss_check_queues(ctlr_info_t *h) +@@ -1475,7 +1625,10 @@ static void cciss_check_queues(ctlr_info_t *h) /* make sure the disk has been added and the drive is real * because this can be called from the middle of init_one. */ @@ -342330,7 +345564,7 @@ index a52cc7f..4d879b7 100644 continue; blk_start_queue(h->gendisk[curr_queue]->queue); -@@ -1532,13 +1684,11 @@ static void cciss_softirq_done(struct request *rq) +@@ -1532,13 +1685,11 @@ static void cciss_softirq_done(struct request *rq) spin_unlock_irqrestore(&h->lock, flags); } @@ -342348,7 +345582,7 @@ index a52cc7f..4d879b7 100644 } /* This function gets the SCSI vendor, model, and revision of a logical drive -@@ -1615,16 +1765,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, +@@ -1615,16 +1766,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, return; } @@ -342375,7 +345609,7 @@ index a52cc7f..4d879b7 100644 /* Set up queue information */ blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); -@@ -1642,14 +1799,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, +@@ -1642,14 +1800,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, disk->queue->queuedata = h; blk_queue_logical_block_size(disk->queue, @@ -342400,7 +345634,7 @@ index a52cc7f..4d879b7 100644 } /* This function will check the usage_count of the drive to be updated/added. -@@ -1662,7 +1826,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, +@@ -1662,7 +1827,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, * is also the controller node. Any changes to disk 0 will show up on * the next reboot. */ @@ -342410,7 +345644,7 @@ index a52cc7f..4d879b7 100644 { ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; -@@ -1672,21 +1837,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) +@@ -1672,21 +1838,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) unsigned long flags = 0; int ret = 0; drive_info_struct *drvinfo; @@ -342433,7 +345667,7 @@ index a52cc7f..4d879b7 100644 /* testing to see if 16-byte CDBs are already being used */ if (h->cciss_read == CCISS_READ_16) { cciss_read_capacity_16(h->ctlr, drv_index, 1, -@@ -1719,16 +1876,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) +@@ -1719,16 +1877,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) drvinfo->model, drvinfo->rev); cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, sizeof(drvinfo->serial_no)); @@ -342460,7 +345694,7 @@ index a52cc7f..4d879b7 100644 /* The disk is unchanged, nothing to update */ goto freeret; -@@ -1738,18 +1898,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) +@@ -1738,18 +1899,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) * If the disk already exists then deregister it before proceeding * (unless it's the first disk (for the controller node). */ @@ -342483,7 +345717,7 @@ index a52cc7f..4d879b7 100644 } /* If the disk is in use return */ -@@ -1757,22 +1916,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) +@@ -1757,22 +1917,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) goto freeret; /* Save the new information from cciss_geometry_inquiry @@ -342527,7 +345761,7 @@ index a52cc7f..4d879b7 100644 /* If it's not disk 0 (drv_index != 0) * or if it was disk 0, but there was previously -@@ -1780,8 +1948,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) +@@ -1780,8 +1949,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) * (raid_leve == -1) then we want to update the * logical drive's information. */ @@ -342545,7 +345779,7 @@ index a52cc7f..4d879b7 100644 freeret: kfree(inq_buff); -@@ -1793,28 +1968,70 @@ mem_msg: +@@ -1793,28 +1969,70 @@ mem_msg: } /* This function will find the first index of the controllers drive array @@ -342628,7 +345862,7 @@ index a52cc7f..4d879b7 100644 /* cciss_add_gendisk finds a free hba[]->drv structure * and allocates a gendisk if needed, and sets the lunid * in the drvinfo structure. It returns the index into -@@ -1824,13 +2041,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node) +@@ -1824,13 +2042,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node) * a means to talk to the controller in case no logical * drives have yet been configured. */ @@ -342646,7 +345880,7 @@ index a52cc7f..4d879b7 100644 /*Check if the gendisk needs to be allocated */ if (!h->gendisk[drv_index]) { h->gendisk[drv_index] = -@@ -1839,23 +2058,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) +@@ -1839,23 +2059,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) printk(KERN_ERR "cciss%d: could not " "allocate a new disk %d\n", h->ctlr, drv_index); @@ -342678,7 +345912,7 @@ index a52cc7f..4d879b7 100644 return -1; } -@@ -1872,21 +2092,25 @@ static void cciss_add_controller_node(ctlr_info_t *h) +@@ -1872,21 +2093,25 @@ static void cciss_add_controller_node(ctlr_info_t *h) if (h->gendisk[0] != NULL) /* already did this? Then bail. */ return; @@ -342718,7 +345952,7 @@ index a52cc7f..4d879b7 100644 } /* This function will add and remove logical drives from the Logical -@@ -1897,7 +2121,8 @@ static void cciss_add_controller_node(ctlr_info_t *h) +@@ -1897,7 +2122,8 @@ static void cciss_add_controller_node(ctlr_info_t *h) * INPUT * h = The controller to perform the operations on */ @@ -342728,7 +345962,7 @@ index a52cc7f..4d879b7 100644 { int ctlr = h->ctlr; int num_luns; -@@ -1907,7 +2132,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) +@@ -1907,7 +2133,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) int i; int drv_found; int drv_index = 0; @@ -342737,7 +345971,7 @@ index a52cc7f..4d879b7 100644 unsigned long flags; if (!capable(CAP_SYS_RAWIO)) -@@ -1960,13 +2185,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) +@@ -1960,13 +2186,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) drv_found = 0; /* skip holes in the array from already deleted drives */ @@ -342755,7 +345989,7 @@ index a52cc7f..4d879b7 100644 drv_found = 1; break; } -@@ -1974,11 +2199,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) +@@ -1974,11 +2200,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) if (!drv_found) { /* Deregister it from the OS, it's gone. */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); @@ -342771,7 +346005,7 @@ index a52cc7f..4d879b7 100644 } } -@@ -1992,17 +2217,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) +@@ -1992,17 +2218,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) drv_found = 0; @@ -342793,7 +346027,7 @@ index a52cc7f..4d879b7 100644 drv_index = j; drv_found = 1; break; -@@ -2015,7 +2239,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) +@@ -2015,7 +2240,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) if (drv_index == -1) goto freeret; } @@ -342803,7 +346037,7 @@ index a52cc7f..4d879b7 100644 } /* end for */ freeret: -@@ -2032,6 +2257,25 @@ mem_msg: +@@ -2032,6 +2258,25 @@ mem_msg: goto freeret; } @@ -342829,7 +346063,7 @@ index a52cc7f..4d879b7 100644 /* This function will deregister the disk and it's queue from the * kernel. It must be called with the controller lock held and the * drv structures busy_configuring flag set. It's parameters are: -@@ -2046,43 +2290,48 @@ mem_msg: +@@ -2046,43 +2291,48 @@ mem_msg: * the disk in preparation for re-adding it. In this case * the highest_lun should be left unchanged and the LunID * should not be cleared. @@ -342889,7 +346123,7 @@ index a52cc7f..4d879b7 100644 /* If clear_all is set then we are deleting the logical * drive, not just refreshing its info. For drives * other than disk 0 we will call put_disk. We do not -@@ -2105,34 +2354,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, +@@ -2105,34 +2355,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, } } else { set_capacity(disk, 0); @@ -342934,7 +346168,7 @@ index a52cc7f..4d879b7 100644 } return 0; } -@@ -2479,8 +2714,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, +@@ -2479,8 +2715,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); } @@ -342943,7 +346177,7 @@ index a52cc7f..4d879b7 100644 } static void -@@ -2514,9 +2747,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, +@@ -2514,9 +2748,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, *total_size = 0; *block_size = BLOCK_SIZE; } @@ -342953,7 +346187,7 @@ index a52cc7f..4d879b7 100644 kfree(buf); } -@@ -2568,7 +2798,8 @@ static int cciss_revalidate(struct gendisk *disk) +@@ -2568,7 +2799,8 @@ static int cciss_revalidate(struct gendisk *disk) InquiryData_struct *inq_buff = NULL; for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { @@ -342963,7 +346197,7 @@ index a52cc7f..4d879b7 100644 FOUND = 1; break; } -@@ -3053,8 +3284,7 @@ static void do_cciss_request(struct request_queue *q) +@@ -3053,8 +3285,7 @@ static void do_cciss_request(struct request_queue *q) /* The first 2 bits are reserved for controller error reporting. */ c->Header.Tag.lower = (c->cmdindex << 3); c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ @@ -342973,7 +346207,7 @@ index a52cc7f..4d879b7 100644 c->Request.CDBLen = 10; // 12 byte commands not in FW yet; c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Attribute = ATTR_SIMPLE; -@@ -3232,20 +3462,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) +@@ -3232,20 +3463,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) return IRQ_HANDLED; } @@ -343103,7 +346337,7 @@ index a52cc7f..4d879b7 100644 return 0; } -@@ -3268,8 +3599,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) +@@ -3268,8 +3600,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) case REPORT_LUNS_CHANGED: printk(KERN_WARNING "cciss%d: report LUN data " "changed\n", h->ctlr); @@ -343114,7 +346348,7 @@ index a52cc7f..4d879b7 100644 return 1; break; case POWER_OR_RESET: -@@ -3489,7 +3820,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) +@@ -3489,7 +3821,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) if (scratchpad == CCISS_FIRMWARE_READY) break; set_current_state(TASK_INTERRUPTIBLE); @@ -343123,7 +346357,7 @@ index a52cc7f..4d879b7 100644 } if (scratchpad != CCISS_FIRMWARE_READY) { printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); -@@ -3615,7 +3946,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) +@@ -3615,7 +3947,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) break; /* delay and try again */ set_current_state(TASK_INTERRUPTIBLE); @@ -343132,7 +346366,7 @@ index a52cc7f..4d879b7 100644 } #ifdef CCISS_DEBUG -@@ -3669,15 +4000,16 @@ Enomem: +@@ -3669,15 +4001,16 @@ Enomem: return -1; } @@ -343156,7 +346390,7 @@ index a52cc7f..4d879b7 100644 } /* Send a message CDB to the firmware. */ -@@ -3889,7 +4221,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, +@@ -3889,7 +4222,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int j = 0; int rc; int dac, return_code; @@ -343165,7 +346399,7 @@ index a52cc7f..4d879b7 100644 if (reset_devices) { /* Reset the controller with a PCI power-cycle */ -@@ -3918,6 +4250,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, +@@ -3918,6 +4251,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->busy_initializing = 1; INIT_HLIST_HEAD(&hba[i]->cmpQ); INIT_HLIST_HEAD(&hba[i]->reqQ); @@ -343173,7 +346407,7 @@ index a52cc7f..4d879b7 100644 if (cciss_pci_init(hba[i], pdev) != 0) goto clean0; -@@ -3926,6 +4259,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, +@@ -3926,6 +4260,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->ctlr = i; hba[i]->pdev = pdev; @@ -343182,7 +346416,7 @@ index a52cc7f..4d879b7 100644 if (cciss_create_hba_sysfs_entry(hba[i])) goto clean0; -@@ -4001,8 +4336,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, +@@ -4001,8 +4337,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, hba[i]->num_luns = 0; hba[i]->highest_lun = -1; for (j = 0; j < CISS_MAX_LUN; j++) { @@ -343192,7 +346426,7 @@ index a52cc7f..4d879b7 100644 hba[i]->gendisk[j] = NULL; } -@@ -4029,23 +4363,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, +@@ -4029,23 +4364,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, printk(KERN_WARNING "cciss: unable to determine firmware" " version of controller\n"); } @@ -343218,7 +346452,7 @@ index a52cc7f..4d879b7 100644 kfree(hba[i]->cmd_pool_bits); if (hba[i]->cmd_pool) pci_free_consistent(hba[i]->pdev, -@@ -4063,12 +4391,7 @@ clean1: +@@ -4063,12 +4392,7 @@ clean1: cciss_destroy_hba_sysfs_entry(hba[i]); clean0: hba[i]->busy_initializing = 0; @@ -343232,7 +346466,7 @@ index a52cc7f..4d879b7 100644 /* * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo -@@ -4125,8 +4448,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) +@@ -4125,8 +4449,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) return; } @@ -343243,7 +346477,7 @@ index a52cc7f..4d879b7 100644 remove_proc_entry(hba[i]->devname, proc_cciss); unregister_blkdev(hba[i]->major, hba[i]->devname); -@@ -4136,8 +4460,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) +@@ -4136,8 +4461,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) if (disk) { struct request_queue *q = disk->queue; @@ -343255,7 +346489,7 @@ index a52cc7f..4d879b7 100644 if (q) blk_cleanup_queue(q); } -@@ -4170,6 +4496,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) +@@ -4170,6 +4497,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); cciss_destroy_hba_sysfs_entry(hba[i]); @@ -343263,7 +346497,7 @@ index a52cc7f..4d879b7 100644 free_hba(i); } -@@ -4202,15 +4529,25 @@ static int __init cciss_init(void) +@@ -4202,15 +4530,25 @@ static int __init cciss_init(void) if (err) return err; @@ -343292,7 +346526,7 @@ index a52cc7f..4d879b7 100644 return err; } -@@ -4227,6 +4564,7 @@ static void __exit cciss_cleanup(void) +@@ -4227,6 +4565,7 @@ static void __exit cciss_cleanup(void) cciss_remove_one(hba[i]->pdev); } } @@ -367389,6 +370623,43 @@ index 894b2cb..40aec0f 100644 __skb_unlink(skb, &bcsp->unack); kfree_skb(skb); +diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c +index 71d1b9b..614da5b 100644 +--- a/drivers/cdrom/cdrom.c ++++ b/drivers/cdrom/cdrom.c +@@ -3412,7 +3412,7 @@ static int cdrom_print_info(const char *header, int val, char *info, + return 0; + } + +-static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, ++static int cdrom_sysctl_info(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int pos; +@@ -3489,7 +3489,7 @@ static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, + goto done; + doit: + mutex_unlock(&cdrom_mutex); +- return proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ return proc_dostring(ctl, write, buffer, lenp, ppos); + done: + printk(KERN_INFO "cdrom: info buffer too small\n"); + goto doit; +@@ -3525,12 +3525,12 @@ static void cdrom_update_settings(void) + mutex_unlock(&cdrom_mutex); + } + +-static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, ++static int cdrom_sysctl_handler(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int ret; + +- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) { + diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index b5621f2..a762283 100644 --- a/drivers/cdrom/gdrom.c @@ -367416,10 +370687,25 @@ index 0fff646..57ca69e 100644 .open = viocd_blk_open, .release = viocd_blk_release, diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig -index 6a06913..b8368e2 100644 +index 6a06913..a2a0e67 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig -@@ -1108,6 +1108,18 @@ config DEVPORT +@@ -1087,6 +1087,14 @@ config MMTIMER + The mmtimer device allows direct userspace access to the + Altix system timer. + ++config UV_MMTIMER ++ tristate "UV_MMTIMER Memory mapped RTC for SGI UV" ++ depends on X86_UV ++ default m ++ help ++ The uv_mmtimer device allows direct userspace access to the ++ UV system timer. ++ + source "drivers/char/tpm/Kconfig" + + config TELCLOCK +@@ -1108,6 +1116,18 @@ config DEVPORT depends on ISA || PCI default y @@ -367439,10 +370725,18 @@ index 6a06913..b8368e2 100644 endmenu diff --git a/drivers/char/Makefile b/drivers/char/Makefile -index 66f779a..3547020 100644 +index 66f779a..56a1d98 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile -@@ -97,6 +97,7 @@ obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o +@@ -58,6 +58,7 @@ obj-$(CONFIG_RAW_DRIVER) += raw.o + obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o + obj-$(CONFIG_MSPEC) += mspec.o + obj-$(CONFIG_MMTIMER) += mmtimer.o ++obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o + obj-$(CONFIG_VIOTAPE) += viotape.o + obj-$(CONFIG_HVCS) += hvcs.o + obj-$(CONFIG_IBM_BSR) += bsr.o +@@ -97,6 +98,7 @@ obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o obj-$(CONFIG_GPIO_TB0219) += tb0219.o obj-$(CONFIG_TELCLOCK) += tlclk.o @@ -367913,7 +371207,7 @@ index 60cc35b..e763d33 100644 .agp_enable = agp_generic_enable, .cache_flush = global_cache_flush, diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c -index c585577..1540e69 100644 +index c585577..4068467 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -10,6 +10,16 @@ @@ -367933,7 +371227,24 @@ index c585577..1540e69 100644 #define PCI_DEVICE_ID_INTEL_E7221_HB 0x2588 #define PCI_DEVICE_ID_INTEL_E7221_IG 0x258a #define PCI_DEVICE_ID_INTEL_82946GZ_HB 0x2970 -@@ -172,6 +182,123 @@ static struct _intel_private { +@@ -36,6 +46,8 @@ + #define PCI_DEVICE_ID_INTEL_Q35_IG 0x29B2 + #define PCI_DEVICE_ID_INTEL_Q33_HB 0x29D0 + #define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 ++#define PCI_DEVICE_ID_INTEL_B43_HB 0x2E40 ++#define PCI_DEVICE_ID_INTEL_B43_IG 0x2E42 + #define PCI_DEVICE_ID_INTEL_GM45_HB 0x2A40 + #define PCI_DEVICE_ID_INTEL_GM45_IG 0x2A42 + #define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00 +@@ -81,6 +93,7 @@ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ ++ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) +@@ -172,6 +185,123 @@ static struct _intel_private { int resource_valid; } intel_private; @@ -368057,7 +371368,7 @@ index c585577..1540e69 100644 static int intel_i810_fetch_size(void) { u32 smram_miscc; -@@ -345,8 +472,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, +@@ -345,8 +475,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, global_cache_flush(); for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { writel(agp_bridge->driver->mask_memory(agp_bridge, @@ -368067,7 +371378,7 @@ index c585577..1540e69 100644 intel_private.registers+I810_PTE_BASE+(j*4)); } readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); -@@ -463,9 +589,8 @@ static void intel_i810_free_by_type(struct agp_memory *curr) +@@ -463,9 +592,8 @@ static void intel_i810_free_by_type(struct agp_memory *curr) } static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, @@ -368078,7 +371389,54 @@ index c585577..1540e69 100644 /* Type checking must be done elsewhere */ return addr | bridge->driver->masks[type].mask; } -@@ -853,7 +978,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, +@@ -679,23 +807,39 @@ static void intel_i830_setup_flush(void) + if (!intel_private.i8xx_page) + return; + +- /* make page uncached */ +- map_page_into_agp(intel_private.i8xx_page); +- + intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); + if (!intel_private.i8xx_flush_page) + intel_i830_fini_flush(); + } + ++static void ++do_wbinvd(void *null) ++{ ++ wbinvd(); ++} ++ ++/* The chipset_flush interface needs to get data that has already been ++ * flushed out of the CPU all the way out to main memory, because the GPU ++ * doesn't snoop those buffers. ++ * ++ * The 8xx series doesn't have the same lovely interface for flushing the ++ * chipset write buffers that the later chips do. According to the 865 ++ * specs, it's 64 octwords, or 1KB. So, to get those previous things in ++ * that buffer out, we just fill 1KB and clflush it out, on the assumption ++ * that it'll push whatever was in there out. It appears to work. ++ */ + static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) + { + unsigned int *pg = intel_private.i8xx_flush_page; +- int i; + +- for (i = 0; i < 256; i += 2) +- *(pg + i) = i; ++ memset(pg, 0, 1024); + +- wmb(); ++ if (cpu_has_clflush) { ++ clflush_cache_range(pg, 1024); ++ } else { ++ if (on_each_cpu(do_wbinvd, NULL, 1) != 0) ++ printk(KERN_ERR "Timed out waiting for cache flush.\n"); ++ } + } + + /* The intel i830 automatically initializes the agp aperture during POST. +@@ -853,7 +997,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { writel(agp_bridge->driver->mask_memory(agp_bridge, @@ -368087,7 +371445,7 @@ index c585577..1540e69 100644 intel_private.registers+I810_PTE_BASE+(j*4)); } readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); -@@ -1017,6 +1142,12 @@ static int intel_i915_configure(void) +@@ -1017,6 +1161,12 @@ static int intel_i915_configure(void) intel_i9xx_setup_flush(); @@ -368100,7 +371458,7 @@ index c585577..1540e69 100644 return 0; } -@@ -1041,7 +1172,7 @@ static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) +@@ -1041,7 +1191,7 @@ static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, int type) { @@ -368109,7 +371467,7 @@ index c585577..1540e69 100644 void *temp; int ret = -EINVAL; int mask_type; -@@ -1065,7 +1196,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, +@@ -1065,7 +1215,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, if ((pg_start + mem->page_count) > num_entries) goto out_err; @@ -368118,7 +371476,7 @@ index c585577..1540e69 100644 * depend on the caller to make the correct offset decisions. */ -@@ -1081,12 +1212,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, +@@ -1081,12 +1231,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, if (!mem->is_flushed) global_cache_flush(); @@ -368132,7 +371490,7 @@ index c585577..1540e69 100644 agp_bridge->driver->tlb_flush(mem); out: -@@ -1198,9 +1324,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) +@@ -1198,9 +1343,8 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) * this conditional. */ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, @@ -368143,7 +371501,15 @@ index c585577..1540e69 100644 /* Shift high bits down */ addr |= (addr >> 28) & 0xf0; -@@ -2006,6 +2131,12 @@ static const struct agp_bridge_driver intel_915_driver = { +@@ -1216,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) + case PCI_DEVICE_ID_INTEL_Q45_HB: + case PCI_DEVICE_ID_INTEL_G45_HB: + case PCI_DEVICE_ID_INTEL_G41_HB: ++ case PCI_DEVICE_ID_INTEL_B43_HB: + case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: + case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: + case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: +@@ -2006,6 +2151,12 @@ static const struct agp_bridge_driver intel_915_driver = { .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, @@ -368156,7 +371522,7 @@ index c585577..1540e69 100644 }; static const struct agp_bridge_driver intel_i965_driver = { -@@ -2034,6 +2165,12 @@ static const struct agp_bridge_driver intel_i965_driver = { +@@ -2034,6 +2185,12 @@ static const struct agp_bridge_driver intel_i965_driver = { .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, @@ -368169,7 +371535,7 @@ index c585577..1540e69 100644 }; static const struct agp_bridge_driver intel_7505_driver = { -@@ -2088,6 +2225,12 @@ static const struct agp_bridge_driver intel_g33_driver = { +@@ -2088,6 +2245,12 @@ static const struct agp_bridge_driver intel_g33_driver = { .agp_destroy_pages = agp_generic_destroy_pages, .agp_type_to_mask_type = intel_i830_type_to_mask_type, .chipset_flush = intel_i915_chipset_flush, @@ -368182,7 +371548,16 @@ index c585577..1540e69 100644 }; static int find_gmch(u16 device) -@@ -2313,15 +2456,6 @@ static int agp_intel_resume(struct pci_dev *pdev) +@@ -2192,6 +2355,8 @@ static const struct intel_driver_description { + "Q45/Q43", NULL, &intel_i965_driver }, + { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0, + "G45/G43", NULL, &intel_i965_driver }, ++ { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, 0, ++ "B43", NULL, &intel_i965_driver }, + { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, + "G41", NULL, &intel_i965_driver }, + { PCI_DEVICE_ID_INTEL_IGDNG_D_HB, PCI_DEVICE_ID_INTEL_IGDNG_D_IG, 0, +@@ -2313,15 +2478,6 @@ static int agp_intel_resume(struct pci_dev *pdev) struct agp_bridge_data *bridge = pci_get_drvdata(pdev); int ret_val; @@ -368198,6 +371573,14 @@ index c585577..1540e69 100644 if (bridge->driver == &intel_generic_driver) intel_configure(); else if (bridge->driver == &intel_850_driver) +@@ -2401,6 +2557,7 @@ static struct pci_device_id agp_intel_pci_table[] = { + ID(PCI_DEVICE_ID_INTEL_Q45_HB), + ID(PCI_DEVICE_ID_INTEL_G45_HB), + ID(PCI_DEVICE_ID_INTEL_G41_HB), ++ ID(PCI_DEVICE_ID_INTEL_B43_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), + ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 263d71d..7e36d2b 100644 --- a/drivers/char/agp/nvidia-agp.c @@ -368500,6 +371883,251 @@ index f192c3b..703959e 100644 MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); MODULE_LICENSE("GPL"); +diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c +index 0a01329..e3dd24b 100644 +--- a/drivers/char/bfin-otp.c ++++ b/drivers/char/bfin-otp.c +@@ -1,8 +1,7 @@ + /* + * Blackfin On-Chip OTP Memory Interface +- * Supports BF52x/BF54x + * +- * Copyright 2007-2008 Analog Devices Inc. ++ * Copyright 2007-2009 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * +@@ -17,8 +16,10 @@ + #include + #include + #include ++#include + + #include ++#include + #include + + #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args) +@@ -30,39 +31,6 @@ + + static DEFINE_MUTEX(bfin_otp_lock); + +-/* OTP Boot ROM functions */ +-#define _BOOTROM_OTP_COMMAND 0xEF000018 +-#define _BOOTROM_OTP_READ 0xEF00001A +-#define _BOOTROM_OTP_WRITE 0xEF00001C +- +-static u32 (* const otp_command)(u32 command, u32 value) = (void *)_BOOTROM_OTP_COMMAND; +-static u32 (* const otp_read)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_READ; +-static u32 (* const otp_write)(u32 page, u32 flags, u64 *page_content) = (void *)_BOOTROM_OTP_WRITE; +- +-/* otp_command(): defines for "command" */ +-#define OTP_INIT 0x00000001 +-#define OTP_CLOSE 0x00000002 +- +-/* otp_{read,write}(): defines for "flags" */ +-#define OTP_LOWER_HALF 0x00000000 /* select upper/lower 64-bit half (bit 0) */ +-#define OTP_UPPER_HALF 0x00000001 +-#define OTP_NO_ECC 0x00000010 /* do not use ECC */ +-#define OTP_LOCK 0x00000020 /* sets page protection bit for page */ +-#define OTP_ACCESS_READ 0x00001000 +-#define OTP_ACCESS_READWRITE 0x00002000 +- +-/* Return values for all functions */ +-#define OTP_SUCCESS 0x00000000 +-#define OTP_MASTER_ERROR 0x001 +-#define OTP_WRITE_ERROR 0x003 +-#define OTP_READ_ERROR 0x005 +-#define OTP_ACC_VIO_ERROR 0x009 +-#define OTP_DATA_MULT_ERROR 0x011 +-#define OTP_ECC_MULT_ERROR 0x021 +-#define OTP_PREV_WR_ERROR 0x041 +-#define OTP_DATA_SB_WARN 0x100 +-#define OTP_ECC_SB_WARN 0x200 +- + /** + * bfin_otp_read - Read OTP pages + * +@@ -86,9 +54,11 @@ static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, + page = *pos / (sizeof(u64) * 2); + while (bytes_done < count) { + flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF); +- stamp("processing page %i (%s)", page, (flags == OTP_UPPER_HALF ? "upper" : "lower")); +- ret = otp_read(page, flags, &content); ++ stamp("processing page %i (0x%x:%s)", page, flags, ++ (flags & OTP_UPPER_HALF ? "upper" : "lower")); ++ ret = bfrom_OtpRead(page, flags, &content); + if (ret & OTP_MASTER_ERROR) { ++ stamp("error from otp: 0x%x", ret); + bytes_done = -EIO; + break; + } +@@ -96,7 +66,7 @@ static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, + bytes_done = -EFAULT; + break; + } +- if (flags == OTP_UPPER_HALF) ++ if (flags & OTP_UPPER_HALF) + ++page; + bytes_done += sizeof(content); + *pos += sizeof(content); +@@ -108,14 +78,53 @@ static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, + } + + #ifdef CONFIG_BFIN_OTP_WRITE_ENABLE ++static bool allow_writes; ++ ++/** ++ * bfin_otp_init_timing - setup OTP timing parameters ++ * ++ * Required before doing any write operation. Algorithms from HRM. ++ */ ++static u32 bfin_otp_init_timing(void) ++{ ++ u32 tp1, tp2, tp3, timing; ++ ++ tp1 = get_sclk() / 1000000; ++ tp2 = (2 * get_sclk() / 10000000) << 8; ++ tp3 = (0x1401) << 15; ++ timing = tp1 | tp2 | tp3; ++ if (bfrom_OtpCommand(OTP_INIT, timing)) ++ return 0; ++ ++ return timing; ++} ++ ++/** ++ * bfin_otp_deinit_timing - set timings to only allow reads ++ * ++ * Should be called after all writes are done. ++ */ ++static void bfin_otp_deinit_timing(u32 timing) ++{ ++ /* mask bits [31:15] so that any attempts to write fail */ ++ bfrom_OtpCommand(OTP_CLOSE, 0); ++ bfrom_OtpCommand(OTP_INIT, timing & ~(-1 << 15)); ++ bfrom_OtpCommand(OTP_CLOSE, 0); ++} ++ + /** +- * bfin_otp_write - Write OTP pages ++ * bfin_otp_write - write OTP pages + * + * All writes must be in half page chunks (half page == 64 bits). + */ + static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos) + { +- stampit(); ++ ssize_t bytes_done; ++ u32 timing, page, base_flags, flags, ret; ++ u64 content; ++ ++ if (!allow_writes) ++ return -EACCES; + + if (count % sizeof(u64)) + return -EMSGSIZE; +@@ -123,20 +132,96 @@ static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t + if (mutex_lock_interruptible(&bfin_otp_lock)) + return -ERESTARTSYS; + +- /* need otp_init() documentation before this can be implemented */ ++ stampit(); ++ ++ timing = bfin_otp_init_timing(); ++ if (timing == 0) { ++ mutex_unlock(&bfin_otp_lock); ++ return -EIO; ++ } ++ ++ base_flags = OTP_CHECK_FOR_PREV_WRITE; ++ ++ bytes_done = 0; ++ page = *pos / (sizeof(u64) * 2); ++ while (bytes_done < count) { ++ flags = base_flags | (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF); ++ stamp("processing page %i (0x%x:%s) from %p", page, flags, ++ (flags & OTP_UPPER_HALF ? "upper" : "lower"), buff + bytes_done); ++ if (copy_from_user(&content, buff + bytes_done, sizeof(content))) { ++ bytes_done = -EFAULT; ++ break; ++ } ++ ret = bfrom_OtpWrite(page, flags, &content); ++ if (ret & OTP_MASTER_ERROR) { ++ stamp("error from otp: 0x%x", ret); ++ bytes_done = -EIO; ++ break; ++ } ++ if (flags & OTP_UPPER_HALF) ++ ++page; ++ bytes_done += sizeof(content); ++ *pos += sizeof(content); ++ } ++ ++ bfin_otp_deinit_timing(timing); + + mutex_unlock(&bfin_otp_lock); + ++ return bytes_done; ++} ++ ++static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg) ++{ ++ stampit(); ++ ++ switch (cmd) { ++ case OTPLOCK: { ++ u32 timing; ++ int ret = -EIO; ++ ++ if (!allow_writes) ++ return -EACCES; ++ ++ if (mutex_lock_interruptible(&bfin_otp_lock)) ++ return -ERESTARTSYS; ++ ++ timing = bfin_otp_init_timing(); ++ if (timing) { ++ u32 otp_result = bfrom_OtpWrite(arg, OTP_LOCK, NULL); ++ stamp("locking page %lu resulted in 0x%x", arg, otp_result); ++ if (!(otp_result & OTP_MASTER_ERROR)) ++ ret = 0; ++ ++ bfin_otp_deinit_timing(timing); ++ } ++ ++ mutex_unlock(&bfin_otp_lock); ++ ++ return ret; ++ } ++ ++ case MEMLOCK: ++ allow_writes = false; ++ return 0; ++ ++ case MEMUNLOCK: ++ allow_writes = true; ++ return 0; ++ } ++ + return -EINVAL; + } + #else + # define bfin_otp_write NULL ++# define bfin_otp_ioctl NULL + #endif + + static struct file_operations bfin_otp_fops = { +- .owner = THIS_MODULE, +- .read = bfin_otp_read, +- .write = bfin_otp_write, ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = bfin_otp_ioctl, ++ .read = bfin_otp_read, ++ .write = bfin_otp_write, + }; + + static struct miscdevice bfin_otp_misc_device = { diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 2dafc2d..df5038b 100644 --- a/drivers/char/cyclades.c @@ -372091,8 +375719,56 @@ index a00869c..ef31738 100644 } void __exit nvram_cleanup(void) +diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c +index 4a9f349..70a770a 100644 +--- a/drivers/char/hpet.c ++++ b/drivers/char/hpet.c +@@ -166,9 +166,8 @@ static irqreturn_t hpet_interrupt(int irq, void *data) + unsigned long m, t; + + t = devp->hd_ireqfreq; +- m = read_counter(&devp->hd_hpet->hpet_mc); +- write_counter(t + m + devp->hd_hpets->hp_delta, +- &devp->hd_timer->hpet_compare); ++ m = read_counter(&devp->hd_timer->hpet_compare); ++ write_counter(t + m, &devp->hd_timer->hpet_compare); + } + + if (devp->hd_flags & HPET_SHARED_IRQ) +@@ -504,21 +503,25 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) + g = v | Tn_32MODE_CNF_MASK | Tn_INT_ENB_CNF_MASK; + + if (devp->hd_flags & HPET_PERIODIC) { +- write_counter(t, &timer->hpet_compare); + g |= Tn_TYPE_CNF_MASK; +- v |= Tn_TYPE_CNF_MASK; +- writeq(v, &timer->hpet_config); +- v |= Tn_VAL_SET_CNF_MASK; ++ v |= Tn_TYPE_CNF_MASK | Tn_VAL_SET_CNF_MASK; + writeq(v, &timer->hpet_config); + local_irq_save(flags); + +- /* NOTE: what we modify here is a hidden accumulator ++ /* ++ * NOTE: First we modify the hidden accumulator + * register supported by periodic-capable comparators. + * We never want to modify the (single) counter; that +- * would affect all the comparators. ++ * would affect all the comparators. The value written ++ * is the counter value when the first interrupt is due. + */ + m = read_counter(&hpet->hpet_mc); + write_counter(t + m + hpetp->hp_delta, &timer->hpet_compare); ++ /* ++ * Then we modify the comparator, indicating the period ++ * for subsequent interrupt. ++ */ ++ write_counter(t, &timer->hpet_compare); + } else { + local_irq_save(flags); + m = read_counter(&hpet->hpet_mc); diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c -index d97779e..25ce15b 100644 +index d97779e..a632f25 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -516,8 +516,6 @@ static void hvc_set_winsz(struct work_struct *work) @@ -372104,11 +375780,76 @@ index d97779e..25ce15b 100644 spin_lock_irqsave(&hp->lock, hvc_flags); if (!hp->tty) { +@@ -680,7 +678,7 @@ int hvc_poll(struct hvc_struct *hp) + EXPORT_SYMBOL_GPL(hvc_poll); + + /** +- * hvc_resize() - Update terminal window size information. ++ * __hvc_resize() - Update terminal window size information. + * @hp: HVC console pointer + * @ws: Terminal window size structure + * +@@ -689,12 +687,12 @@ EXPORT_SYMBOL_GPL(hvc_poll); + * + * Locking: Locking free; the function MUST be called holding hp->lock + */ +-void hvc_resize(struct hvc_struct *hp, struct winsize ws) ++void __hvc_resize(struct hvc_struct *hp, struct winsize ws) + { + hp->ws = ws; + schedule_work(&hp->tty_resize); + } +-EXPORT_SYMBOL_GPL(hvc_resize); ++EXPORT_SYMBOL_GPL(__hvc_resize); + + /* + * This kthread is either polling or interrupt driven. This is determined by +diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h +index 3c85d78..10950ca 100644 +--- a/drivers/char/hvc_console.h ++++ b/drivers/char/hvc_console.h +@@ -28,6 +28,7 @@ + #define HVC_CONSOLE_H + #include + #include ++#include + + /* + * This is the max number of console adapters that can/will be found as +@@ -88,7 +89,16 @@ int hvc_poll(struct hvc_struct *hp); + void hvc_kick(void); + + /* Resize hvc tty terminal window */ +-extern void hvc_resize(struct hvc_struct *hp, struct winsize ws); ++extern void __hvc_resize(struct hvc_struct *hp, struct winsize ws); ++ ++static inline void hvc_resize(struct hvc_struct *hp, struct winsize ws) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hp->lock, flags); ++ __hvc_resize(hp, ws); ++ spin_unlock_irqrestore(&hp->lock, flags); ++} + + /* default notifier for irq based notification */ + extern int notifier_add_irq(struct hvc_struct *hp, int data); diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c -index 86105ef..0ecac7e 100644 +index 86105ef..b8a5d65 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c -@@ -1006,7 +1006,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console) +@@ -273,7 +273,9 @@ static int hvc_iucv_write(struct hvc_iucv_private *priv, + case MSG_TYPE_WINSIZE: + if (rb->mbuf->datalen != sizeof(struct winsize)) + break; +- hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data)); ++ /* The caller must ensure that the hvc is locked, which ++ * is the case when called from hvc_iucv_get_chars() */ ++ __hvc_resize(priv->hvc, *((struct winsize *) rb->mbuf->data)); + break; + + case MSG_TYPE_ERROR: /* ignored ... */ +@@ -1006,7 +1008,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console) priv->dev->release = (void (*)(struct device *)) kfree; rc = device_register(priv->dev); if (rc) { @@ -372562,9 +376303,18 @@ index acd8e9e..87c67b4 100644 static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) diff --git a/drivers/char/mem.c b/drivers/char/mem.c -index afa8813..0aede1d 100644 +index afa8813..6c8b65d 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c +@@ -690,7 +690,7 @@ static ssize_t read_zero(struct file * file, char __user * buf, + + if (chunk > PAGE_SIZE) + chunk = PAGE_SIZE; /* Just for latency reasons */ +- unwritten = clear_user(buf, chunk); ++ unwritten = __clear_user(buf, chunk); + written += chunk - unwritten; + if (unwritten) + break; @@ -822,6 +822,7 @@ static const struct file_operations zero_fops = { * - permits private mappings, "copies" are taken of the source of zeros */ @@ -372745,6 +376495,60 @@ index 62c99fa..07fa612 100644 return 0; fail_printk: +diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c +index 94ad2c3..a4ec50c 100644 +--- a/drivers/char/mwave/mwavedd.c ++++ b/drivers/char/mwave/mwavedd.c +@@ -281,12 +281,6 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, + case IOCTL_MW_REGISTER_IPC: { + unsigned int ipcnum = (unsigned int) ioarg; + +- PRINTK_3(TRACE_MWAVE, +- "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" +- " ipcnum %x entry usIntCount %x\n", +- ipcnum, +- pDrvData->IPCs[ipcnum].usIntCount); +- + if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { + PRINTK_ERROR(KERN_ERR_MWAVE + "mwavedd::mwave_ioctl:" +@@ -295,6 +289,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, + ipcnum); + return -EINVAL; + } ++ PRINTK_3(TRACE_MWAVE, ++ "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" ++ " ipcnum %x entry usIntCount %x\n", ++ ipcnum, ++ pDrvData->IPCs[ipcnum].usIntCount); ++ + lock_kernel(); + pDrvData->IPCs[ipcnum].bIsHere = FALSE; + pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; +@@ -310,11 +310,6 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, + case IOCTL_MW_GET_IPC: { + unsigned int ipcnum = (unsigned int) ioarg; + +- PRINTK_3(TRACE_MWAVE, +- "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC" +- " ipcnum %x, usIntCount %x\n", +- ipcnum, +- pDrvData->IPCs[ipcnum].usIntCount); + if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { + PRINTK_ERROR(KERN_ERR_MWAVE + "mwavedd::mwave_ioctl:" +@@ -322,6 +317,11 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, + " Invalid ipcnum %x\n", ipcnum); + return -EINVAL; + } ++ PRINTK_3(TRACE_MWAVE, ++ "mwavedd::mwave_ioctl IOCTL_MW_GET_IPC" ++ " ipcnum %x, usIntCount %x\n", ++ ipcnum, ++ pDrvData->IPCs[ipcnum].usIntCount); + + lock_kernel(); + if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index dbf8d52..5e28d39 100644 --- a/drivers/char/mxser.c @@ -373102,7 +376906,7 @@ index b33d668..53761ce 100644 return c; } diff --git a/drivers/char/random.c b/drivers/char/random.c -index 8c74448..d8a9255 100644 +index 8c74448..04b505e 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -240,6 +240,7 @@ @@ -373153,6 +376957,24 @@ index 8c74448..d8a9255 100644 } static int rand_initialize(void) +@@ -1217,7 +1231,7 @@ static char sysctl_bootid[16]; + * as an ASCII string in the standard UUID format. If accesses via the + * sysctl system call, it is returned as 16 bytes of binary data. + */ +-static int proc_do_uuid(ctl_table *table, int write, struct file *filp, ++static int proc_do_uuid(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + ctl_table fake_table; +@@ -1240,7 +1254,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp, + fake_table.data = buf; + fake_table.maxlen = sizeof(buf); + +- return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos); ++ return proc_dostring(&fake_table, write, buffer, lenp, ppos); + } + + static int uuid_strategy(ctl_table *table, diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 05f9d18..64acd05 100644 --- a/drivers/char/raw.c @@ -373184,6 +377006,19 @@ index 05f9d18..64acd05 100644 device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); return 0; +diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c +index eecee0f..7433955 100644 +--- a/drivers/char/rio/rioctrl.c ++++ b/drivers/char/rio/rioctrl.c +@@ -873,7 +873,7 @@ int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su + /* + ** It is important that the product code is an unsigned object! + */ +- if (DownLoad.ProductCode > MAX_PRODUCT) { ++ if (DownLoad.ProductCode >= MAX_PRODUCT) { + rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); + p->RIOError.Error = NO_SUCH_PRODUCT; + return -ENXIO; diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 171711a..3cfa22d 100644 --- a/drivers/char/riscom8.c @@ -373742,9 +377577,18 @@ index 5d7a02f..44203ff 100644 static struct sysrq_key_op sysrq_showregs_op = { .handler = sysrq_handle_showregs, diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c -index b0603b2..45d5800 100644 +index b0603b2..aeafac5 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c +@@ -31,7 +31,7 @@ + + enum tpm_const { + TPM_MINOR = 224, /* officially assigned */ +- TPM_BUFSIZE = 2048, ++ TPM_BUFSIZE = 4096, + TPM_NUM_DEVICES = 256, + }; + @@ -696,7 +696,7 @@ int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) cmd.header.in = pcrread_header; @@ -374704,6 +378548,228 @@ index 0000000..29de6ab + +module_init(ummunotify_init); +module_exit(ummunotify_cleanup); +diff --git a/drivers/char/uv_mmtimer.c b/drivers/char/uv_mmtimer.c +new file mode 100644 +index 0000000..867b67b +--- /dev/null ++++ b/drivers/char/uv_mmtimer.c +@@ -0,0 +1,216 @@ ++/* ++ * Timer device implementation for SGI UV platform. ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (c) 2009 Silicon Graphics, Inc. All rights reserved. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Dimitri Sivanich "); ++MODULE_DESCRIPTION("SGI UV Memory Mapped RTC Timer"); ++MODULE_LICENSE("GPL"); ++ ++/* name of the device, usually in /dev */ ++#define UV_MMTIMER_NAME "mmtimer" ++#define UV_MMTIMER_DESC "SGI UV Memory Mapped RTC Timer" ++#define UV_MMTIMER_VERSION "1.0" ++ ++static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg); ++static int uv_mmtimer_mmap(struct file *file, struct vm_area_struct *vma); ++ ++/* ++ * Period in femtoseconds (10^-15 s) ++ */ ++static unsigned long uv_mmtimer_femtoperiod; ++ ++static const struct file_operations uv_mmtimer_fops = { ++ .owner = THIS_MODULE, ++ .mmap = uv_mmtimer_mmap, ++ .unlocked_ioctl = uv_mmtimer_ioctl, ++}; ++ ++/** ++ * uv_mmtimer_ioctl - ioctl interface for /dev/uv_mmtimer ++ * @file: file structure for the device ++ * @cmd: command to execute ++ * @arg: optional argument to command ++ * ++ * Executes the command specified by @cmd. Returns 0 for success, < 0 for ++ * failure. ++ * ++ * Valid commands: ++ * ++ * %MMTIMER_GETOFFSET - Should return the offset (relative to the start ++ * of the page where the registers are mapped) for the counter in question. ++ * ++ * %MMTIMER_GETRES - Returns the resolution of the clock in femto (10^-15) ++ * seconds ++ * ++ * %MMTIMER_GETFREQ - Copies the frequency of the clock in Hz to the address ++ * specified by @arg ++ * ++ * %MMTIMER_GETBITS - Returns the number of bits in the clock's counter ++ * ++ * %MMTIMER_MMAPAVAIL - Returns 1 if registers can be mmap'd into userspace ++ * ++ * %MMTIMER_GETCOUNTER - Gets the current value in the counter and places it ++ * in the address specified by @arg. ++ */ ++static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ int ret = 0; ++ ++ switch (cmd) { ++ case MMTIMER_GETOFFSET: /* offset of the counter */ ++ /* ++ * UV RTC register is on its own page ++ */ ++ if (PAGE_SIZE <= (1 << 16)) ++ ret = ((UV_LOCAL_MMR_BASE | UVH_RTC) & (PAGE_SIZE-1)) ++ / 8; ++ else ++ ret = -ENOSYS; ++ break; ++ ++ case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */ ++ if (copy_to_user((unsigned long __user *)arg, ++ &uv_mmtimer_femtoperiod, sizeof(unsigned long))) ++ ret = -EFAULT; ++ break; ++ ++ case MMTIMER_GETFREQ: /* frequency in Hz */ ++ if (copy_to_user((unsigned long __user *)arg, ++ &sn_rtc_cycles_per_second, ++ sizeof(unsigned long))) ++ ret = -EFAULT; ++ break; ++ ++ case MMTIMER_GETBITS: /* number of bits in the clock */ ++ ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK); ++ break; ++ ++ case MMTIMER_MMAPAVAIL: /* can we mmap the clock into userspace? */ ++ ret = (PAGE_SIZE <= (1 << 16)) ? 1 : 0; ++ break; ++ ++ case MMTIMER_GETCOUNTER: ++ if (copy_to_user((unsigned long __user *)arg, ++ (unsigned long *)uv_local_mmr_address(UVH_RTC), ++ sizeof(unsigned long))) ++ ret = -EFAULT; ++ break; ++ default: ++ ret = -ENOTTY; ++ break; ++ } ++ return ret; ++} ++ ++/** ++ * uv_mmtimer_mmap - maps the clock's registers into userspace ++ * @file: file structure for the device ++ * @vma: VMA to map the registers into ++ * ++ * Calls remap_pfn_range() to map the clock's registers into ++ * the calling process' address space. ++ */ ++static int uv_mmtimer_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ unsigned long uv_mmtimer_addr; ++ ++ if (vma->vm_end - vma->vm_start != PAGE_SIZE) ++ return -EINVAL; ++ ++ if (vma->vm_flags & VM_WRITE) ++ return -EPERM; ++ ++ if (PAGE_SIZE > (1 << 16)) ++ return -ENOSYS; ++ ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ uv_mmtimer_addr = UV_LOCAL_MMR_BASE | UVH_RTC; ++ uv_mmtimer_addr &= ~(PAGE_SIZE - 1); ++ uv_mmtimer_addr &= 0xfffffffffffffffUL; ++ ++ if (remap_pfn_range(vma, vma->vm_start, uv_mmtimer_addr >> PAGE_SHIFT, ++ PAGE_SIZE, vma->vm_page_prot)) { ++ printk(KERN_ERR "remap_pfn_range failed in uv_mmtimer_mmap\n"); ++ return -EAGAIN; ++ } ++ ++ return 0; ++} ++ ++static struct miscdevice uv_mmtimer_miscdev = { ++ MISC_DYNAMIC_MINOR, ++ UV_MMTIMER_NAME, ++ &uv_mmtimer_fops ++}; ++ ++ ++/** ++ * uv_mmtimer_init - device initialization routine ++ * ++ * Does initial setup for the uv_mmtimer device. ++ */ ++static int __init uv_mmtimer_init(void) ++{ ++ if (!is_uv_system()) { ++ printk(KERN_ERR "%s: Hardware unsupported\n", UV_MMTIMER_NAME); ++ return -1; ++ } ++ ++ /* ++ * Sanity check the cycles/sec variable ++ */ ++ if (sn_rtc_cycles_per_second < 100000) { ++ printk(KERN_ERR "%s: unable to determine clock frequency\n", ++ UV_MMTIMER_NAME); ++ return -1; ++ } ++ ++ uv_mmtimer_femtoperiod = ((unsigned long)1E15 + ++ sn_rtc_cycles_per_second / 2) / ++ sn_rtc_cycles_per_second; ++ ++ if (misc_register(&uv_mmtimer_miscdev)) { ++ printk(KERN_ERR "%s: failed to register device\n", ++ UV_MMTIMER_NAME); ++ return -1; ++ } ++ ++ printk(KERN_INFO "%s: v%s, %ld MHz\n", UV_MMTIMER_DESC, ++ UV_MMTIMER_VERSION, ++ sn_rtc_cycles_per_second/(unsigned long)1E6); ++ ++ return 0; ++} ++ ++module_init(uv_mmtimer_init); diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index c74dacf..0d328b5 100644 --- a/drivers/char/virtio_console.c @@ -389981,7 +394047,7 @@ index c907ff0..365d423 100644 size_t len; }; diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig -index 4339b1a..a3ca18e 100644 +index 4339b1a..02127e5 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -59,7 +59,7 @@ config EDAC_MM_EDAC @@ -389993,8 +394059,37 @@ index 4339b1a..a3ca18e 100644 help Support for error detection and correction on the AMD 64 Families of Memory Controllers (K8, F10h and F11h) +@@ -133,6 +133,13 @@ config EDAC_I3000 + Support for error detection and correction on the Intel + 3000 and 3010 server chipsets. + ++config EDAC_I3200 ++ tristate "Intel 3200" ++ depends on EDAC_MM_EDAC && PCI && X86 && EXPERIMENTAL ++ help ++ Support for error detection and correction on the Intel ++ 3200 and 3210 server chipsets. ++ + config EDAC_X38 + tristate "Intel X38" + depends on EDAC_MM_EDAC && PCI && X86 +@@ -176,11 +183,11 @@ config EDAC_I5100 + San Clemente MCH. + + config EDAC_MPC85XX +- tristate "Freescale MPC85xx" +- depends on EDAC_MM_EDAC && FSL_SOC && MPC85xx ++ tristate "Freescale MPC83xx / MPC85xx" ++ depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || MPC85xx) + help + Support for error detection and correction on the Freescale +- MPC8560, MPC8540, MPC8548 ++ MPC8349, MPC8560, MPC8540, MPC8548 + + config EDAC_MV64X60 + tristate "Marvell MV64x60" diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile -index 98aa4a7..cfa033c 100644 +index 98aa4a7..7a473bb 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -17,6 +17,10 @@ ifdef CONFIG_PCI @@ -390008,7 +394103,12 @@ index 98aa4a7..cfa033c 100644 obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o obj-$(CONFIG_EDAC_I5000) += i5000_edac.o -@@ -32,7 +36,7 @@ obj-$(CONFIG_EDAC_X38) += x38_edac.o +@@ -28,11 +32,12 @@ obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o + obj-$(CONFIG_EDAC_I82875P) += i82875p_edac.o + obj-$(CONFIG_EDAC_I82975X) += i82975x_edac.o + obj-$(CONFIG_EDAC_I3000) += i3000_edac.o ++obj-$(CONFIG_EDAC_I3200) += i3200_edac.o + obj-$(CONFIG_EDAC_X38) += x38_edac.o obj-$(CONFIG_EDAC_I82860) += i82860_edac.o obj-$(CONFIG_EDAC_R82600) += r82600_edac.o @@ -390017,6 +394117,11 @@ index 98aa4a7..cfa033c 100644 amd64_edac_mod-$(CONFIG_EDAC_DEBUG) += amd64_edac_dbg.o amd64_edac_mod-$(CONFIG_EDAC_AMD64_ERROR_INJECTION) += amd64_edac_inj.o +@@ -45,3 +50,4 @@ obj-$(CONFIG_EDAC_CELL) += cell_edac.o + obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o + obj-$(CONFIG_EDAC_AMD8111) += amd8111_edac.o + obj-$(CONFIG_EDAC_AMD8131) += amd8131_edac.o ++ diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index e2a10bc..4e551e6 100644 --- a/drivers/edac/amd64_edac.c @@ -391043,6 +395148,36 @@ index f212ff1..0000000 - "2 3", - "1 2 3" -}; +diff --git a/drivers/edac/cpc925_edac.c b/drivers/edac/cpc925_edac.c +index 8c54196..3d50274 100644 +--- a/drivers/edac/cpc925_edac.c ++++ b/drivers/edac/cpc925_edac.c +@@ -885,14 +885,14 @@ static int __devinit cpc925_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdev->name)) { + cpc925_printk(KERN_ERR, "Unable to request mem region\n"); + res = -EBUSY; + goto err1; + } + +- vbase = devm_ioremap(&pdev->dev, r->start, r->end - r->start + 1); ++ vbase = devm_ioremap(&pdev->dev, r->start, resource_size(r)); + if (!vbase) { + cpc925_printk(KERN_ERR, "Unable to ioremap device\n"); + res = -ENOMEM; +@@ -953,7 +953,7 @@ err3: + cpc925_mc_exit(mci); + edac_mc_free(mci); + err2: +- devm_release_mem_region(&pdev->dev, r->start, r->end-r->start+1); ++ devm_release_mem_region(&pdev->dev, r->start, resource_size(r)); + err1: + devres_release_group(&pdev->dev, cpc925_probe); + out: diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index 871c13b..12f355c 100644 --- a/drivers/edac/edac_core.h @@ -391056,6 +395191,52 @@ index 871c13b..12f355c 100644 * a single memory access or all of the memory sticks * spanned by a chip-select row. A single socket set * has two chip-select rows and if double-sided sticks +diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c +index b02a6a6..d5e13c9 100644 +--- a/drivers/edac/edac_device.c ++++ b/drivers/edac/edac_device.c +@@ -356,7 +356,6 @@ static void complete_edac_device_list_del(struct rcu_head *head) + + edac_dev = container_of(head, struct edac_device_ctl_info, rcu); + INIT_LIST_HEAD(&edac_dev->link); +- complete(&edac_dev->removal_complete); + } + + /* +@@ -369,10 +368,8 @@ static void del_edac_device_from_global_list(struct edac_device_ctl_info + *edac_device) + { + list_del_rcu(&edac_device->link); +- +- init_completion(&edac_device->removal_complete); + call_rcu(&edac_device->rcu, complete_edac_device_list_del); +- wait_for_completion(&edac_device->removal_complete); ++ rcu_barrier(); + } + + /* +diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c +index 335b7eb..b629c41 100644 +--- a/drivers/edac/edac_mc.c ++++ b/drivers/edac/edac_mc.c +@@ -418,16 +418,14 @@ static void complete_mc_list_del(struct rcu_head *head) + + mci = container_of(head, struct mem_ctl_info, rcu); + INIT_LIST_HEAD(&mci->link); +- complete(&mci->complete); + } + + static void del_mc_from_global_list(struct mem_ctl_info *mci) + { + atomic_dec(&edac_handlers); + list_del_rcu(&mci->link); +- init_completion(&mci->complete); + call_rcu(&mci->rcu, complete_mc_list_del); +- wait_for_completion(&mci->complete); ++ rcu_barrier(); + } + + /** diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c new file mode 100644 index 0000000..0c21c37 @@ -391559,6 +395740,773 @@ index 0000000..df23ee0 +void amd_decode_nb_mce(int, struct err_regs *, int); + +#endif /* _EDAC_MCE_AMD_H */ +diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c +index 30b585b..efb5d56 100644 +--- a/drivers/edac/edac_pci.c ++++ b/drivers/edac/edac_pci.c +@@ -174,7 +174,6 @@ static void complete_edac_pci_list_del(struct rcu_head *head) + + pci = container_of(head, struct edac_pci_ctl_info, rcu); + INIT_LIST_HEAD(&pci->link); +- complete(&pci->complete); + } + + /* +@@ -185,9 +184,8 @@ static void complete_edac_pci_list_del(struct rcu_head *head) + static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci) + { + list_del_rcu(&pci->link); +- init_completion(&pci->complete); + call_rcu(&pci->rcu, complete_edac_pci_list_del); +- wait_for_completion(&pci->complete); ++ rcu_barrier(); + } + + #if 0 +diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c +new file mode 100644 +index 0000000..fde4db9 +--- /dev/null ++++ b/drivers/edac/i3200_edac.c +@@ -0,0 +1,527 @@ ++/* ++ * Intel 3200/3210 Memory Controller kernel module ++ * Copyright (C) 2008-2009 Akamai Technologies, Inc. ++ * Portions by Hitoshi Mitake . ++ * ++ * This file may be distributed under the terms of the ++ * GNU General Public License. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "edac_core.h" ++ ++#define I3200_REVISION "1.1" ++ ++#define EDAC_MOD_STR "i3200_edac" ++ ++#define PCI_DEVICE_ID_INTEL_3200_HB 0x29f0 ++ ++#define I3200_RANKS 8 ++#define I3200_RANKS_PER_CHANNEL 4 ++#define I3200_CHANNELS 2 ++ ++/* Intel 3200 register addresses - device 0 function 0 - DRAM Controller */ ++ ++#define I3200_MCHBAR_LOW 0x48 /* MCH Memory Mapped Register BAR */ ++#define I3200_MCHBAR_HIGH 0x4c ++#define I3200_MCHBAR_MASK 0xfffffc000ULL /* bits 35:14 */ ++#define I3200_MMR_WINDOW_SIZE 16384 ++ ++#define I3200_TOM 0xa0 /* Top of Memory (16b) ++ * ++ * 15:10 reserved ++ * 9:0 total populated physical memory ++ */ ++#define I3200_TOM_MASK 0x3ff /* bits 9:0 */ ++#define I3200_TOM_SHIFT 26 /* 64MiB grain */ ++ ++#define I3200_ERRSTS 0xc8 /* Error Status Register (16b) ++ * ++ * 15 reserved ++ * 14 Isochronous TBWRR Run Behind FIFO Full ++ * (ITCV) ++ * 13 Isochronous TBWRR Run Behind FIFO Put ++ * (ITSTV) ++ * 12 reserved ++ * 11 MCH Thermal Sensor Event ++ * for SMI/SCI/SERR (GTSE) ++ * 10 reserved ++ * 9 LOCK to non-DRAM Memory Flag (LCKF) ++ * 8 reserved ++ * 7 DRAM Throttle Flag (DTF) ++ * 6:2 reserved ++ * 1 Multi-bit DRAM ECC Error Flag (DMERR) ++ * 0 Single-bit DRAM ECC Error Flag (DSERR) ++ */ ++#define I3200_ERRSTS_UE 0x0002 ++#define I3200_ERRSTS_CE 0x0001 ++#define I3200_ERRSTS_BITS (I3200_ERRSTS_UE | I3200_ERRSTS_CE) ++ ++ ++/* Intel MMIO register space - device 0 function 0 - MMR space */ ++ ++#define I3200_C0DRB 0x200 /* Channel 0 DRAM Rank Boundary (16b x 4) ++ * ++ * 15:10 reserved ++ * 9:0 Channel 0 DRAM Rank Boundary Address ++ */ ++#define I3200_C1DRB 0x600 /* Channel 1 DRAM Rank Boundary (16b x 4) */ ++#define I3200_DRB_MASK 0x3ff /* bits 9:0 */ ++#define I3200_DRB_SHIFT 26 /* 64MiB grain */ ++ ++#define I3200_C0ECCERRLOG 0x280 /* Channel 0 ECC Error Log (64b) ++ * ++ * 63:48 Error Column Address (ERRCOL) ++ * 47:32 Error Row Address (ERRROW) ++ * 31:29 Error Bank Address (ERRBANK) ++ * 28:27 Error Rank Address (ERRRANK) ++ * 26:24 reserved ++ * 23:16 Error Syndrome (ERRSYND) ++ * 15: 2 reserved ++ * 1 Multiple Bit Error Status (MERRSTS) ++ * 0 Correctable Error Status (CERRSTS) ++ */ ++#define I3200_C1ECCERRLOG 0x680 /* Chan 1 ECC Error Log (64b) */ ++#define I3200_ECCERRLOG_CE 0x1 ++#define I3200_ECCERRLOG_UE 0x2 ++#define I3200_ECCERRLOG_RANK_BITS 0x18000000 ++#define I3200_ECCERRLOG_RANK_SHIFT 27 ++#define I3200_ECCERRLOG_SYNDROME_BITS 0xff0000 ++#define I3200_ECCERRLOG_SYNDROME_SHIFT 16 ++#define I3200_CAPID0 0xe0 /* P.95 of spec for details */ ++ ++struct i3200_priv { ++ void __iomem *window; ++}; ++ ++static int nr_channels; ++ ++static int how_many_channels(struct pci_dev *pdev) ++{ ++ unsigned char capid0_8b; /* 8th byte of CAPID0 */ ++ ++ pci_read_config_byte(pdev, I3200_CAPID0 + 8, &capid0_8b); ++ if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */ ++ debugf0("In single channel mode.\n"); ++ return 1; ++ } else { ++ debugf0("In dual channel mode.\n"); ++ return 2; ++ } ++} ++ ++static unsigned long eccerrlog_syndrome(u64 log) ++{ ++ return (log & I3200_ECCERRLOG_SYNDROME_BITS) >> ++ I3200_ECCERRLOG_SYNDROME_SHIFT; ++} ++ ++static int eccerrlog_row(int channel, u64 log) ++{ ++ u64 rank = ((log & I3200_ECCERRLOG_RANK_BITS) >> ++ I3200_ECCERRLOG_RANK_SHIFT); ++ return rank | (channel * I3200_RANKS_PER_CHANNEL); ++} ++ ++enum i3200_chips { ++ I3200 = 0, ++}; ++ ++struct i3200_dev_info { ++ const char *ctl_name; ++}; ++ ++struct i3200_error_info { ++ u16 errsts; ++ u16 errsts2; ++ u64 eccerrlog[I3200_CHANNELS]; ++}; ++ ++static const struct i3200_dev_info i3200_devs[] = { ++ [I3200] = { ++ .ctl_name = "i3200" ++ }, ++}; ++ ++static struct pci_dev *mci_pdev; ++static int i3200_registered = 1; ++ ++ ++static void i3200_clear_error_info(struct mem_ctl_info *mci) ++{ ++ struct pci_dev *pdev; ++ ++ pdev = to_pci_dev(mci->dev); ++ ++ /* ++ * Clear any error bits. ++ * (Yes, we really clear bits by writing 1 to them.) ++ */ ++ pci_write_bits16(pdev, I3200_ERRSTS, I3200_ERRSTS_BITS, ++ I3200_ERRSTS_BITS); ++} ++ ++static void i3200_get_and_clear_error_info(struct mem_ctl_info *mci, ++ struct i3200_error_info *info) ++{ ++ struct pci_dev *pdev; ++ struct i3200_priv *priv = mci->pvt_info; ++ void __iomem *window = priv->window; ++ ++ pdev = to_pci_dev(mci->dev); ++ ++ /* ++ * This is a mess because there is no atomic way to read all the ++ * registers at once and the registers can transition from CE being ++ * overwritten by UE. ++ */ ++ pci_read_config_word(pdev, I3200_ERRSTS, &info->errsts); ++ if (!(info->errsts & I3200_ERRSTS_BITS)) ++ return; ++ ++ info->eccerrlog[0] = readq(window + I3200_C0ECCERRLOG); ++ if (nr_channels == 2) ++ info->eccerrlog[1] = readq(window + I3200_C1ECCERRLOG); ++ ++ pci_read_config_word(pdev, I3200_ERRSTS, &info->errsts2); ++ ++ /* ++ * If the error is the same for both reads then the first set ++ * of reads is valid. If there is a change then there is a CE ++ * with no info and the second set of reads is valid and ++ * should be UE info. ++ */ ++ if ((info->errsts ^ info->errsts2) & I3200_ERRSTS_BITS) { ++ info->eccerrlog[0] = readq(window + I3200_C0ECCERRLOG); ++ if (nr_channels == 2) ++ info->eccerrlog[1] = readq(window + I3200_C1ECCERRLOG); ++ } ++ ++ i3200_clear_error_info(mci); ++} ++ ++static void i3200_process_error_info(struct mem_ctl_info *mci, ++ struct i3200_error_info *info) ++{ ++ int channel; ++ u64 log; ++ ++ if (!(info->errsts & I3200_ERRSTS_BITS)) ++ return; ++ ++ if ((info->errsts ^ info->errsts2) & I3200_ERRSTS_BITS) { ++ edac_mc_handle_ce_no_info(mci, "UE overwrote CE"); ++ info->errsts = info->errsts2; ++ } ++ ++ for (channel = 0; channel < nr_channels; channel++) { ++ log = info->eccerrlog[channel]; ++ if (log & I3200_ECCERRLOG_UE) { ++ edac_mc_handle_ue(mci, 0, 0, ++ eccerrlog_row(channel, log), ++ "i3200 UE"); ++ } else if (log & I3200_ECCERRLOG_CE) { ++ edac_mc_handle_ce(mci, 0, 0, ++ eccerrlog_syndrome(log), ++ eccerrlog_row(channel, log), 0, ++ "i3200 CE"); ++ } ++ } ++} ++ ++static void i3200_check(struct mem_ctl_info *mci) ++{ ++ struct i3200_error_info info; ++ ++ debugf1("MC%d: %s()\n", mci->mc_idx, __func__); ++ i3200_get_and_clear_error_info(mci, &info); ++ i3200_process_error_info(mci, &info); ++} ++ ++ ++void __iomem *i3200_map_mchbar(struct pci_dev *pdev) ++{ ++ union { ++ u64 mchbar; ++ struct { ++ u32 mchbar_low; ++ u32 mchbar_high; ++ }; ++ } u; ++ void __iomem *window; ++ ++ pci_read_config_dword(pdev, I3200_MCHBAR_LOW, &u.mchbar_low); ++ pci_read_config_dword(pdev, I3200_MCHBAR_HIGH, &u.mchbar_high); ++ u.mchbar &= I3200_MCHBAR_MASK; ++ ++ if (u.mchbar != (resource_size_t)u.mchbar) { ++ printk(KERN_ERR ++ "i3200: mmio space beyond accessible range (0x%llx)\n", ++ (unsigned long long)u.mchbar); ++ return NULL; ++ } ++ ++ window = ioremap_nocache(u.mchbar, I3200_MMR_WINDOW_SIZE); ++ if (!window) ++ printk(KERN_ERR "i3200: cannot map mmio space at 0x%llx\n", ++ (unsigned long long)u.mchbar); ++ ++ return window; ++} ++ ++ ++static void i3200_get_drbs(void __iomem *window, ++ u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL]) ++{ ++ int i; ++ ++ for (i = 0; i < I3200_RANKS_PER_CHANNEL; i++) { ++ drbs[0][i] = readw(window + I3200_C0DRB + 2*i) & I3200_DRB_MASK; ++ drbs[1][i] = readw(window + I3200_C1DRB + 2*i) & I3200_DRB_MASK; ++ } ++} ++ ++static bool i3200_is_stacked(struct pci_dev *pdev, ++ u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL]) ++{ ++ u16 tom; ++ ++ pci_read_config_word(pdev, I3200_TOM, &tom); ++ tom &= I3200_TOM_MASK; ++ ++ return drbs[I3200_CHANNELS - 1][I3200_RANKS_PER_CHANNEL - 1] == tom; ++} ++ ++static unsigned long drb_to_nr_pages( ++ u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL], bool stacked, ++ int channel, int rank) ++{ ++ int n; ++ ++ n = drbs[channel][rank]; ++ if (rank > 0) ++ n -= drbs[channel][rank - 1]; ++ if (stacked && (channel == 1) && ++ drbs[channel][rank] == drbs[channel][I3200_RANKS_PER_CHANNEL - 1]) ++ n -= drbs[0][I3200_RANKS_PER_CHANNEL - 1]; ++ ++ n <<= (I3200_DRB_SHIFT - PAGE_SHIFT); ++ return n; ++} ++ ++static int i3200_probe1(struct pci_dev *pdev, int dev_idx) ++{ ++ int rc; ++ int i; ++ struct mem_ctl_info *mci = NULL; ++ unsigned long last_page; ++ u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL]; ++ bool stacked; ++ void __iomem *window; ++ struct i3200_priv *priv; ++ ++ debugf0("MC: %s()\n", __func__); ++ ++ window = i3200_map_mchbar(pdev); ++ if (!window) ++ return -ENODEV; ++ ++ i3200_get_drbs(window, drbs); ++ nr_channels = how_many_channels(pdev); ++ ++ mci = edac_mc_alloc(sizeof(struct i3200_priv), I3200_RANKS, ++ nr_channels, 0); ++ if (!mci) ++ return -ENOMEM; ++ ++ debugf3("MC: %s(): init mci\n", __func__); ++ ++ mci->dev = &pdev->dev; ++ mci->mtype_cap = MEM_FLAG_DDR2; ++ ++ mci->edac_ctl_cap = EDAC_FLAG_SECDED; ++ mci->edac_cap = EDAC_FLAG_SECDED; ++ ++ mci->mod_name = EDAC_MOD_STR; ++ mci->mod_ver = I3200_REVISION; ++ mci->ctl_name = i3200_devs[dev_idx].ctl_name; ++ mci->dev_name = pci_name(pdev); ++ mci->edac_check = i3200_check; ++ mci->ctl_page_to_phys = NULL; ++ priv = mci->pvt_info; ++ priv->window = window; ++ ++ stacked = i3200_is_stacked(pdev, drbs); ++ ++ /* ++ * The dram rank boundary (DRB) reg values are boundary addresses ++ * for each DRAM rank with a granularity of 64MB. DRB regs are ++ * cumulative; the last one will contain the total memory ++ * contained in all ranks. ++ */ ++ last_page = -1UL; ++ for (i = 0; i < mci->nr_csrows; i++) { ++ unsigned long nr_pages; ++ struct csrow_info *csrow = &mci->csrows[i]; ++ ++ nr_pages = drb_to_nr_pages(drbs, stacked, ++ i / I3200_RANKS_PER_CHANNEL, ++ i % I3200_RANKS_PER_CHANNEL); ++ ++ if (nr_pages == 0) { ++ csrow->mtype = MEM_EMPTY; ++ continue; ++ } ++ ++ csrow->first_page = last_page + 1; ++ last_page += nr_pages; ++ csrow->last_page = last_page; ++ csrow->nr_pages = nr_pages; ++ ++ csrow->grain = nr_pages << PAGE_SHIFT; ++ csrow->mtype = MEM_DDR2; ++ csrow->dtype = DEV_UNKNOWN; ++ csrow->edac_mode = EDAC_UNKNOWN; ++ } ++ ++ i3200_clear_error_info(mci); ++ ++ rc = -ENODEV; ++ if (edac_mc_add_mc(mci)) { ++ debugf3("MC: %s(): failed edac_mc_add_mc()\n", __func__); ++ goto fail; ++ } ++ ++ /* get this far and it's successful */ ++ debugf3("MC: %s(): success\n", __func__); ++ return 0; ++ ++fail: ++ iounmap(window); ++ if (mci) ++ edac_mc_free(mci); ++ ++ return rc; ++} ++ ++static int __devinit i3200_init_one(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ int rc; ++ ++ debugf0("MC: %s()\n", __func__); ++ ++ if (pci_enable_device(pdev) < 0) ++ return -EIO; ++ ++ rc = i3200_probe1(pdev, ent->driver_data); ++ if (!mci_pdev) ++ mci_pdev = pci_dev_get(pdev); ++ ++ return rc; ++} ++ ++static void __devexit i3200_remove_one(struct pci_dev *pdev) ++{ ++ struct mem_ctl_info *mci; ++ struct i3200_priv *priv; ++ ++ debugf0("%s()\n", __func__); ++ ++ mci = edac_mc_del_mc(&pdev->dev); ++ if (!mci) ++ return; ++ ++ priv = mci->pvt_info; ++ iounmap(priv->window); ++ ++ edac_mc_free(mci); ++} ++ ++static const struct pci_device_id i3200_pci_tbl[] __devinitdata = { ++ { ++ PCI_VEND_DEV(INTEL, 3200_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, ++ I3200}, ++ { ++ 0, ++ } /* 0 terminated list. */ ++}; ++ ++MODULE_DEVICE_TABLE(pci, i3200_pci_tbl); ++ ++static struct pci_driver i3200_driver = { ++ .name = EDAC_MOD_STR, ++ .probe = i3200_init_one, ++ .remove = __devexit_p(i3200_remove_one), ++ .id_table = i3200_pci_tbl, ++}; ++ ++static int __init i3200_init(void) ++{ ++ int pci_rc; ++ ++ debugf3("MC: %s()\n", __func__); ++ ++ /* Ensure that the OPSTATE is set correctly for POLL or NMI */ ++ opstate_init(); ++ ++ pci_rc = pci_register_driver(&i3200_driver); ++ if (pci_rc < 0) ++ goto fail0; ++ ++ if (!mci_pdev) { ++ i3200_registered = 0; ++ mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, ++ PCI_DEVICE_ID_INTEL_3200_HB, NULL); ++ if (!mci_pdev) { ++ debugf0("i3200 pci_get_device fail\n"); ++ pci_rc = -ENODEV; ++ goto fail1; ++ } ++ ++ pci_rc = i3200_init_one(mci_pdev, i3200_pci_tbl); ++ if (pci_rc < 0) { ++ debugf0("i3200 init fail\n"); ++ pci_rc = -ENODEV; ++ goto fail1; ++ } ++ } ++ ++ return 0; ++ ++fail1: ++ pci_unregister_driver(&i3200_driver); ++ ++fail0: ++ if (mci_pdev) ++ pci_dev_put(mci_pdev); ++ ++ return pci_rc; ++} ++ ++static void __exit i3200_exit(void) ++{ ++ debugf3("MC: %s()\n", __func__); ++ ++ pci_unregister_driver(&i3200_driver); ++ if (!i3200_registered) { ++ i3200_remove_one(mci_pdev); ++ pci_dev_put(mci_pdev); ++ } ++} ++ ++module_init(i3200_init); ++module_exit(i3200_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Akamai Technologies, Inc."); ++MODULE_DESCRIPTION("MC support for Intel 3200 memory hub controllers"); ++ ++module_param(edac_op_state, int, 0444); ++MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); +diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c +index 3f2ccfc..157f650 100644 +--- a/drivers/edac/mpc85xx_edac.c ++++ b/drivers/edac/mpc85xx_edac.c +@@ -41,7 +41,9 @@ static u32 orig_pci_err_en; + #endif + + static u32 orig_l2_err_disable; ++#ifdef CONFIG_MPC85xx + static u32 orig_hid1[2]; ++#endif + + /************************ MC SYSFS parts ***********************************/ + +@@ -646,6 +648,7 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = { + { .compatible = "fsl,mpc8560-l2-cache-controller", }, + { .compatible = "fsl,mpc8568-l2-cache-controller", }, + { .compatible = "fsl,mpc8572-l2-cache-controller", }, ++ { .compatible = "fsl,p2020-l2-cache-controller", }, + {}, + }; + +@@ -788,19 +791,20 @@ static void __devinit mpc85xx_init_csrows(struct mem_ctl_info *mci) + csrow = &mci->csrows[index]; + cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 + + (index * MPC85XX_MC_CS_BNDS_OFS)); +- start = (cs_bnds & 0xfff0000) << 4; +- end = ((cs_bnds & 0xfff) << 20); +- if (start) +- start |= 0xfffff; +- if (end) +- end |= 0xfffff; ++ ++ start = (cs_bnds & 0xffff0000) >> 16; ++ end = (cs_bnds & 0x0000ffff); + + if (start == end) + continue; /* not populated */ + ++ start <<= (24 - PAGE_SHIFT); ++ end <<= (24 - PAGE_SHIFT); ++ end |= (1 << (24 - PAGE_SHIFT)) - 1; ++ + csrow->first_page = start >> PAGE_SHIFT; + csrow->last_page = end >> PAGE_SHIFT; +- csrow->nr_pages = csrow->last_page + 1 - csrow->first_page; ++ csrow->nr_pages = end + 1 - start; + csrow->grain = 8; + csrow->mtype = mtype; + csrow->dtype = DEV_UNKNOWN; +@@ -984,6 +988,8 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = { + { .compatible = "fsl,mpc8560-memory-controller", }, + { .compatible = "fsl,mpc8568-memory-controller", }, + { .compatible = "fsl,mpc8572-memory-controller", }, ++ { .compatible = "fsl,mpc8349-memory-controller", }, ++ { .compatible = "fsl,p2020-memory-controller", }, + {}, + }; + +@@ -999,13 +1005,13 @@ static struct of_platform_driver mpc85xx_mc_err_driver = { + }, + }; + +- ++#ifdef CONFIG_MPC85xx + static void __init mpc85xx_mc_clear_rfxe(void *data) + { + orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1); + mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000)); + } +- ++#endif + + static int __init mpc85xx_mc_init(void) + { +@@ -1038,26 +1044,32 @@ static int __init mpc85xx_mc_init(void) + printk(KERN_WARNING EDAC_MOD_STR "PCI fails to register\n"); + #endif + ++#ifdef CONFIG_MPC85xx + /* + * need to clear HID1[RFXE] to disable machine check int + * so we can catch it + */ + if (edac_op_state == EDAC_OPSTATE_INT) + on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0); ++#endif + + return 0; + } + + module_init(mpc85xx_mc_init); + ++#ifdef CONFIG_MPC85xx + static void __exit mpc85xx_mc_restore_hid1(void *data) + { + mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]); + } ++#endif + + static void __exit mpc85xx_mc_exit(void) + { ++#ifdef CONFIG_MPC85xx + on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); ++#endif + #ifdef CONFIG_PCI + of_unregister_platform_driver(&mpc85xx_pci_err_driver); + #endif +diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c +index 5131aaa..a6b9fec 100644 +--- a/drivers/edac/mv64x60_edac.c ++++ b/drivers/edac/mv64x60_edac.c +@@ -90,7 +90,7 @@ static int __init mv64x60_pci_fixup(struct platform_device *pdev) + return -ENOENT; + } + +- pci_serr = ioremap(r->start, r->end - r->start + 1); ++ pci_serr = ioremap(r->start, resource_size(r)); + if (!pci_serr) + return -ENOMEM; + +@@ -140,7 +140,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdata->name)) { + printk(KERN_ERR "%s: Error while requesting mem region\n", + __func__); +@@ -150,7 +150,7 @@ static int __devinit mv64x60_pci_err_probe(struct platform_device *pdev) + + pdata->pci_vbase = devm_ioremap(&pdev->dev, + r->start, +- r->end - r->start + 1); ++ resource_size(r)); + if (!pdata->pci_vbase) { + printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__); + res = -ENOMEM; +@@ -306,7 +306,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdata->name)) { + printk(KERN_ERR "%s: Error while request mem region\n", + __func__); +@@ -316,7 +316,7 @@ static int __devinit mv64x60_sram_err_probe(struct platform_device *pdev) + + pdata->sram_vbase = devm_ioremap(&pdev->dev, + r->start, +- r->end - r->start + 1); ++ resource_size(r)); + if (!pdata->sram_vbase) { + printk(KERN_ERR "%s: Unable to setup SRAM err regs\n", + __func__); +@@ -474,7 +474,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdata->name)) { + printk(KERN_ERR "%s: Error while requesting mem region\n", + __func__); +@@ -484,7 +484,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev) + + pdata->cpu_vbase[0] = devm_ioremap(&pdev->dev, + r->start, +- r->end - r->start + 1); ++ resource_size(r)); + if (!pdata->cpu_vbase[0]) { + printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__); + res = -ENOMEM; +@@ -501,7 +501,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdata->name)) { + printk(KERN_ERR "%s: Error while requesting mem region\n", + __func__); +@@ -511,7 +511,7 @@ static int __devinit mv64x60_cpu_err_probe(struct platform_device *pdev) + + pdata->cpu_vbase[1] = devm_ioremap(&pdev->dev, + r->start, +- r->end - r->start + 1); ++ resource_size(r)); + if (!pdata->cpu_vbase[1]) { + printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__); + res = -ENOMEM; +@@ -726,7 +726,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev) + + if (!devm_request_mem_region(&pdev->dev, + r->start, +- r->end - r->start + 1, ++ resource_size(r), + pdata->name)) { + printk(KERN_ERR "%s: Error while requesting mem region\n", + __func__); +@@ -736,7 +736,7 @@ static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev) + + pdata->mc_vbase = devm_ioremap(&pdev->dev, + r->start, +- r->end - r->start + 1); ++ resource_size(r)); + if (!pdata->mc_vbase) { + printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__); + res = -ENOMEM; diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index f74edae..e4864e8 100644 --- a/drivers/firewire/core-card.c @@ -393495,7 +398443,7 @@ index de566cf..30879df 100644 -obj-y += drm/ +obj-y += drm/ vga/ diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig -index 39b393d..e4d971c 100644 +index 39b393d..f831ea1 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -18,6 +18,14 @@ menuconfig DRM @@ -393533,7 +398481,7 @@ index 39b393d..e4d971c 100644 help Choose this option if you have an ATI Radeon graphics card. There are both PCI and AGP versions. You don't need to choose this to -@@ -82,11 +92,10 @@ config DRM_I830 +@@ -82,17 +92,17 @@ config DRM_I830 config DRM_I915 tristate "i915 driver" depends on AGP_INTEL @@ -393546,7 +398494,14 @@ index 39b393d..e4d971c 100644 # i915 depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick select VIDEO_OUTPUT_CONTROL if ACPI -@@ -116,6 +125,7 @@ endchoice + select BACKLIGHT_CLASS_DEVICE if ACPI + select INPUT if ACPI + select ACPI_VIDEO if ACPI ++ select ACPI_BUTTON if ACPI + help + Choose this option if you have a system that has Intel 830M, 845G, + 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the +@@ -116,6 +126,7 @@ endchoice config DRM_MGA tristate "Matrox g200/g400" depends on DRM @@ -394377,7 +399332,7 @@ index b39d7bf..a75ca63 100644 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH), diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c -index 7f2728b..90d76ba 100644 +index 7f2728b..9888c20 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -60,6 +60,12 @@ @@ -394393,7 +399348,18 @@ index 7f2728b..90d76ba 100644 static struct edid_quirk { char *vendor; -@@ -237,28 +243,291 @@ static void edid_fixup_preferred(struct drm_connector *connector, +@@ -103,7 +109,9 @@ static struct edid_quirk { + + + /* Valid EDID header has these bytes */ +-static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; ++static const u8 edid_header[] = { ++ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 ++}; + + /** + * edid_is_valid - sanity check EDID data +@@ -237,39 +245,343 @@ static void edid_fixup_preferred(struct drm_connector *connector, preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; } @@ -394654,6 +399620,19 @@ index 7f2728b..90d76ba 100644 + } + return mode; +} ++ ++/* ++ * 0 is reserved. The spec says 0x01 fill for unused timings. Some old ++ * monitors fill with ascii space (0x20) instead. ++ */ ++static int ++bad_std_timing(u8 a, u8 b) ++{ ++ return (a == 0x00 && b == 0x00) || ++ (a == 0x01 && b == 0x01) || ++ (a == 0x20 && b == 0x20); ++} ++ /** * drm_mode_std - convert standard mode info (width, height, refresh) into mode * @t: standard timing params @@ -394669,6 +399648,7 @@ index 7f2728b..90d76ba 100644 struct drm_display_mode *drm_mode_std(struct drm_device *dev, - struct std_timing *t) + struct std_timing *t, ++ int revision, + int timing_level) { struct drm_display_mode *mode; @@ -394677,23 +399657,30 @@ index 7f2728b..90d76ba 100644 + int vrefresh_rate; unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) >> EDID_TIMING_ASPECT_SHIFT; -- -- mode = drm_mode_create(dev); -- if (!mode) -- return NULL; -- + unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) + >> EDID_TIMING_VFREQ_SHIFT; -+ + +- mode = drm_mode_create(dev); +- if (!mode) ++ if (bad_std_timing(t->hsize, t->vfreq_aspect)) + return NULL; + +- if (aspect_ratio == 0) +- vsize = (hsize * 10) / 16; +- else if (aspect_ratio == 1) + /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ + hsize = t->hsize * 8 + 248; + /* vrefresh_rate = vfreq + 60 */ + vrefresh_rate = vfreq + 60; + /* the vdisplay is calculated based on the aspect ratio */ - if (aspect_ratio == 0) - vsize = (hsize * 10) / 16; - else if (aspect_ratio == 1) -@@ -267,9 +536,30 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, ++ if (aspect_ratio == 0) { ++ if (revision < 3) ++ vsize = hsize; ++ else ++ vsize = (hsize * 10) / 16; ++ } else if (aspect_ratio == 1) + vsize = (hsize * 3) / 4; + else if (aspect_ratio == 2) vsize = (hsize * 4) / 5; else vsize = (hsize * 9) / 16; @@ -394727,7 +399714,7 @@ index 7f2728b..90d76ba 100644 return mode; } -@@ -451,6 +741,19 @@ static int add_established_modes(struct drm_connector *connector, struct edid *e +@@ -451,6 +763,19 @@ static int add_established_modes(struct drm_connector *connector, struct edid *e return modes; } @@ -394747,7 +399734,7 @@ index 7f2728b..90d76ba 100644 /** * add_standard_modes - get std. modes from EDID and add them -@@ -463,6 +766,9 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid +@@ -463,6 +788,9 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid { struct drm_device *dev = connector->dev; int i, modes = 0; @@ -394757,17 +399744,17 @@ index 7f2728b..90d76ba 100644 for (i = 0; i < EDID_STD_TIMINGS; i++) { struct std_timing *t = &edid->standard_timings[i]; -@@ -472,7 +778,8 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid +@@ -472,7 +800,8 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid if (t->hsize == 1 && t->vfreq_aspect == 1) continue; - newmode = drm_mode_std(dev, &edid->standard_timings[i]); + newmode = drm_mode_std(dev, &edid->standard_timings[i], -+ timing_level); ++ edid->revision, timing_level); if (newmode) { drm_mode_probed_add(connector, newmode); modes++; -@@ -496,6 +803,9 @@ static int add_detailed_info(struct drm_connector *connector, +@@ -496,6 +825,9 @@ static int add_detailed_info(struct drm_connector *connector, { struct drm_device *dev = connector->dev; int i, j, modes = 0; @@ -394777,17 +399764,25 @@ index 7f2728b..90d76ba 100644 for (i = 0; i < EDID_DETAILED_TIMINGS; i++) { struct detailed_timing *timing = &edid->detailed_timings[i]; -@@ -525,7 +835,8 @@ static int add_detailed_info(struct drm_connector *connector, +@@ -519,13 +851,14 @@ static int add_detailed_info(struct drm_connector *connector, + case EDID_DETAIL_MONITOR_CPDATA: + break; + case EDID_DETAIL_STD_MODES: +- /* Five modes per detailed section */ +- for (j = 0; j < 5; i++) { ++ for (j = 0; j < 6; i++) { + struct std_timing *std; struct drm_display_mode *newmode; std = &data->data.timings[j]; - newmode = drm_mode_std(dev, std); + newmode = drm_mode_std(dev, std, ++ edid->revision, + timing_level); if (newmode) { drm_mode_probed_add(connector, newmode); modes++; -@@ -551,6 +862,122 @@ static int add_detailed_info(struct drm_connector *connector, +@@ -551,6 +884,124 @@ static int add_detailed_info(struct drm_connector *connector, return modes; } @@ -394893,7 +399888,9 @@ index 7f2728b..90d76ba 100644 + struct drm_display_mode *newmode; + + std = &data->data.timings[j]; -+ newmode = drm_mode_std(dev, std, timing_level); ++ newmode = drm_mode_std(dev, std, ++ edid->revision, ++ timing_level); + if (newmode) { + drm_mode_probed_add(connector, newmode); + modes++; @@ -394910,7 +399907,7 @@ index 7f2728b..90d76ba 100644 #define DDC_ADDR 0x50 /** -@@ -584,7 +1011,6 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, +@@ -584,7 +1035,6 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter, if (i2c_transfer(adapter, msgs, 2) == 2) return 0; @@ -394918,7 +399915,7 @@ index 7f2728b..90d76ba 100644 return -1; } EXPORT_SYMBOL(drm_do_probe_ddc_edid); -@@ -597,8 +1023,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector, +@@ -597,8 +1047,6 @@ static int drm_ddc_read_edid(struct drm_connector *connector, ret = drm_do_probe_ddc_edid(adapter, buf, len); if (ret != 0) { @@ -394927,7 +399924,7 @@ index 7f2728b..90d76ba 100644 goto end; } if (!edid_is_valid((struct edid *)buf)) { -@@ -610,7 +1034,6 @@ end: +@@ -610,7 +1058,6 @@ end: return ret; } @@ -394935,7 +399932,7 @@ index 7f2728b..90d76ba 100644 /** * drm_get_edid - get EDID data, if available * @connector: connector we're probing -@@ -763,6 +1186,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) +@@ -763,6 +1210,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) num_modes += add_established_modes(connector, edid); num_modes += add_standard_modes(connector, edid); num_modes += add_detailed_info(connector, edid, quirks); @@ -394943,7 +399940,7 @@ index 7f2728b..90d76ba 100644 if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) edid_fixup_preferred(connector, quirks); -@@ -788,3 +1212,49 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) +@@ -788,3 +1236,49 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) return num_modes; } EXPORT_SYMBOL(drm_add_edid_modes); @@ -395829,10 +400826,30 @@ index 0000000..2c46713 +} +EXPORT_SYMBOL(drm_fb_helper_fill_var); diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c -index ffe8f43..230c9ff 100644 +index ffe8f43..8039199 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c -@@ -164,7 +164,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc); +@@ -142,6 +142,19 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size) + if (IS_ERR(obj->filp)) + goto free; + ++ /* Basically we want to disable the OOM killer and handle ENOMEM ++ * ourselves by sacrificing pages from cached buffers. ++ * XXX shmem_file_[gs]et_gfp_mask() ++ */ ++ mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, ++ GFP_HIGHUSER | ++ __GFP_COLD | ++ __GFP_FS | ++ __GFP_RECLAIMABLE | ++ __GFP_NORETRY | ++ __GFP_NOWARN | ++ __GFP_NOMEMALLOC); ++ + kref_init(&obj->refcount); + kref_init(&obj->handlecount); + obj->size = size; +@@ -164,7 +177,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc); * Removes the mapping from handle to filp for this object. */ static int @@ -395841,7 +400858,7 @@ index ffe8f43..230c9ff 100644 { struct drm_device *dev; struct drm_gem_object *obj; -@@ -207,7 +207,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle) +@@ -207,7 +220,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle) int drm_gem_handle_create(struct drm_file *file_priv, struct drm_gem_object *obj, @@ -395850,7 +400867,7 @@ index ffe8f43..230c9ff 100644 { int ret; -@@ -221,7 +221,7 @@ again: +@@ -221,7 +234,7 @@ again: /* do the allocation under our spinlock */ spin_lock(&file_priv->table_lock); @@ -395859,7 +400876,7 @@ index ffe8f43..230c9ff 100644 spin_unlock(&file_priv->table_lock); if (ret == -EAGAIN) goto again; -@@ -237,7 +237,7 @@ EXPORT_SYMBOL(drm_gem_handle_create); +@@ -237,7 +250,7 @@ EXPORT_SYMBOL(drm_gem_handle_create); /** Returns a reference to the object named by the handle. */ struct drm_gem_object * drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, @@ -395868,7 +400885,7 @@ index ffe8f43..230c9ff 100644 { struct drm_gem_object *obj; -@@ -344,7 +344,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, +@@ -344,7 +357,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, struct drm_gem_open *args = data; struct drm_gem_object *obj; int ret; @@ -395877,7 +400894,7 @@ index ffe8f43..230c9ff 100644 if (!(dev->driver->driver_features & DRIVER_GEM)) return -ENODEV; -@@ -539,7 +539,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) +@@ -539,7 +552,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; vma->vm_ops = obj->dev->driver->gem_vm_ops; vma->vm_private_data = map->handle; @@ -396591,10 +401608,10 @@ index f7a615b..7e42b7e 100644 +} +EXPORT_SYMBOL_GPL(drm_class_device_unregister); diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile -index 30d6b99..5269dfa 100644 +index 30d6b99..fa7b9be 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile -@@ -4,10 +4,10 @@ +@@ -4,11 +4,12 @@ ccflags-y := -Iinclude/drm i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ @@ -396604,14 +401621,16 @@ index 30d6b99..5269dfa 100644 i915_gem_debug.o \ - i915_gem_debugfs.o \ i915_gem_tiling.o \ ++ i915_trace_points.o \ intel_display.o \ intel_crt.o \ + intel_lvds.o \ diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c new file mode 100644 -index 0000000..1e3bdce +index 0000000..f8ce9a3 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_debugfs.c -@@ -0,0 +1,445 @@ +@@ -0,0 +1,447 @@ +/* + * Copyright © 2008 Intel Corporation + * @@ -396710,11 +401729,13 @@ index 0000000..1e3bdce + { + struct drm_gem_object *obj = obj_priv->obj; + -+ seq_printf(m, " %p: %s %08x %08x %d", ++ seq_printf(m, " %p: %s %8zd %08x %08x %d %s", + obj, + get_pin_flag(obj_priv), ++ obj->size, + obj->read_domains, obj->write_domain, -+ obj_priv->last_rendering_seqno); ++ obj_priv->last_rendering_seqno, ++ obj_priv->dirty ? "dirty" : ""); + + if (obj->name) + seq_printf(m, " (name: %d)", obj->name); @@ -397058,10 +402079,10 @@ index 0000000..1e3bdce +#endif /* CONFIG_DEBUG_FS */ + diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c -index 50d1f78..5a49a18 100644 +index 50d1f78..45d507e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c -@@ -29,11 +29,11 @@ +@@ -29,11 +29,12 @@ #include "drmP.h" #include "drm.h" #include "drm_crtc_helper.h" @@ -397071,11 +402092,36 @@ index 50d1f78..5a49a18 100644 #include "i915_drv.h" - -#define I915_DRV "i915_drv" ++#include "i915_trace.h" +#include /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time -@@ -80,6 +80,34 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) +@@ -50,14 +51,18 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) + u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + int i; + ++ trace_i915_ring_wait_begin (dev); ++ + for (i = 0; i < 100000; i++) { + ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; + acthd = I915_READ(acthd_reg); + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->Size; +- if (ring->space >= n) ++ if (ring->space >= n) { ++ trace_i915_ring_wait_end (dev); + return 0; ++ } + + if (dev->primary->master) { + struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; +@@ -77,9 +82,38 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller) + + } + ++ trace_i915_ring_wait_end (dev); return -EBUSY; } @@ -397110,7 +402156,7 @@ index 50d1f78..5a49a18 100644 /** * Sets up the hardware status page for devices that need a physical address * in the register. -@@ -101,7 +129,7 @@ static int i915_init_phys_hws(struct drm_device *dev) +@@ -101,7 +135,7 @@ static int i915_init_phys_hws(struct drm_device *dev) memset(dev_priv->hw_status_page, 0, PAGE_SIZE); I915_WRITE(HWS_PGA, dev_priv->dma_status_page); @@ -397119,7 +402165,7 @@ index 50d1f78..5a49a18 100644 return 0; } -@@ -187,8 +215,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) +@@ -187,8 +221,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) master_priv->sarea_priv = (drm_i915_sarea_t *) ((u8 *)master_priv->sarea->handle + init->sarea_priv_offset); } else { @@ -397129,7 +402175,7 @@ index 50d1f78..5a49a18 100644 } if (init->ring_size != 0) { -@@ -200,7 +227,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) +@@ -200,7 +233,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } dev_priv->ring.Size = init->ring_size; @@ -397137,7 +402183,7 @@ index 50d1f78..5a49a18 100644 dev_priv->ring.map.offset = init->ring_start; dev_priv->ring.map.size = init->ring_size; -@@ -238,7 +264,7 @@ static int i915_dma_resume(struct drm_device * dev) +@@ -238,7 +270,7 @@ static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; @@ -397146,7 +402192,7 @@ index 50d1f78..5a49a18 100644 if (dev_priv->ring.map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" -@@ -251,14 +277,14 @@ static int i915_dma_resume(struct drm_device * dev) +@@ -251,14 +283,14 @@ static int i915_dma_resume(struct drm_device * dev) DRM_ERROR("Can not find hardware status page\n"); return -EINVAL; } @@ -397163,7 +402209,7 @@ index 50d1f78..5a49a18 100644 return 0; } -@@ -552,7 +578,7 @@ static int i915_dispatch_flip(struct drm_device * dev) +@@ -552,7 +584,7 @@ static int i915_dispatch_flip(struct drm_device * dev) if (!master_priv->sarea_priv) return -EINVAL; @@ -397172,7 +402218,7 @@ index 50d1f78..5a49a18 100644 __func__, dev_priv->current_page, master_priv->sarea_priv->pf_current_page); -@@ -633,8 +659,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, +@@ -633,8 +665,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, return -EINVAL; } @@ -397182,7 +402228,7 @@ index 50d1f78..5a49a18 100644 batch->start, batch->used, batch->num_cliprects); RING_LOCK_TEST_WITH_RETURN(dev, file_priv); -@@ -681,8 +706,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, +@@ -681,8 +712,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, void *batch_data; int ret; @@ -397192,7 +402238,7 @@ index 50d1f78..5a49a18 100644 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects); RING_LOCK_TEST_WITH_RETURN(dev, file_priv); -@@ -735,7 +759,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, +@@ -735,7 +765,7 @@ static int i915_flip_bufs(struct drm_device *dev, void *data, { int ret; @@ -397201,7 +402247,7 @@ index 50d1f78..5a49a18 100644 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); -@@ -778,7 +802,7 @@ static int i915_getparam(struct drm_device *dev, void *data, +@@ -778,7 +808,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = dev_priv->num_fence_regs - dev_priv->fence_reg_start; break; default: @@ -397210,7 +402256,7 @@ index 50d1f78..5a49a18 100644 param->param); return -EINVAL; } -@@ -819,7 +843,7 @@ static int i915_setparam(struct drm_device *dev, void *data, +@@ -819,7 +849,7 @@ static int i915_setparam(struct drm_device *dev, void *data, dev_priv->fence_reg_start = param->value; break; default: @@ -397219,7 +402265,7 @@ index 50d1f78..5a49a18 100644 param->param); return -EINVAL; } -@@ -846,7 +870,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, +@@ -846,7 +876,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, return 0; } @@ -397228,7 +402274,7 @@ index 50d1f78..5a49a18 100644 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); -@@ -868,13 +892,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data, +@@ -868,13 +898,25 @@ static int i915_set_status_page(struct drm_device *dev, void *data, memset(dev_priv->hw_status_page, 0, PAGE_SIZE); I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr); @@ -397256,9 +402302,13 @@ index 50d1f78..5a49a18 100644 /** * i915_probe_agp - get AGP bootup configuration * @pdev: PCI device -@@ -888,20 +924,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data, +@@ -886,22 +928,16 @@ static int i915_set_status_page(struct drm_device *dev, void *data, + * how much was set aside so we can use it for our own purposes. + */ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, - uint32_t *preallocated_size) +- uint32_t *preallocated_size) ++ uint32_t *preallocated_size, ++ uint32_t *start) { - struct pci_dev *bridge_dev; + struct drm_i915_private *dev_priv = dev->dev_private; @@ -397279,10 +402329,163 @@ index 50d1f78..5a49a18 100644 *aperture_size = 1024 * 1024; *preallocated_size = 1024 * 1024; -@@ -984,6 +1013,19 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, +@@ -980,11 +1016,174 @@ static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size, + return -1; + } + *preallocated_size = stolen - overhead; ++ *start = overhead; + return 0; } ++#define PTE_ADDRESS_MASK 0xfffff000 ++#define PTE_ADDRESS_MASK_HIGH 0x000000f0 /* i915+ */ ++#define PTE_MAPPING_TYPE_UNCACHED (0 << 1) ++#define PTE_MAPPING_TYPE_DCACHE (1 << 1) /* i830 only */ ++#define PTE_MAPPING_TYPE_CACHED (3 << 1) ++#define PTE_MAPPING_TYPE_MASK (3 << 1) ++#define PTE_VALID (1 << 0) ++ ++/** ++ * i915_gtt_to_phys - take a GTT address and turn it into a physical one ++ * @dev: drm device ++ * @gtt_addr: address to translate ++ * ++ * Some chip functions require allocations from stolen space but need the ++ * physical address of the memory in question. We use this routine ++ * to get a physical address suitable for register programming from a given ++ * GTT address. ++ */ ++static unsigned long i915_gtt_to_phys(struct drm_device *dev, ++ unsigned long gtt_addr) ++{ ++ unsigned long *gtt; ++ unsigned long entry, phys; ++ int gtt_bar = IS_I9XX(dev) ? 0 : 1; ++ int gtt_offset, gtt_size; ++ ++ if (IS_I965G(dev)) { ++ if (IS_G4X(dev) || IS_IGDNG(dev)) { ++ gtt_offset = 2*1024*1024; ++ gtt_size = 2*1024*1024; ++ } else { ++ gtt_offset = 512*1024; ++ gtt_size = 512*1024; ++ } ++ } else { ++ gtt_bar = 3; ++ gtt_offset = 0; ++ gtt_size = pci_resource_len(dev->pdev, gtt_bar); ++ } ++ ++ gtt = ioremap_wc(pci_resource_start(dev->pdev, gtt_bar) + gtt_offset, ++ gtt_size); ++ if (!gtt) { ++ DRM_ERROR("ioremap of GTT failed\n"); ++ return 0; ++ } ++ ++ entry = *(volatile u32 *)(gtt + (gtt_addr / 1024)); ++ ++ DRM_DEBUG("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); ++ ++ /* Mask out these reserved bits on this hardware. */ ++ if (!IS_I9XX(dev) || IS_I915G(dev) || IS_I915GM(dev) || ++ IS_I945G(dev) || IS_I945GM(dev)) { ++ entry &= ~PTE_ADDRESS_MASK_HIGH; ++ } ++ ++ /* If it's not a mapping type we know, then bail. */ ++ if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && ++ (entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) { ++ iounmap(gtt); ++ return 0; ++ } ++ ++ if (!(entry & PTE_VALID)) { ++ DRM_ERROR("bad GTT entry in stolen space\n"); ++ iounmap(gtt); ++ return 0; ++ } ++ ++ iounmap(gtt); ++ ++ phys =(entry & PTE_ADDRESS_MASK) | ++ ((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); ++ ++ DRM_DEBUG("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys); ++ ++ return phys; ++} ++ ++static void i915_warn_stolen(struct drm_device *dev) ++{ ++ DRM_ERROR("not enough stolen space for compressed buffer, disabling\n"); ++ DRM_ERROR("hint: you may be able to increase stolen memory size in the BIOS to avoid this\n"); ++} ++ ++static void i915_setup_compression(struct drm_device *dev, int size) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_mm_node *compressed_fb, *compressed_llb; ++ unsigned long cfb_base, ll_base; ++ ++ /* Leave 1M for line length buffer & misc. */ ++ compressed_fb = drm_mm_search_free(&dev_priv->vram, size, 4096, 0); ++ if (!compressed_fb) { ++ i915_warn_stolen(dev); ++ return; ++ } ++ ++ compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); ++ if (!compressed_fb) { ++ i915_warn_stolen(dev); ++ return; ++ } ++ ++ cfb_base = i915_gtt_to_phys(dev, compressed_fb->start); ++ if (!cfb_base) { ++ DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); ++ drm_mm_put_block(compressed_fb); ++ } ++ ++ if (!IS_GM45(dev)) { ++ compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096, ++ 4096, 0); ++ if (!compressed_llb) { ++ i915_warn_stolen(dev); ++ return; ++ } ++ ++ compressed_llb = drm_mm_get_block(compressed_llb, 4096, 4096); ++ if (!compressed_llb) { ++ i915_warn_stolen(dev); ++ return; ++ } ++ ++ ll_base = i915_gtt_to_phys(dev, compressed_llb->start); ++ if (!ll_base) { ++ DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); ++ drm_mm_put_block(compressed_fb); ++ drm_mm_put_block(compressed_llb); ++ } ++ } ++ ++ dev_priv->cfb_size = size; ++ ++ if (IS_GM45(dev)) { ++ g4x_disable_fbc(dev); ++ I915_WRITE(DPFC_CB_BASE, compressed_fb->start); ++ } else { ++ i8xx_disable_fbc(dev); ++ I915_WRITE(FBC_CFB_BASE, cfb_base); ++ I915_WRITE(FBC_LL_BASE, ll_base); ++ } ++ ++ DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, ++ ll_base, size >> 20); ++} ++ +/* true = enable decode, false = disable decoder */ +static unsigned int i915_vga_set_decode(void *cookie, bool state) +{ @@ -397297,9 +402500,48 @@ index 50d1f78..5a49a18 100644 +} + static int i915_load_modeset_init(struct drm_device *dev, ++ unsigned long prealloc_start, unsigned long prealloc_size, unsigned long agp_size) -@@ -1029,6 +1071,11 @@ static int i915_load_modeset_init(struct drm_device *dev, + { +@@ -1005,6 +1204,10 @@ static int i915_load_modeset_init(struct drm_device *dev, + + /* Basic memrange allocator for stolen space (aka vram) */ + drm_mm_init(&dev_priv->vram, 0, prealloc_size); ++ DRM_INFO("set up %ldM of stolen space\n", prealloc_size / (1024*1024)); ++ ++ /* We're off and running w/KMS */ ++ dev_priv->mm.suspended = 0; + + /* Let GEM Manage from end of prealloc space to end of aperture. + * +@@ -1017,10 +1220,25 @@ static int i915_load_modeset_init(struct drm_device *dev, + */ + i915_gem_do_init(dev, prealloc_size, agp_size - 4096); + ++ mutex_lock(&dev->struct_mutex); + ret = i915_gem_init_ringbuffer(dev); ++ mutex_unlock(&dev->struct_mutex); + if (ret) + goto out; + ++ /* Try to set up FBC with a reasonable compressed buffer size */ ++ if (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev) || IS_GM45(dev)) && ++ i915_powersave) { ++ int cfb_size; ++ ++ /* Try to get an 8M buffer... */ ++ if (prealloc_size > (9*1024*1024)) ++ cfb_size = 8*1024*1024; ++ else /* fall back to 7/8 of the stolen space */ ++ cfb_size = prealloc_size * 7 / 8; ++ i915_setup_compression(dev, cfb_size); ++ } ++ + /* Allow hardware batchbuffers unless told otherwise. + */ + dev_priv->allow_batchbuffer = 1; +@@ -1029,6 +1247,11 @@ static int i915_load_modeset_init(struct drm_device *dev, if (ret) DRM_INFO("failed to find VBIOS tables\n"); @@ -397311,7 +402553,16 @@ index 50d1f78..5a49a18 100644 ret = drm_irq_install(dev); if (ret) goto destroy_ringbuffer; -@@ -1153,11 +1200,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) +@@ -1133,7 +1356,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + struct drm_i915_private *dev_priv = dev->dev_private; + resource_size_t base, size; + int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; +- uint32_t agp_size, prealloc_size; ++ uint32_t agp_size, prealloc_size, prealloc_start; + + /* i915 has 4 more counters */ + dev->counters += 4; +@@ -1153,11 +1376,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) base = drm_get_resource_start(dev, mmio_bar); size = drm_get_resource_len(dev, mmio_bar); @@ -397329,7 +402580,39 @@ index 50d1f78..5a49a18 100644 } dev_priv->mm.gtt_mapping = -@@ -1269,6 +1321,8 @@ out_iomapfree: +@@ -1182,7 +1410,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + "performance may suffer.\n"); + } + +- ret = i915_probe_agp(dev, &agp_size, &prealloc_size); ++ ret = i915_probe_agp(dev, &agp_size, &prealloc_size, &prealloc_start); + if (ret) + goto out_iomapfree; + +@@ -1248,8 +1476,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + return ret; + } + ++ /* Start out suspended */ ++ dev_priv->mm.suspended = 1; ++ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { +- ret = i915_load_modeset_init(dev, prealloc_size, agp_size); ++ ret = i915_load_modeset_init(dev, prealloc_start, ++ prealloc_size, agp_size); + if (ret < 0) { + DRM_ERROR("failed to init modeset\n"); + goto out_workqueue_free; +@@ -1261,6 +1493,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) + if (!IS_IGDNG(dev)) + intel_opregion_init(dev, 0); + ++ setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, ++ (unsigned long) dev); + return 0; + + out_workqueue_free: +@@ -1269,6 +1503,8 @@ out_iomapfree: io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: iounmap(dev_priv->regs); @@ -397338,7 +402621,15 @@ index 50d1f78..5a49a18 100644 free_priv: kfree(dev_priv); return ret; -@@ -1289,6 +1343,7 @@ int i915_driver_unload(struct drm_device *dev) +@@ -1279,6 +1515,7 @@ int i915_driver_unload(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + + destroy_workqueue(dev_priv->wq); ++ del_timer_sync(&dev_priv->hangcheck_timer); + + io_mapping_free(dev_priv->mm.gtt_mapping); + if (dev_priv->mm.gtt_mtrr >= 0) { +@@ -1289,6 +1526,7 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_irq_uninstall(dev); @@ -397346,7 +402637,7 @@ index 50d1f78..5a49a18 100644 } if (dev->pdev->msi_enabled) -@@ -1312,6 +1367,7 @@ int i915_driver_unload(struct drm_device *dev) +@@ -1312,6 +1550,7 @@ int i915_driver_unload(struct drm_device *dev) i915_gem_lastclose(dev); } @@ -397354,7 +402645,7 @@ index 50d1f78..5a49a18 100644 kfree(dev->dev_private); return 0; -@@ -1321,7 +1377,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) +@@ -1321,7 +1560,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) { struct drm_i915_file_private *i915_file_priv; @@ -397363,7 +402654,7 @@ index 50d1f78..5a49a18 100644 i915_file_priv = (struct drm_i915_file_private *) kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); -@@ -1352,7 +1408,7 @@ void i915_driver_lastclose(struct drm_device * dev) +@@ -1352,7 +1591,7 @@ void i915_driver_lastclose(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { @@ -397372,8 +402663,16 @@ index 50d1f78..5a49a18 100644 return; } +@@ -1416,6 +1655,7 @@ struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), + DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), + DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), ++ DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0), + }; + + int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c -index fc4b68a..dbe568c 100644 +index fc4b68a..b93814c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -37,12 +37,15 @@ @@ -397393,7 +402692,161 @@ index fc4b68a..dbe568c 100644 static struct drm_driver driver; static struct pci_device_id pciidlist[] = { -@@ -188,8 +191,8 @@ static struct drm_driver driver = { +@@ -86,6 +89,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) + pci_set_power_state(dev->pdev, PCI_D3hot); + } + ++ dev_priv->suspended = 1; ++ + return 0; + } + +@@ -94,8 +99,6 @@ static int i915_resume(struct drm_device *dev) + struct drm_i915_private *dev_priv = dev->dev_private; + int ret = 0; + +- pci_set_power_state(dev->pdev, PCI_D0); +- pci_restore_state(dev->pdev); + if (pci_enable_device(dev->pdev)) + return -1; + pci_set_master(dev->pdev); +@@ -121,9 +124,135 @@ static int i915_resume(struct drm_device *dev) + drm_helper_resume_force_mode(dev); + } + ++ dev_priv->suspended = 0; ++ + return ret; + } + ++/** ++ * i965_reset - reset chip after a hang ++ * @dev: drm device to reset ++ * @flags: reset domains ++ * ++ * Reset the chip. Useful if a hang is detected. Returns zero on successful ++ * reset or otherwise an error code. ++ * ++ * Procedure is fairly simple: ++ * - reset the chip using the reset reg ++ * - re-init context state ++ * - re-init hardware status page ++ * - re-init ring buffer ++ * - re-init interrupt state ++ * - re-init display ++ */ ++int i965_reset(struct drm_device *dev, u8 flags) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ unsigned long timeout; ++ u8 gdrst; ++ /* ++ * We really should only reset the display subsystem if we actually ++ * need to ++ */ ++ bool need_display = true; ++ ++ mutex_lock(&dev->struct_mutex); ++ ++ /* ++ * Clear request list ++ */ ++ i915_gem_retire_requests(dev); ++ ++ if (need_display) ++ i915_save_display(dev); ++ ++ if (IS_I965G(dev) || IS_G4X(dev)) { ++ /* ++ * Set the domains we want to reset, then the reset bit (bit 0). ++ * Clear the reset bit after a while and wait for hardware status ++ * bit (bit 1) to be set ++ */ ++ pci_read_config_byte(dev->pdev, GDRST, &gdrst); ++ pci_write_config_byte(dev->pdev, GDRST, gdrst | flags | ((flags == GDRST_FULL) ? 0x1 : 0x0)); ++ udelay(50); ++ pci_write_config_byte(dev->pdev, GDRST, gdrst & 0xfe); ++ ++ /* ...we don't want to loop forever though, 500ms should be plenty */ ++ timeout = jiffies + msecs_to_jiffies(500); ++ do { ++ udelay(100); ++ pci_read_config_byte(dev->pdev, GDRST, &gdrst); ++ } while ((gdrst & 0x1) && time_after(timeout, jiffies)); ++ ++ if (gdrst & 0x1) { ++ WARN(true, "i915: Failed to reset chip\n"); ++ mutex_unlock(&dev->struct_mutex); ++ return -EIO; ++ } ++ } else { ++ DRM_ERROR("Error occurred. Don't know how to reset this chip.\n"); ++ return -ENODEV; ++ } ++ ++ /* Ok, now get things going again... */ ++ ++ /* ++ * Everything depends on having the GTT running, so we need to start ++ * there. Fortunately we don't need to do this unless we reset the ++ * chip at a PCI level. ++ * ++ * Next we need to restore the context, but we don't use those ++ * yet either... ++ * ++ * Ring buffer needs to be re-initialized in the KMS case, or if X ++ * was running at the time of the reset (i.e. we weren't VT ++ * switched away). ++ */ ++ if (drm_core_check_feature(dev, DRIVER_MODESET) || ++ !dev_priv->mm.suspended) { ++ drm_i915_ring_buffer_t *ring = &dev_priv->ring; ++ struct drm_gem_object *obj = ring->ring_obj; ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ dev_priv->mm.suspended = 0; ++ ++ /* Stop the ring if it's running. */ ++ I915_WRITE(PRB0_CTL, 0); ++ I915_WRITE(PRB0_TAIL, 0); ++ I915_WRITE(PRB0_HEAD, 0); ++ ++ /* Initialize the ring. */ ++ I915_WRITE(PRB0_START, obj_priv->gtt_offset); ++ I915_WRITE(PRB0_CTL, ++ ((obj->size - 4096) & RING_NR_PAGES) | ++ RING_NO_REPORT | ++ RING_VALID); ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ i915_kernel_lost_context(dev); ++ else { ++ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; ++ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; ++ ring->space = ring->head - (ring->tail + 8); ++ if (ring->space < 0) ++ ring->space += ring->Size; ++ } ++ ++ mutex_unlock(&dev->struct_mutex); ++ drm_irq_uninstall(dev); ++ drm_irq_install(dev); ++ mutex_lock(&dev->struct_mutex); ++ } ++ ++ /* ++ * Display needs restore too... ++ */ ++ if (need_display) ++ i915_restore_display(dev); ++ ++ mutex_unlock(&dev->struct_mutex); ++ return 0; ++} ++ ++ + static int __devinit + i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { +@@ -188,8 +317,8 @@ static struct drm_driver driver = { .master_create = i915_master_create, .master_destroy = i915_master_destroy, #if defined(CONFIG_DEBUG_FS) @@ -397404,11 +402857,40 @@ index fc4b68a..dbe568c 100644 #endif .gem_init_object = i915_gem_init_object, .gem_free_object = i915_gem_free_object, +@@ -231,6 +360,8 @@ static int __init i915_init(void) + { + driver.num_ioctls = i915_max_ioctl; + ++ i915_gem_shrinker_init(); ++ + /* + * If CONFIG_DRM_I915_KMS is set, default to KMS unless + * explicitly disabled with the module pararmeter. +@@ -257,6 +388,7 @@ static int __init i915_init(void) + + static void __exit i915_exit(void) + { ++ i915_gem_shrinker_exit(); + drm_exit(&driver); + } + diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h -index 5b4f87e..a0632f8 100644 +index 5b4f87e..b24b2d1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h -@@ -85,7 +85,6 @@ struct drm_i915_gem_phys_object { +@@ -48,6 +48,11 @@ enum pipe { + PIPE_B, + }; + ++enum plane { ++ PLANE_A = 0, ++ PLANE_B, ++}; ++ + #define I915_NUM_PIPE 2 + + /* Interface history: +@@ -85,7 +90,6 @@ struct drm_i915_gem_phys_object { }; typedef struct _drm_i915_ring_buffer { @@ -397416,7 +402898,31 @@ index 5b4f87e..a0632f8 100644 unsigned long Size; u8 *virtual_start; int head; -@@ -156,6 +155,7 @@ typedef struct drm_i915_private { +@@ -149,6 +153,23 @@ struct drm_i915_error_state { + struct timeval time; + }; + ++struct drm_i915_display_funcs { ++ void (*dpms)(struct drm_crtc *crtc, int mode); ++ bool (*fbc_enabled)(struct drm_crtc *crtc); ++ void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); ++ void (*disable_fbc)(struct drm_device *dev); ++ int (*get_display_clock_speed)(struct drm_device *dev); ++ int (*get_fifo_size)(struct drm_device *dev, int plane); ++ void (*update_wm)(struct drm_device *dev, int planea_clock, ++ int planeb_clock, int sr_hdisplay, int pixel_size); ++ /* clock updates for mode set */ ++ /* cursor updates */ ++ /* render clock increase/decrease */ ++ /* display clock increase/decrease */ ++ /* pll clock increase/decrease */ ++ /* clock gating init */ ++}; ++ + typedef struct drm_i915_private { + struct drm_device *dev; + +@@ -156,6 +177,7 @@ typedef struct drm_i915_private { void __iomem *regs; @@ -397424,7 +402930,50 @@ index 5b4f87e..a0632f8 100644 drm_i915_ring_buffer_t ring; drm_dma_handle_t *status_page_dmah; -@@ -311,7 +311,7 @@ typedef struct drm_i915_private { +@@ -198,10 +220,21 @@ typedef struct drm_i915_private { + unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; + int vblank_pipe; + ++ /* For hangcheck timer */ ++#define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ ++ struct timer_list hangcheck_timer; ++ int hangcheck_count; ++ uint32_t last_acthd; ++ + bool cursor_needs_physical; + + struct drm_mm vram; + ++ unsigned long cfb_size; ++ unsigned long cfb_pitch; ++ int cfb_fence; ++ int cfb_plane; ++ + int irq_enabled; + + struct intel_opregion opregion; +@@ -222,6 +255,8 @@ typedef struct drm_i915_private { + unsigned int edp_support:1; + int lvds_ssc_freq; + ++ struct notifier_block lid_notifier; ++ + int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ + struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ + int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ +@@ -234,7 +269,11 @@ typedef struct drm_i915_private { + struct work_struct error_work; + struct workqueue_struct *wq; + ++ /* Display functions */ ++ struct drm_i915_display_funcs display; ++ + /* Register state */ ++ bool suspended; + u8 saveLBB; + u32 saveDSPACNTR; + u32 saveDSPBCNTR; +@@ -311,7 +350,7 @@ typedef struct drm_i915_private { u32 saveIMR; u32 saveCACHE_MODE_0; u32 saveD_STATE; @@ -397433,7 +402982,32 @@ index 5b4f87e..a0632f8 100644 u32 saveMI_ARB_STATE; u32 saveSWF0[16]; u32 saveSWF1[16]; -@@ -443,6 +443,14 @@ typedef struct drm_i915_private { +@@ -350,6 +389,15 @@ typedef struct drm_i915_private { + int gtt_mtrr; + + /** ++ * Membership on list of all loaded devices, used to evict ++ * inactive buffers under memory pressure. ++ * ++ * Modifications should only be done whilst holding the ++ * shrink_list_lock spinlock. ++ */ ++ struct list_head shrink_list; ++ ++ /** + * List of objects currently involved in rendering from the + * ringbuffer. + * +@@ -432,7 +480,7 @@ typedef struct drm_i915_private { + * It prevents command submission from occuring and makes + * every pending request fail + */ +- int wedged; ++ atomic_t wedged; + + /** Bit 6 swizzling required for X tiling */ + uint32_t bit_6_swizzle_x; +@@ -443,6 +491,14 @@ typedef struct drm_i915_private { struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; } mm; struct sdvo_device_mapping sdvo_mappings[2]; @@ -397448,15 +403022,80 @@ index 5b4f87e..a0632f8 100644 } drm_i915_private_t; /** driver private structure attached to each drm_gem_object */ -@@ -575,6 +583,7 @@ enum intel_chip_family { +@@ -483,10 +539,7 @@ struct drm_i915_gem_object { + * This is the same as gtt_space->start + */ + uint32_t gtt_offset; +- /** +- * Required alignment for the object +- */ +- uint32_t gtt_alignment; ++ + /** + * Fake offset for use by mmap(2) + */ +@@ -533,6 +586,11 @@ struct drm_i915_gem_object { + * in an execbuffer object list. + */ + int in_execbuffer; ++ ++ /** ++ * Advice: are the backing pages purgeable? ++ */ ++ int madv; + }; + + /** +@@ -575,7 +633,10 @@ enum intel_chip_family { extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; +extern unsigned int i915_powersave; ++extern void i915_save_display(struct drm_device *dev); ++extern void i915_restore_display(struct drm_device *dev); extern int i915_master_create(struct drm_device *dev, struct drm_master *master); extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); -@@ -730,8 +739,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, + +@@ -595,8 +656,10 @@ extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, + extern int i915_emit_box(struct drm_device *dev, + struct drm_clip_rect *boxes, + int i, int DR1, int DR4); ++extern int i965_reset(struct drm_device *dev, u8 flags); + + /* i915_irq.c */ ++void i915_hangcheck_elapsed(unsigned long data); + extern int i915_irq_emit(struct drm_device *dev, void *data, + struct drm_file *file_priv); + extern int i915_irq_wait(struct drm_device *dev, void *data, +@@ -667,6 +730,8 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); ++int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); + int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, +@@ -686,6 +751,7 @@ int i915_gem_object_unbind(struct drm_gem_object *obj); + void i915_gem_release_mmap(struct drm_gem_object *obj); + void i915_gem_lastclose(struct drm_device *dev); + uint32_t i915_get_gem_seqno(struct drm_device *dev); ++bool i915_seqno_passed(uint32_t seq1, uint32_t seq2); + int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); + int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); + void i915_gem_retire_requests(struct drm_device *dev); +@@ -711,6 +777,9 @@ int i915_gem_object_get_pages(struct drm_gem_object *obj); + void i915_gem_object_put_pages(struct drm_gem_object *obj); + void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); + ++void i915_gem_shrinker_init(void); ++void i915_gem_shrinker_exit(void); ++ + /* i915_gem_tiling.c */ + void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); + void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); +@@ -730,8 +799,8 @@ void i915_gem_dump_object(struct drm_gem_object *obj, int len, void i915_dump_lru(struct drm_device *dev, const char *where); /* i915_debugfs.c */ @@ -397467,15 +403106,17 @@ index 5b4f87e..a0632f8 100644 /* i915_suspend.c */ extern int i915_save_state(struct drm_device *dev); -@@ -757,6 +766,7 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; } +@@ -757,6 +826,9 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; } /* modesetting */ extern void intel_modeset_init(struct drm_device *dev); extern void intel_modeset_cleanup(struct drm_device *dev); +extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); ++extern void i8xx_disable_fbc(struct drm_device *dev); ++extern void g4x_disable_fbc(struct drm_device *dev); /** * Lock test for when it's just for synchronization of ring access. -@@ -781,33 +791,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev); +@@ -781,33 +853,32 @@ extern void intel_modeset_cleanup(struct drm_device *dev); #define I915_VERBOSE 0 @@ -397529,7 +403170,7 @@ index 5b4f87e..a0632f8 100644 } while(0) /** -@@ -830,6 +839,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); +@@ -830,6 +901,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev); #define I915_GEM_HWS_INDEX 0x20 #define I915_BREADCRUMB_INDEX 0x21 @@ -397537,29 +403178,69 @@ index 5b4f87e..a0632f8 100644 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); #define IS_I830(dev) ((dev)->pci_device == 0x3577) -@@ -903,6 +913,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); +@@ -854,6 +926,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + (dev)->pci_device == 0x2E12 || \ + (dev)->pci_device == 0x2E22 || \ + (dev)->pci_device == 0x2E32 || \ ++ (dev)->pci_device == 0x2E42 || \ + (dev)->pci_device == 0x0042 || \ + (dev)->pci_device == 0x0046) + +@@ -866,6 +939,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + (dev)->pci_device == 0x2E12 || \ + (dev)->pci_device == 0x2E22 || \ + (dev)->pci_device == 0x2E32 || \ ++ (dev)->pci_device == 0x2E42 || \ + IS_GM45(dev)) + + #define IS_IGDG(dev) ((dev)->pci_device == 0xa001) +@@ -899,10 +973,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); + #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) + #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) + #define SUPPORTS_EDP(dev) (IS_IGDNG_M(dev)) +-#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) ++#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev) || IS_I965G(dev)) /* dsparb controlled by hw only */ #define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IGDNG(dev)) +#define HAS_FW_BLC(dev) (IS_I9XX(dev) || IS_G4X(dev) || IS_IGDNG(dev)) +#define HAS_PIPE_CXSR(dev) (IS_G4X(dev) || IS_IGDNG(dev)) ++#define I915_HAS_FBC(dev) (IS_MOBILE(dev) && (IS_I9XX(dev) || IS_I965G(dev))) + #define PRIMARY_RINGBUFFER_SIZE (128*1024) #endif diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c -index 80e5ba4..c673171 100644 +index 80e5ba4..40727d4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c -@@ -29,6 +29,7 @@ +@@ -29,6 +29,8 @@ #include "drm.h" #include "i915_drm.h" #include "i915_drv.h" ++#include "i915_trace.h" +#include "intel_drv.h" #include #include -@@ -111,7 +112,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, +@@ -47,11 +49,15 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); + static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, + unsigned alignment); + static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); +-static int i915_gem_evict_something(struct drm_device *dev); ++static int i915_gem_evict_something(struct drm_device *dev, int min_size); ++static int i915_gem_evict_from_inactive_list(struct drm_device *dev); + static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, + struct drm_i915_gem_pwrite *args, + struct drm_file *file_priv); + ++static LIST_HEAD(shrink_list); ++static DEFINE_SPINLOCK(shrink_list_lock); ++ + int i915_gem_do_init(struct drm_device *dev, unsigned long start, + unsigned long end) + { +@@ -111,7 +117,8 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_create *args = data; struct drm_gem_object *obj; @@ -397569,7 +403250,75 @@ index 80e5ba4..c673171 100644 args->size = roundup(args->size, PAGE_SIZE); -@@ -981,6 +983,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, +@@ -314,6 +321,45 @@ fail_unlock: + return ret; + } + ++static inline gfp_t ++i915_gem_object_get_page_gfp_mask (struct drm_gem_object *obj) ++{ ++ return mapping_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping); ++} ++ ++static inline void ++i915_gem_object_set_page_gfp_mask (struct drm_gem_object *obj, gfp_t gfp) ++{ ++ mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping, gfp); ++} ++ ++static int ++i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) ++{ ++ int ret; ++ ++ ret = i915_gem_object_get_pages(obj); ++ ++ /* If we've insufficient memory to map in the pages, attempt ++ * to make some space by throwing out some old buffers. ++ */ ++ if (ret == -ENOMEM) { ++ struct drm_device *dev = obj->dev; ++ gfp_t gfp; ++ ++ ret = i915_gem_evict_something(dev, obj->size); ++ if (ret) ++ return ret; ++ ++ gfp = i915_gem_object_get_page_gfp_mask(obj); ++ i915_gem_object_set_page_gfp_mask(obj, gfp & ~__GFP_NORETRY); ++ ret = i915_gem_object_get_pages(obj); ++ i915_gem_object_set_page_gfp_mask (obj, gfp); ++ } ++ ++ return ret; ++} ++ + /** + * This is the fallback shmem pread path, which allocates temporary storage + * in kernel space to copy_to_user into outside of the struct_mutex, so we +@@ -365,8 +411,8 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, + + mutex_lock(&dev->struct_mutex); + +- ret = i915_gem_object_get_pages(obj); +- if (ret != 0) ++ ret = i915_gem_object_get_pages_or_evict(obj); ++ if (ret) + goto fail_unlock; + + ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, +@@ -840,8 +886,8 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, + + mutex_lock(&dev->struct_mutex); + +- ret = i915_gem_object_get_pages(obj); +- if (ret != 0) ++ ret = i915_gem_object_get_pages_or_evict(obj); ++ if (ret) + goto fail_unlock; + + ret = i915_gem_object_set_to_cpu_domain(obj, 1); +@@ -981,6 +1027,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_set_domain *args = data; struct drm_gem_object *obj; @@ -397577,7 +403326,7 @@ index 80e5ba4..c673171 100644 uint32_t read_domains = args->read_domains; uint32_t write_domain = args->write_domain; int ret; -@@ -1004,15 +1007,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, +@@ -1004,15 +1051,17 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, obj = drm_gem_object_lookup(dev, file_priv, args->handle); if (obj == NULL) return -EBADF; @@ -397597,7 +403346,820 @@ index 80e5ba4..c673171 100644 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); /* Update the LRU on the fence for the CPU access that's -@@ -2776,6 +2781,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) +@@ -1150,28 +1199,22 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + /* Now bind it into the GTT if needed */ + mutex_lock(&dev->struct_mutex); + if (!obj_priv->gtt_space) { +- ret = i915_gem_object_bind_to_gtt(obj, obj_priv->gtt_alignment); +- if (ret) { +- mutex_unlock(&dev->struct_mutex); +- return VM_FAULT_SIGBUS; +- } +- +- ret = i915_gem_object_set_to_gtt_domain(obj, write); +- if (ret) { +- mutex_unlock(&dev->struct_mutex); +- return VM_FAULT_SIGBUS; +- } ++ ret = i915_gem_object_bind_to_gtt(obj, 0); ++ if (ret) ++ goto unlock; + + list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); ++ ++ ret = i915_gem_object_set_to_gtt_domain(obj, write); ++ if (ret) ++ goto unlock; + } + + /* Need a new fence register? */ + if (obj_priv->tiling_mode != I915_TILING_NONE) { + ret = i915_gem_object_get_fence_reg(obj); +- if (ret) { +- mutex_unlock(&dev->struct_mutex); +- return VM_FAULT_SIGBUS; +- } ++ if (ret) ++ goto unlock; + } + + pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + +@@ -1179,18 +1222,18 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) + + /* Finally, remap it using the new GTT offset */ + ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn); +- ++unlock: + mutex_unlock(&dev->struct_mutex); + + switch (ret) { ++ case 0: ++ case -ERESTARTSYS: ++ return VM_FAULT_NOPAGE; + case -ENOMEM: + case -EAGAIN: + return VM_FAULT_OOM; +- case -EFAULT: +- case -EINVAL: +- return VM_FAULT_SIGBUS; + default: +- return VM_FAULT_NOPAGE; ++ return VM_FAULT_SIGBUS; + } + } + +@@ -1383,6 +1426,14 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, + + obj_priv = obj->driver_private; + ++ if (obj_priv->madv != I915_MADV_WILLNEED) { ++ DRM_ERROR("Attempting to mmap a purgeable buffer\n"); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return -EINVAL; ++ } ++ ++ + if (!obj_priv->mmap_offset) { + ret = i915_gem_create_mmap_offset(obj); + if (ret) { +@@ -1394,22 +1445,12 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, + + args->offset = obj_priv->mmap_offset; + +- obj_priv->gtt_alignment = i915_gem_get_gtt_alignment(obj); +- +- /* Make sure the alignment is correct for fence regs etc */ +- if (obj_priv->agp_mem && +- (obj_priv->gtt_offset & (obj_priv->gtt_alignment - 1))) { +- drm_gem_object_unreference(obj); +- mutex_unlock(&dev->struct_mutex); +- return -EINVAL; +- } +- + /* + * Pull it into the GTT so that we have a page list (makes the + * initial fault faster and any subsequent flushing possible). + */ + if (!obj_priv->agp_mem) { +- ret = i915_gem_object_bind_to_gtt(obj, obj_priv->gtt_alignment); ++ ret = i915_gem_object_bind_to_gtt(obj, 0); + if (ret) { + drm_gem_object_unreference(obj); + mutex_unlock(&dev->struct_mutex); +@@ -1432,6 +1473,7 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) + int i; + + BUG_ON(obj_priv->pages_refcount == 0); ++ BUG_ON(obj_priv->madv == __I915_MADV_PURGED); + + if (--obj_priv->pages_refcount != 0) + return; +@@ -1439,13 +1481,21 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) + if (obj_priv->tiling_mode != I915_TILING_NONE) + i915_gem_object_save_bit_17_swizzle(obj); + +- for (i = 0; i < page_count; i++) +- if (obj_priv->pages[i] != NULL) { +- if (obj_priv->dirty) +- set_page_dirty(obj_priv->pages[i]); ++ if (obj_priv->madv == I915_MADV_DONTNEED) ++ obj_priv->dirty = 0; ++ ++ for (i = 0; i < page_count; i++) { ++ if (obj_priv->pages[i] == NULL) ++ break; ++ ++ if (obj_priv->dirty) ++ set_page_dirty(obj_priv->pages[i]); ++ ++ if (obj_priv->madv == I915_MADV_WILLNEED) + mark_page_accessed(obj_priv->pages[i]); +- page_cache_release(obj_priv->pages[i]); +- } ++ ++ page_cache_release(obj_priv->pages[i]); ++ } + obj_priv->dirty = 0; + + drm_free_large(obj_priv->pages); +@@ -1484,6 +1534,26 @@ i915_gem_object_move_to_flushing(struct drm_gem_object *obj) + obj_priv->last_rendering_seqno = 0; + } + ++/* Immediately discard the backing storage */ ++static void ++i915_gem_object_truncate(struct drm_gem_object *obj) ++{ ++ struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ struct inode *inode; ++ ++ inode = obj->filp->f_path.dentry->d_inode; ++ if (inode->i_op->truncate) ++ inode->i_op->truncate (inode); ++ ++ obj_priv->madv = __I915_MADV_PURGED; ++} ++ ++static inline int ++i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) ++{ ++ return obj_priv->madv == I915_MADV_DONTNEED; ++} ++ + static void + i915_gem_object_move_to_inactive(struct drm_gem_object *obj) + { +@@ -1572,15 +1642,24 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, + + if ((obj->write_domain & flush_domains) == + obj->write_domain) { ++ uint32_t old_write_domain = obj->write_domain; ++ + obj->write_domain = 0; + i915_gem_object_move_to_active(obj, seqno); ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + } + + } + +- if (was_empty && !dev_priv->mm.suspended) +- queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); ++ if (!dev_priv->mm.suspended) { ++ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); ++ if (was_empty) ++ queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); ++ } + return seqno; + } + +@@ -1618,6 +1697,8 @@ i915_gem_retire_request(struct drm_device *dev, + { + drm_i915_private_t *dev_priv = dev->dev_private; + ++ trace_i915_gem_request_retire(dev, request->seqno); ++ + /* Move any buffers on the active list that are no longer referenced + * by the ringbuffer to the flushing/inactive lists as appropriate. + */ +@@ -1666,7 +1747,7 @@ out: + /** + * Returns true if seq1 is later than seq2. + */ +-static int ++bool + i915_seqno_passed(uint32_t seq1, uint32_t seq2) + { + return (int32_t)(seq1 - seq2) >= 0; +@@ -1704,7 +1785,7 @@ i915_gem_retire_requests(struct drm_device *dev) + retiring_seqno = request->seqno; + + if (i915_seqno_passed(seqno, retiring_seqno) || +- dev_priv->mm.wedged) { ++ atomic_read(&dev_priv->mm.wedged)) { + i915_gem_retire_request(dev, request); + + list_del(&request->list); +@@ -1746,6 +1827,9 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) + + BUG_ON(seqno == 0); + ++ if (atomic_read(&dev_priv->mm.wedged)) ++ return -EIO; ++ + if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) { + if (IS_IGDNG(dev)) + ier = I915_READ(DEIER) | I915_READ(GTIER); +@@ -1758,16 +1842,20 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno) + i915_driver_irq_postinstall(dev); + } + ++ trace_i915_gem_request_wait_begin(dev, seqno); ++ + dev_priv->mm.waiting_gem_seqno = seqno; + i915_user_irq_get(dev); + ret = wait_event_interruptible(dev_priv->irq_queue, + i915_seqno_passed(i915_get_gem_seqno(dev), + seqno) || +- dev_priv->mm.wedged); ++ atomic_read(&dev_priv->mm.wedged)); + i915_user_irq_put(dev); + dev_priv->mm.waiting_gem_seqno = 0; ++ ++ trace_i915_gem_request_wait_end(dev, seqno); + } +- if (dev_priv->mm.wedged) ++ if (atomic_read(&dev_priv->mm.wedged)) + ret = -EIO; + + if (ret && ret != -ERESTARTSYS) +@@ -1798,6 +1886,8 @@ i915_gem_flush(struct drm_device *dev, + DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, + invalidate_domains, flush_domains); + #endif ++ trace_i915_gem_request_flush(dev, dev_priv->mm.next_gem_seqno, ++ invalidate_domains, flush_domains); + + if (flush_domains & I915_GEM_DOMAIN_CPU) + drm_agp_chipset_flush(dev); +@@ -1910,6 +2000,12 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + return -EINVAL; + } + ++ /* blow away mappings if mapped through GTT */ ++ i915_gem_release_mmap(obj); ++ ++ if (obj_priv->fence_reg != I915_FENCE_REG_NONE) ++ i915_gem_clear_fence_reg(obj); ++ + /* Move the object to the CPU domain to ensure that + * any possible CPU writes while it's not in the GTT + * are flushed when we go to remap it. This will +@@ -1923,21 +2019,16 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + return ret; + } + ++ BUG_ON(obj_priv->active); ++ + if (obj_priv->agp_mem != NULL) { + drm_unbind_agp(obj_priv->agp_mem); + drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); + obj_priv->agp_mem = NULL; + } + +- BUG_ON(obj_priv->active); +- +- /* blow away mappings if mapped through GTT */ +- i915_gem_release_mmap(obj); +- +- if (obj_priv->fence_reg != I915_FENCE_REG_NONE) +- i915_gem_clear_fence_reg(obj); +- + i915_gem_object_put_pages(obj); ++ BUG_ON(obj_priv->pages_refcount); + + if (obj_priv->gtt_space) { + atomic_dec(&dev->gtt_count); +@@ -1951,40 +2042,113 @@ i915_gem_object_unbind(struct drm_gem_object *obj) + if (!list_empty(&obj_priv->list)) + list_del_init(&obj_priv->list); + ++ if (i915_gem_object_is_purgeable(obj_priv)) ++ i915_gem_object_truncate(obj); ++ ++ trace_i915_gem_object_unbind(obj); ++ ++ return 0; ++} ++ ++static struct drm_gem_object * ++i915_gem_find_inactive_object(struct drm_device *dev, int min_size) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ struct drm_i915_gem_object *obj_priv; ++ struct drm_gem_object *best = NULL; ++ struct drm_gem_object *first = NULL; ++ ++ /* Try to find the smallest clean object */ ++ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { ++ struct drm_gem_object *obj = obj_priv->obj; ++ if (obj->size >= min_size) { ++ if ((!obj_priv->dirty || ++ i915_gem_object_is_purgeable(obj_priv)) && ++ (!best || obj->size < best->size)) { ++ best = obj; ++ if (best->size == min_size) ++ return best; ++ } ++ if (!first) ++ first = obj; ++ } ++ } ++ ++ return best ? best : first; ++} ++ ++static int ++i915_gem_evict_everything(struct drm_device *dev) ++{ ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ uint32_t seqno; ++ int ret; ++ bool lists_empty; ++ ++ spin_lock(&dev_priv->mm.active_list_lock); ++ lists_empty = (list_empty(&dev_priv->mm.inactive_list) && ++ list_empty(&dev_priv->mm.flushing_list) && ++ list_empty(&dev_priv->mm.active_list)); ++ spin_unlock(&dev_priv->mm.active_list_lock); ++ ++ if (lists_empty) ++ return -ENOSPC; ++ ++ /* Flush everything (on to the inactive lists) and evict */ ++ i915_gem_flush(dev, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); ++ seqno = i915_add_request(dev, NULL, I915_GEM_GPU_DOMAINS); ++ if (seqno == 0) ++ return -ENOMEM; ++ ++ ret = i915_wait_request(dev, seqno); ++ if (ret) ++ return ret; ++ ++ ret = i915_gem_evict_from_inactive_list(dev); ++ if (ret) ++ return ret; ++ ++ spin_lock(&dev_priv->mm.active_list_lock); ++ lists_empty = (list_empty(&dev_priv->mm.inactive_list) && ++ list_empty(&dev_priv->mm.flushing_list) && ++ list_empty(&dev_priv->mm.active_list)); ++ spin_unlock(&dev_priv->mm.active_list_lock); ++ BUG_ON(!lists_empty); ++ + return 0; + } + + static int +-i915_gem_evict_something(struct drm_device *dev) ++i915_gem_evict_something(struct drm_device *dev, int min_size) + { + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_gem_object *obj; +- struct drm_i915_gem_object *obj_priv; +- int ret = 0; ++ int ret; + + for (;;) { ++ i915_gem_retire_requests(dev); ++ + /* If there's an inactive buffer available now, grab it + * and be done. + */ +- if (!list_empty(&dev_priv->mm.inactive_list)) { +- obj_priv = list_first_entry(&dev_priv->mm.inactive_list, +- struct drm_i915_gem_object, +- list); +- obj = obj_priv->obj; +- BUG_ON(obj_priv->pin_count != 0); ++ obj = i915_gem_find_inactive_object(dev, min_size); ++ if (obj) { ++ struct drm_i915_gem_object *obj_priv; ++ + #if WATCH_LRU + DRM_INFO("%s: evicting %p\n", __func__, obj); + #endif ++ obj_priv = obj->driver_private; ++ BUG_ON(obj_priv->pin_count != 0); + BUG_ON(obj_priv->active); + + /* Wait on the rendering and unbind the buffer. */ +- ret = i915_gem_object_unbind(obj); +- break; ++ return i915_gem_object_unbind(obj); + } + + /* If we didn't get anything, but the ring is still processing +- * things, wait for one of those things to finish and hopefully +- * leave us a buffer to evict. ++ * things, wait for the next to finish and hopefully leave us ++ * a buffer to evict. + */ + if (!list_empty(&dev_priv->mm.request_list)) { + struct drm_i915_gem_request *request; +@@ -1995,16 +2159,9 @@ i915_gem_evict_something(struct drm_device *dev) + + ret = i915_wait_request(dev, request->seqno); + if (ret) +- break; ++ return ret; + +- /* if waiting caused an object to become inactive, +- * then loop around and wait for it. Otherwise, we +- * assume that waiting freed and unbound something, +- * so there should now be some space in the GTT +- */ +- if (!list_empty(&dev_priv->mm.inactive_list)) +- continue; +- break; ++ continue; + } + + /* If we didn't have anything on the request list but there +@@ -2013,46 +2170,44 @@ i915_gem_evict_something(struct drm_device *dev) + * will get moved to inactive. + */ + if (!list_empty(&dev_priv->mm.flushing_list)) { +- obj_priv = list_first_entry(&dev_priv->mm.flushing_list, +- struct drm_i915_gem_object, +- list); +- obj = obj_priv->obj; ++ struct drm_i915_gem_object *obj_priv; + +- i915_gem_flush(dev, +- obj->write_domain, +- obj->write_domain); +- i915_add_request(dev, NULL, obj->write_domain); ++ /* Find an object that we can immediately reuse */ ++ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { ++ obj = obj_priv->obj; ++ if (obj->size >= min_size) ++ break; + +- obj = NULL; +- continue; +- } ++ obj = NULL; ++ } + +- DRM_ERROR("inactive empty %d request empty %d " +- "flushing empty %d\n", +- list_empty(&dev_priv->mm.inactive_list), +- list_empty(&dev_priv->mm.request_list), +- list_empty(&dev_priv->mm.flushing_list)); +- /* If we didn't do any of the above, there's nothing to be done +- * and we just can't fit it in. +- */ +- return -ENOSPC; +- } +- return ret; +-} ++ if (obj != NULL) { ++ uint32_t seqno; + +-static int +-i915_gem_evict_everything(struct drm_device *dev) +-{ +- int ret; ++ i915_gem_flush(dev, ++ obj->write_domain, ++ obj->write_domain); ++ seqno = i915_add_request(dev, NULL, obj->write_domain); ++ if (seqno == 0) ++ return -ENOMEM; + +- for (;;) { +- ret = i915_gem_evict_something(dev); +- if (ret != 0) +- break; ++ ret = i915_wait_request(dev, seqno); ++ if (ret) ++ return ret; ++ ++ continue; ++ } ++ } ++ ++ /* If we didn't do any of the above, there's no single buffer ++ * large enough to swap out for the new one, so just evict ++ * everything and start again. (This should be rare.) ++ */ ++ if (!list_empty (&dev_priv->mm.inactive_list)) ++ return i915_gem_evict_from_inactive_list(dev); ++ else ++ return i915_gem_evict_everything(dev); + } +- if (ret == -ENOSPC) +- return 0; +- return ret; + } + + int +@@ -2075,7 +2230,6 @@ i915_gem_object_get_pages(struct drm_gem_object *obj) + BUG_ON(obj_priv->pages != NULL); + obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *)); + if (obj_priv->pages == NULL) { +- DRM_ERROR("Faled to allocate page list\n"); + obj_priv->pages_refcount--; + return -ENOMEM; + } +@@ -2086,7 +2240,6 @@ i915_gem_object_get_pages(struct drm_gem_object *obj) + page = read_mapping_page(mapping, i, NULL); + if (IS_ERR(page)) { + ret = PTR_ERR(page); +- DRM_ERROR("read_mapping_page failed: %d\n", ret); + i915_gem_object_put_pages(obj); + return ret; + } +@@ -2323,6 +2476,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) + else + i830_write_fence_reg(reg); + ++ trace_i915_gem_object_get_fence(obj, i, obj_priv->tiling_mode); ++ + return 0; + } + +@@ -2405,10 +2560,17 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + struct drm_mm_node *free_space; +- int page_count, ret; ++ bool retry_alloc = false; ++ int ret; + + if (dev_priv->mm.suspended) + return -EBUSY; ++ ++ if (obj_priv->madv != I915_MADV_WILLNEED) { ++ DRM_ERROR("Attempting to bind a purgeable object\n"); ++ return -EINVAL; ++ } ++ + if (alignment == 0) + alignment = i915_gem_get_gtt_alignment(obj); + if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { +@@ -2428,30 +2590,16 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + } + } + if (obj_priv->gtt_space == NULL) { +- bool lists_empty; +- + /* If the gtt is empty and we're still having trouble + * fitting our object in, we're out of memory. + */ + #if WATCH_LRU + DRM_INFO("%s: GTT full, evicting something\n", __func__); + #endif +- spin_lock(&dev_priv->mm.active_list_lock); +- lists_empty = (list_empty(&dev_priv->mm.inactive_list) && +- list_empty(&dev_priv->mm.flushing_list) && +- list_empty(&dev_priv->mm.active_list)); +- spin_unlock(&dev_priv->mm.active_list_lock); +- if (lists_empty) { +- DRM_ERROR("GTT full, but LRU list empty\n"); +- return -ENOSPC; +- } +- +- ret = i915_gem_evict_something(dev); +- if (ret != 0) { +- if (ret != -ERESTARTSYS) +- DRM_ERROR("Failed to evict a buffer %d\n", ret); ++ ret = i915_gem_evict_something(dev, obj->size); ++ if (ret) + return ret; +- } ++ + goto search_free; + } + +@@ -2459,27 +2607,56 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + DRM_INFO("Binding object of size %zd at 0x%08x\n", + obj->size, obj_priv->gtt_offset); + #endif ++ if (retry_alloc) { ++ i915_gem_object_set_page_gfp_mask (obj, ++ i915_gem_object_get_page_gfp_mask (obj) & ~__GFP_NORETRY); ++ } + ret = i915_gem_object_get_pages(obj); ++ if (retry_alloc) { ++ i915_gem_object_set_page_gfp_mask (obj, ++ i915_gem_object_get_page_gfp_mask (obj) | __GFP_NORETRY); ++ } + if (ret) { + drm_mm_put_block(obj_priv->gtt_space); + obj_priv->gtt_space = NULL; ++ ++ if (ret == -ENOMEM) { ++ /* first try to clear up some space from the GTT */ ++ ret = i915_gem_evict_something(dev, obj->size); ++ if (ret) { ++ /* now try to shrink everyone else */ ++ if (! retry_alloc) { ++ retry_alloc = true; ++ goto search_free; ++ } ++ ++ return ret; ++ } ++ ++ goto search_free; ++ } ++ + return ret; + } + +- page_count = obj->size / PAGE_SIZE; + /* Create an AGP memory structure pointing at our pages, and bind it + * into the GTT. + */ + obj_priv->agp_mem = drm_agp_bind_pages(dev, + obj_priv->pages, +- page_count, ++ obj->size >> PAGE_SHIFT, + obj_priv->gtt_offset, + obj_priv->agp_type); + if (obj_priv->agp_mem == NULL) { + i915_gem_object_put_pages(obj); + drm_mm_put_block(obj_priv->gtt_space); + obj_priv->gtt_space = NULL; +- return -ENOMEM; ++ ++ ret = i915_gem_evict_something(dev, obj->size); ++ if (ret) ++ return ret; ++ ++ goto search_free; + } + atomic_inc(&dev->gtt_count); + atomic_add(obj->size, &dev->gtt_memory); +@@ -2491,6 +2668,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) + BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); + BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); + ++ trace_i915_gem_object_bind(obj, obj_priv->gtt_offset); ++ + return 0; + } + +@@ -2506,15 +2685,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj) + if (obj_priv->pages == NULL) + return; + +- /* XXX: The 865 in particular appears to be weird in how it handles +- * cache flushing. We haven't figured it out, but the +- * clflush+agp_chipset_flush doesn't appear to successfully get the +- * data visible to the PGU, while wbinvd + agp_chipset_flush does. +- */ +- if (IS_I865G(obj->dev)) { +- wbinvd(); +- return; +- } ++ trace_i915_gem_object_clflush(obj); + + drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); + } +@@ -2525,21 +2696,29 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; + uint32_t seqno; ++ uint32_t old_write_domain; + + if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) + return; + + /* Queue the GPU write cache flushing we need. */ ++ old_write_domain = obj->write_domain; + i915_gem_flush(dev, 0, obj->write_domain); + seqno = i915_add_request(dev, NULL, obj->write_domain); + obj->write_domain = 0; + i915_gem_object_move_to_active(obj, seqno); ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + + /** Flushes the GTT write domain for the object if it's dirty. */ + static void + i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) + { ++ uint32_t old_write_domain; ++ + if (obj->write_domain != I915_GEM_DOMAIN_GTT) + return; + +@@ -2547,7 +2726,12 @@ i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) + * to it immediately go to main memory as far as we know, so there's + * no chipset flush. It also doesn't land in render cache. + */ ++ old_write_domain = obj->write_domain; + obj->write_domain = 0; ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + + /** Flushes the CPU write domain for the object if it's dirty. */ +@@ -2555,13 +2739,19 @@ static void + i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) + { + struct drm_device *dev = obj->dev; ++ uint32_t old_write_domain; + + if (obj->write_domain != I915_GEM_DOMAIN_CPU) + return; + + i915_gem_clflush_object(obj); + drm_agp_chipset_flush(dev); ++ old_write_domain = obj->write_domain; + obj->write_domain = 0; ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + + /** +@@ -2574,6 +2764,7 @@ int + i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) + { + struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ uint32_t old_write_domain, old_read_domains; + int ret; + + /* Not valid to be called on unbound objects. */ +@@ -2586,6 +2777,9 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) + if (ret != 0) + return ret; + ++ old_write_domain = obj->write_domain; ++ old_read_domains = obj->read_domains; ++ + /* If we're writing through the GTT domain, then CPU and GPU caches + * will need to be invalidated at next use. + */ +@@ -2604,6 +2798,10 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) + obj_priv->dirty = 1; + } + ++ trace_i915_gem_object_change_domain(obj, ++ old_read_domains, ++ old_write_domain); ++ + return 0; + } + +@@ -2616,6 +2814,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) + static int + i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) + { ++ uint32_t old_write_domain, old_read_domains; + int ret; + + i915_gem_object_flush_gpu_write_domain(obj); +@@ -2631,6 +2830,9 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) + */ + i915_gem_object_set_to_full_cpu_read_domain(obj); + ++ old_write_domain = obj->write_domain; ++ old_read_domains = obj->read_domains; ++ + /* Flush the CPU cache if it's still invalid. */ + if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { + i915_gem_clflush_object(obj); +@@ -2651,6 +2853,10 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) + obj->write_domain = I915_GEM_DOMAIN_CPU; + } + ++ trace_i915_gem_object_change_domain(obj, ++ old_read_domains, ++ old_write_domain); ++ + return 0; + } + +@@ -2772,10 +2978,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) + struct drm_i915_gem_object *obj_priv = obj->driver_private; + uint32_t invalidate_domains = 0; + uint32_t flush_domains = 0; ++ uint32_t old_read_domains; + BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU); BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU); @@ -397606,7 +404168,472 @@ index 80e5ba4..c673171 100644 #if WATCH_BUF DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", __func__, obj, -@@ -4093,7 +4100,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) +@@ -2816,6 +3025,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) + i915_gem_clflush_object(obj); + } + ++ old_read_domains = obj->read_domains; ++ + /* The actual obj->write_domain will be updated with + * pending_write_domain after we emit the accumulated flush for all + * of our domain changes in execbuffers (which clears objects' +@@ -2834,6 +3045,10 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) + obj->read_domains, obj->write_domain, + dev->invalidate_domains, dev->flush_domains); + #endif ++ ++ trace_i915_gem_object_change_domain(obj, ++ old_read_domains, ++ obj->write_domain); + } + + /** +@@ -2886,6 +3101,7 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, + uint64_t offset, uint64_t size) + { + struct drm_i915_gem_object *obj_priv = obj->driver_private; ++ uint32_t old_read_domains; + int i, ret; + + if (offset == 0 && size == obj->size) +@@ -2932,8 +3148,13 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, + */ + BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); + ++ old_read_domains = obj->read_domains; + obj->read_domains |= I915_GEM_DOMAIN_CPU; + ++ trace_i915_gem_object_change_domain(obj, ++ old_read_domains, ++ obj->write_domain); ++ + return 0; + } + +@@ -2977,6 +3198,21 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + } + target_obj_priv = target_obj->driver_private; + ++#if WATCH_RELOC ++ DRM_INFO("%s: obj %p offset %08x target %d " ++ "read %08x write %08x gtt %08x " ++ "presumed %08x delta %08x\n", ++ __func__, ++ obj, ++ (int) reloc->offset, ++ (int) reloc->target_handle, ++ (int) reloc->read_domains, ++ (int) reloc->write_domain, ++ (int) target_obj_priv->gtt_offset, ++ (int) reloc->presumed_offset, ++ reloc->delta); ++#endif ++ + /* The target buffer should have appeared before us in the + * exec_object list, so it should have a GTT space bound by now. + */ +@@ -2988,25 +3224,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + return -EINVAL; + } + +- if (reloc->offset > obj->size - 4) { +- DRM_ERROR("Relocation beyond object bounds: " +- "obj %p target %d offset %d size %d.\n", +- obj, reloc->target_handle, +- (int) reloc->offset, (int) obj->size); +- drm_gem_object_unreference(target_obj); +- i915_gem_object_unpin(obj); +- return -EINVAL; +- } +- if (reloc->offset & 3) { +- DRM_ERROR("Relocation not 4-byte aligned: " +- "obj %p target %d offset %d.\n", +- obj, reloc->target_handle, +- (int) reloc->offset); +- drm_gem_object_unreference(target_obj); +- i915_gem_object_unpin(obj); +- return -EINVAL; +- } +- ++ /* Validate that the target is in a valid r/w GPU domain */ + if (reloc->write_domain & I915_GEM_DOMAIN_CPU || + reloc->read_domains & I915_GEM_DOMAIN_CPU) { + DRM_ERROR("reloc with read/write CPU domains: " +@@ -3020,7 +3238,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + i915_gem_object_unpin(obj); + return -EINVAL; + } +- + if (reloc->write_domain && target_obj->pending_write_domain && + reloc->write_domain != target_obj->pending_write_domain) { + DRM_ERROR("Write domain conflict: " +@@ -3035,21 +3252,6 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + return -EINVAL; + } + +-#if WATCH_RELOC +- DRM_INFO("%s: obj %p offset %08x target %d " +- "read %08x write %08x gtt %08x " +- "presumed %08x delta %08x\n", +- __func__, +- obj, +- (int) reloc->offset, +- (int) reloc->target_handle, +- (int) reloc->read_domains, +- (int) reloc->write_domain, +- (int) target_obj_priv->gtt_offset, +- (int) reloc->presumed_offset, +- reloc->delta); +-#endif +- + target_obj->pending_read_domains |= reloc->read_domains; + target_obj->pending_write_domain |= reloc->write_domain; + +@@ -3061,6 +3263,37 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj, + continue; + } + ++ /* Check that the relocation address is valid... */ ++ if (reloc->offset > obj->size - 4) { ++ DRM_ERROR("Relocation beyond object bounds: " ++ "obj %p target %d offset %d size %d.\n", ++ obj, reloc->target_handle, ++ (int) reloc->offset, (int) obj->size); ++ drm_gem_object_unreference(target_obj); ++ i915_gem_object_unpin(obj); ++ return -EINVAL; ++ } ++ if (reloc->offset & 3) { ++ DRM_ERROR("Relocation not 4-byte aligned: " ++ "obj %p target %d offset %d.\n", ++ obj, reloc->target_handle, ++ (int) reloc->offset); ++ drm_gem_object_unreference(target_obj); ++ i915_gem_object_unpin(obj); ++ return -EINVAL; ++ } ++ ++ /* and points to somewhere within the target object. */ ++ if (reloc->delta >= target_obj->size) { ++ DRM_ERROR("Relocation beyond target object bounds: " ++ "obj %p target %d delta %d size %d.\n", ++ obj, reloc->target_handle, ++ (int) reloc->delta, (int) target_obj->size); ++ drm_gem_object_unreference(target_obj); ++ i915_gem_object_unpin(obj); ++ return -EINVAL; ++ } ++ + ret = i915_gem_object_set_to_gtt_domain(obj, 1); + if (ret != 0) { + drm_gem_object_unreference(target_obj); +@@ -3119,6 +3352,8 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev, + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; + exec_len = (uint32_t) exec->batch_len; + ++ trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno); ++ + count = nbox ? nbox : 1; + + for (i = 0; i < count; i++) { +@@ -3356,7 +3591,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + i915_verify_inactive(dev, __FILE__, __LINE__); + +- if (dev_priv->mm.wedged) { ++ if (atomic_read(&dev_priv->mm.wedged)) { + DRM_ERROR("Execbuf while wedged\n"); + mutex_unlock(&dev->struct_mutex); + ret = -EIO; +@@ -3414,8 +3649,23 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + /* error other than GTT full, or we've already tried again */ + if (ret != -ENOSPC || pin_tries >= 1) { +- if (ret != -ERESTARTSYS) +- DRM_ERROR("Failed to pin buffers %d\n", ret); ++ if (ret != -ERESTARTSYS) { ++ unsigned long long total_size = 0; ++ for (i = 0; i < args->buffer_count; i++) ++ total_size += object_list[i]->size; ++ DRM_ERROR("Failed to pin buffer %d of %d, total %llu bytes: %d\n", ++ pinned+1, args->buffer_count, ++ total_size, ret); ++ DRM_ERROR("%d objects [%d pinned], " ++ "%d object bytes [%d pinned], " ++ "%d/%d gtt bytes\n", ++ atomic_read(&dev->object_count), ++ atomic_read(&dev->pin_count), ++ atomic_read(&dev->object_memory), ++ atomic_read(&dev->pin_memory), ++ atomic_read(&dev->gtt_memory), ++ dev->gtt_total); ++ } + goto err; + } + +@@ -3426,7 +3676,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + /* evict everyone we can from the aperture */ + ret = i915_gem_evict_everything(dev); +- if (ret) ++ if (ret && ret != -ENOSPC) + goto err; + } + +@@ -3482,8 +3732,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, + + for (i = 0; i < args->buffer_count; i++) { + struct drm_gem_object *obj = object_list[i]; ++ uint32_t old_write_domain = obj->write_domain; + + obj->write_domain = obj->pending_write_domain; ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + + i915_verify_inactive(dev, __FILE__, __LINE__); +@@ -3600,11 +3854,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) + i915_verify_inactive(dev, __FILE__, __LINE__); + if (obj_priv->gtt_space == NULL) { + ret = i915_gem_object_bind_to_gtt(obj, alignment); +- if (ret != 0) { +- if (ret != -EBUSY && ret != -ERESTARTSYS) +- DRM_ERROR("Failure to bind: %d\n", ret); ++ if (ret) + return ret; +- } + } + /* + * Pre-965 chips need a fence register set up in order to +@@ -3684,6 +3935,13 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, + } + obj_priv = obj->driver_private; + ++ if (obj_priv->madv != I915_MADV_WILLNEED) { ++ DRM_ERROR("Attempting to pin a purgeable buffer\n"); ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ return -EINVAL; ++ } ++ + if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { + DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", + args->handle); +@@ -3796,6 +4054,56 @@ i915_gem_throttle_ioctl(struct drm_device *dev, void *data, + return i915_gem_ring_throttle(dev, file_priv); + } + ++int ++i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_i915_gem_madvise *args = data; ++ struct drm_gem_object *obj; ++ struct drm_i915_gem_object *obj_priv; ++ ++ switch (args->madv) { ++ case I915_MADV_DONTNEED: ++ case I915_MADV_WILLNEED: ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ obj = drm_gem_object_lookup(dev, file_priv, args->handle); ++ if (obj == NULL) { ++ DRM_ERROR("Bad handle in i915_gem_madvise_ioctl(): %d\n", ++ args->handle); ++ return -EBADF; ++ } ++ ++ mutex_lock(&dev->struct_mutex); ++ obj_priv = obj->driver_private; ++ ++ if (obj_priv->pin_count) { ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ DRM_ERROR("Attempted i915_gem_madvise_ioctl() on a pinned object\n"); ++ return -EINVAL; ++ } ++ ++ if (obj_priv->madv != __I915_MADV_PURGED) ++ obj_priv->madv = args->madv; ++ ++ /* if the object is no longer bound, discard its backing storage */ ++ if (i915_gem_object_is_purgeable(obj_priv) && ++ obj_priv->gtt_space == NULL) ++ i915_gem_object_truncate(obj); ++ ++ args->retained = obj_priv->madv != __I915_MADV_PURGED; ++ ++ drm_gem_object_unreference(obj); ++ mutex_unlock(&dev->struct_mutex); ++ ++ return 0; ++} ++ + int i915_gem_init_object(struct drm_gem_object *obj) + { + struct drm_i915_gem_object *obj_priv; +@@ -3820,6 +4128,9 @@ int i915_gem_init_object(struct drm_gem_object *obj) + obj_priv->fence_reg = I915_FENCE_REG_NONE; + INIT_LIST_HEAD(&obj_priv->list); + INIT_LIST_HEAD(&obj_priv->fence_list); ++ obj_priv->madv = I915_MADV_WILLNEED; ++ ++ trace_i915_gem_object_create(obj); + + return 0; + } +@@ -3829,6 +4140,8 @@ void i915_gem_free_object(struct drm_gem_object *obj) + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = obj->driver_private; + ++ trace_i915_gem_object_destroy(obj); ++ + while (obj_priv->pin_count > 0) + i915_gem_object_unpin(obj); + +@@ -3837,43 +4150,35 @@ void i915_gem_free_object(struct drm_gem_object *obj) + + i915_gem_object_unbind(obj); + +- i915_gem_free_mmap_offset(obj); ++ if (obj_priv->mmap_offset) ++ i915_gem_free_mmap_offset(obj); + + kfree(obj_priv->page_cpu_valid); + kfree(obj_priv->bit_17); + kfree(obj->driver_private); + } + +-/** Unbinds all objects that are on the given buffer list. */ ++/** Unbinds all inactive objects. */ + static int +-i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head) ++i915_gem_evict_from_inactive_list(struct drm_device *dev) + { +- struct drm_gem_object *obj; +- struct drm_i915_gem_object *obj_priv; +- int ret; ++ drm_i915_private_t *dev_priv = dev->dev_private; + +- while (!list_empty(head)) { +- obj_priv = list_first_entry(head, +- struct drm_i915_gem_object, +- list); +- obj = obj_priv->obj; ++ while (!list_empty(&dev_priv->mm.inactive_list)) { ++ struct drm_gem_object *obj; ++ int ret; + +- if (obj_priv->pin_count != 0) { +- DRM_ERROR("Pinned object in unbind list\n"); +- mutex_unlock(&dev->struct_mutex); +- return -EINVAL; +- } ++ obj = list_first_entry(&dev_priv->mm.inactive_list, ++ struct drm_i915_gem_object, ++ list)->obj; + + ret = i915_gem_object_unbind(obj); + if (ret != 0) { +- DRM_ERROR("Error unbinding object in LeaveVT: %d\n", +- ret); +- mutex_unlock(&dev->struct_mutex); ++ DRM_ERROR("Error unbinding object: %d\n", ret); + return ret; + } + } + +- + return 0; + } + +@@ -3895,6 +4200,7 @@ i915_gem_idle(struct drm_device *dev) + * We need to replace this with a semaphore, or something. + */ + dev_priv->mm.suspended = 1; ++ del_timer(&dev_priv->hangcheck_timer); + + /* Cancel the retire work handler, wait for it to finish if running + */ +@@ -3924,7 +4230,7 @@ i915_gem_idle(struct drm_device *dev) + if (last_seqno == cur_seqno) { + if (stuck++ > 100) { + DRM_ERROR("hardware wedged\n"); +- dev_priv->mm.wedged = 1; ++ atomic_set(&dev_priv->mm.wedged, 1); + DRM_WAKEUP(&dev_priv->irq_queue); + break; + } +@@ -3937,7 +4243,7 @@ i915_gem_idle(struct drm_device *dev) + i915_gem_retire_requests(dev); + + spin_lock(&dev_priv->mm.active_list_lock); +- if (!dev_priv->mm.wedged) { ++ if (!atomic_read(&dev_priv->mm.wedged)) { + /* Active and flushing should now be empty as we've + * waited for a sequence higher than any pending execbuffer + */ +@@ -3955,29 +4261,41 @@ i915_gem_idle(struct drm_device *dev) + * the GPU domains and just stuff them onto inactive. + */ + while (!list_empty(&dev_priv->mm.active_list)) { +- struct drm_i915_gem_object *obj_priv; ++ struct drm_gem_object *obj; ++ uint32_t old_write_domain; + +- obj_priv = list_first_entry(&dev_priv->mm.active_list, +- struct drm_i915_gem_object, +- list); +- obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; +- i915_gem_object_move_to_inactive(obj_priv->obj); ++ obj = list_first_entry(&dev_priv->mm.active_list, ++ struct drm_i915_gem_object, ++ list)->obj; ++ old_write_domain = obj->write_domain; ++ obj->write_domain &= ~I915_GEM_GPU_DOMAINS; ++ i915_gem_object_move_to_inactive(obj); ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + spin_unlock(&dev_priv->mm.active_list_lock); + + while (!list_empty(&dev_priv->mm.flushing_list)) { +- struct drm_i915_gem_object *obj_priv; ++ struct drm_gem_object *obj; ++ uint32_t old_write_domain; + +- obj_priv = list_first_entry(&dev_priv->mm.flushing_list, +- struct drm_i915_gem_object, +- list); +- obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS; +- i915_gem_object_move_to_inactive(obj_priv->obj); ++ obj = list_first_entry(&dev_priv->mm.flushing_list, ++ struct drm_i915_gem_object, ++ list)->obj; ++ old_write_domain = obj->write_domain; ++ obj->write_domain &= ~I915_GEM_GPU_DOMAINS; ++ i915_gem_object_move_to_inactive(obj); ++ ++ trace_i915_gem_object_change_domain(obj, ++ obj->read_domains, ++ old_write_domain); + } + + + /* Move all inactive buffers out of the GTT. */ +- ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list); ++ ret = i915_gem_evict_from_inactive_list(dev); + WARN_ON(!list_empty(&dev_priv->mm.inactive_list)); + if (ret) { + mutex_unlock(&dev->struct_mutex); +@@ -4093,7 +4411,6 @@ i915_gem_init_ringbuffer(struct drm_device *dev) /* Set up the kernel mapping for the ring. */ ring->Size = obj->size; @@ -397614,6 +404641,146 @@ index 80e5ba4..c673171 100644 ring->map.offset = dev->agp->base + obj_priv->gtt_offset; ring->map.size = obj->size; +@@ -4200,9 +4517,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + +- if (dev_priv->mm.wedged) { ++ if (atomic_read(&dev_priv->mm.wedged)) { + DRM_ERROR("Reenabling wedged hardware, good luck\n"); +- dev_priv->mm.wedged = 0; ++ atomic_set(&dev_priv->mm.wedged, 0); + } + + mutex_lock(&dev->struct_mutex); +@@ -4268,6 +4585,10 @@ i915_gem_load(struct drm_device *dev) + i915_gem_retire_work_handler); + dev_priv->mm.next_gem_seqno = 1; + ++ spin_lock(&shrink_list_lock); ++ list_add(&dev_priv->mm.shrink_list, &shrink_list); ++ spin_unlock(&shrink_list_lock); ++ + /* Old X drivers will take 0-2 for front, back, depth buffers */ + dev_priv->fence_reg_start = 3; + +@@ -4485,3 +4806,116 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv) + list_del_init(i915_file_priv->mm.request_list.next); + mutex_unlock(&dev->struct_mutex); + } ++ ++static int ++i915_gem_shrink(int nr_to_scan, gfp_t gfp_mask) ++{ ++ drm_i915_private_t *dev_priv, *next_dev; ++ struct drm_i915_gem_object *obj_priv, *next_obj; ++ int cnt = 0; ++ int would_deadlock = 1; ++ ++ /* "fast-path" to count number of available objects */ ++ if (nr_to_scan == 0) { ++ spin_lock(&shrink_list_lock); ++ list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { ++ struct drm_device *dev = dev_priv->dev; ++ ++ if (mutex_trylock(&dev->struct_mutex)) { ++ list_for_each_entry(obj_priv, ++ &dev_priv->mm.inactive_list, ++ list) ++ cnt++; ++ mutex_unlock(&dev->struct_mutex); ++ } ++ } ++ spin_unlock(&shrink_list_lock); ++ ++ return (cnt / 100) * sysctl_vfs_cache_pressure; ++ } ++ ++ spin_lock(&shrink_list_lock); ++ ++ /* first scan for clean buffers */ ++ list_for_each_entry_safe(dev_priv, next_dev, ++ &shrink_list, mm.shrink_list) { ++ struct drm_device *dev = dev_priv->dev; ++ ++ if (! mutex_trylock(&dev->struct_mutex)) ++ continue; ++ ++ spin_unlock(&shrink_list_lock); ++ ++ i915_gem_retire_requests(dev); ++ ++ list_for_each_entry_safe(obj_priv, next_obj, ++ &dev_priv->mm.inactive_list, ++ list) { ++ if (i915_gem_object_is_purgeable(obj_priv)) { ++ i915_gem_object_unbind(obj_priv->obj); ++ if (--nr_to_scan <= 0) ++ break; ++ } ++ } ++ ++ spin_lock(&shrink_list_lock); ++ mutex_unlock(&dev->struct_mutex); ++ ++ would_deadlock = 0; ++ ++ if (nr_to_scan <= 0) ++ break; ++ } ++ ++ /* second pass, evict/count anything still on the inactive list */ ++ list_for_each_entry_safe(dev_priv, next_dev, ++ &shrink_list, mm.shrink_list) { ++ struct drm_device *dev = dev_priv->dev; ++ ++ if (! mutex_trylock(&dev->struct_mutex)) ++ continue; ++ ++ spin_unlock(&shrink_list_lock); ++ ++ list_for_each_entry_safe(obj_priv, next_obj, ++ &dev_priv->mm.inactive_list, ++ list) { ++ if (nr_to_scan > 0) { ++ i915_gem_object_unbind(obj_priv->obj); ++ nr_to_scan--; ++ } else ++ cnt++; ++ } ++ ++ spin_lock(&shrink_list_lock); ++ mutex_unlock(&dev->struct_mutex); ++ ++ would_deadlock = 0; ++ } ++ ++ spin_unlock(&shrink_list_lock); ++ ++ if (would_deadlock) ++ return -1; ++ else if (cnt > 0) ++ return (cnt / 100) * sysctl_vfs_cache_pressure; ++ else ++ return 0; ++} ++ ++static struct shrinker shrinker = { ++ .shrink = i915_gem_shrink, ++ .seeks = DEFAULT_SEEKS, ++}; ++ ++__init void ++i915_gem_shrinker_init(void) ++{ ++ register_shrinker(&shrinker); ++} ++ ++__exit void ++i915_gem_shrinker_exit(void) ++{ ++ unregister_shrinker(&shrinker); ++} diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c deleted file mode 100644 index cb3b974..0000000 @@ -398196,10 +405363,94 @@ index a2d527b..200e398 100644 dev_priv->mm.bit_6_swizzle_y = swizzle_y; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c -index 7ebc84c..6c89f2f 100644 +index 7ebc84c..4dfeec7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -565,6 +565,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) +@@ -31,6 +31,7 @@ + #include "drm.h" + #include "i915_drm.h" + #include "i915_drv.h" ++#include "i915_trace.h" + #include "intel_drv.h" + + #define MAX_NOPID ((u32)~0) +@@ -279,7 +280,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) + } + + if (gt_iir & GT_USER_INTERRUPT) { +- dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); ++ u32 seqno = i915_get_gem_seqno(dev); ++ dev_priv->mm.irq_gem_seqno = seqno; ++ trace_i915_gem_request_complete(dev, seqno); + DRM_WAKEUP(&dev_priv->irq_queue); + } + +@@ -302,12 +305,25 @@ static void i915_error_work_func(struct work_struct *work) + drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, + error_work); + struct drm_device *dev = dev_priv->dev; +- char *event_string = "ERROR=1"; +- char *envp[] = { event_string, NULL }; ++ char *error_event[] = { "ERROR=1", NULL }; ++ char *reset_event[] = { "RESET=1", NULL }; ++ char *reset_done_event[] = { "ERROR=0", NULL }; + + DRM_DEBUG("generating error event\n"); +- +- kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); ++ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); ++ ++ if (atomic_read(&dev_priv->mm.wedged)) { ++ if (IS_I965G(dev)) { ++ DRM_DEBUG("resetting chip\n"); ++ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); ++ if (!i965_reset(dev, GDRST_RENDER)) { ++ atomic_set(&dev_priv->mm.wedged, 0); ++ kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event); ++ } ++ } else { ++ printk("reboot required\n"); ++ } ++ } + } + + /** +@@ -372,7 +388,7 @@ out: + * so userspace knows something bad happened (should trigger collection + * of a ring dump etc.). + */ +-static void i915_handle_error(struct drm_device *dev) ++static void i915_handle_error(struct drm_device *dev, bool wedged) + { + struct drm_i915_private *dev_priv = dev->dev_private; + u32 eir = I915_READ(EIR); +@@ -482,6 +498,16 @@ static void i915_handle_error(struct drm_device *dev) + I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); + } + ++ if (wedged) { ++ atomic_set(&dev_priv->mm.wedged, 1); ++ ++ /* ++ * Wakeup waiting processes so they don't hang ++ */ ++ printk("i915: Waking up sleeping processes\n"); ++ DRM_WAKEUP(&dev_priv->irq_queue); ++ } ++ + queue_work(dev_priv->wq, &dev_priv->error_work); + } + +@@ -527,7 +553,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) + pipeb_stats = I915_READ(PIPEBSTAT); + + if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) +- i915_handle_error(dev); ++ i915_handle_error(dev, false); + + /* + * Clear the PIPE(A|B)STAT regs before the IIR +@@ -565,6 +591,27 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); I915_READ(PORT_HOTPLUG_STAT); @@ -398227,8 +405478,118 @@ index 7ebc84c..6c89f2f 100644 } I915_WRITE(IIR, iir); +@@ -578,8 +625,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) + } + + if (iir & I915_USER_INTERRUPT) { +- dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); ++ u32 seqno = i915_get_gem_seqno(dev); ++ dev_priv->mm.irq_gem_seqno = seqno; ++ trace_i915_gem_request_complete(dev, seqno); + DRM_WAKEUP(&dev_priv->irq_queue); ++ dev_priv->hangcheck_count = 0; ++ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); + } + + if (pipea_stats & vblank_status) { +@@ -859,6 +910,52 @@ int i915_vblank_swap(struct drm_device *dev, void *data, + return -EINVAL; + } + ++struct drm_i915_gem_request *i915_get_tail_request(struct drm_device *dev) { ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ return list_entry(dev_priv->mm.request_list.prev, struct drm_i915_gem_request, list); ++} ++ ++/** ++ * This is called when the chip hasn't reported back with completed ++ * batchbuffers in a long time. The first time this is called we simply record ++ * ACTHD. If ACTHD hasn't changed by the time the hangcheck timer elapses ++ * again, we assume the chip is wedged and try to fix it. ++ */ ++void i915_hangcheck_elapsed(unsigned long data) ++{ ++ struct drm_device *dev = (struct drm_device *)data; ++ drm_i915_private_t *dev_priv = dev->dev_private; ++ uint32_t acthd; ++ ++ if (!IS_I965G(dev)) ++ acthd = I915_READ(ACTHD); ++ else ++ acthd = I915_READ(ACTHD_I965); ++ ++ /* If all work is done then ACTHD clearly hasn't advanced. */ ++ if (list_empty(&dev_priv->mm.request_list) || ++ i915_seqno_passed(i915_get_gem_seqno(dev), i915_get_tail_request(dev)->seqno)) { ++ dev_priv->hangcheck_count = 0; ++ return; ++ } ++ ++ if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { ++ DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); ++ i915_handle_error(dev, true); ++ return; ++ } ++ ++ /* Reset timer case chip hangs without another request being added */ ++ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD); ++ ++ if (acthd != dev_priv->last_acthd) ++ dev_priv->hangcheck_count = 0; ++ else ++ dev_priv->hangcheck_count++; ++ ++ dev_priv->last_acthd = acthd; ++} ++ + /* drm_dma.h hooks + */ + static void igdng_irq_preinstall(struct drm_device *dev) +diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c +index e4b4e88..2d51935 100644 +--- a/drivers/gpu/drm/i915/i915_opregion.c ++++ b/drivers/gpu/drm/i915/i915_opregion.c +@@ -148,6 +148,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) + struct drm_i915_private *dev_priv = dev->dev_private; + struct opregion_asle *asle = dev_priv->opregion.asle; + u32 blc_pwm_ctl, blc_pwm_ctl2; ++ u32 max_backlight, level, shift; + + if (!(bclp & ASLE_BCLP_VALID)) + return ASLE_BACKLIGHT_FAIL; +@@ -157,14 +158,25 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) + return ASLE_BACKLIGHT_FAIL; + + blc_pwm_ctl = I915_READ(BLC_PWM_CTL); +- blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; + blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); + +- if (blc_pwm_ctl2 & BLM_COMBINATION_MODE) ++ if (IS_I965G(dev) && (blc_pwm_ctl2 & BLM_COMBINATION_MODE)) + pci_write_config_dword(dev->pdev, PCI_LBPC, bclp); +- else +- I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1)); +- ++ else { ++ if (IS_IGD(dev)) { ++ blc_pwm_ctl &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); ++ max_backlight = (blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> ++ BACKLIGHT_MODULATION_FREQ_SHIFT; ++ shift = BACKLIGHT_DUTY_CYCLE_SHIFT + 1; ++ } else { ++ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; ++ max_backlight = ((blc_pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> ++ BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; ++ shift = BACKLIGHT_DUTY_CYCLE_SHIFT; ++ } ++ level = (bclp * max_backlight) / 255; ++ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | (level << shift)); ++ } + asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID; + + return 0; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h -index 2955083..3f79635 100644 +index 2955083..0466ddb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -30,6 +30,7 @@ @@ -398248,7 +405609,7 @@ index 2955083..3f79635 100644 #define GC_CLOCK_133_200 (0 << 0) #define GC_CLOCK_100_200 (1 << 0) #define GC_CLOCK_100_133 (2 << 0) -@@ -65,6 +66,25 @@ +@@ -65,7 +66,30 @@ #define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4) #define GC_DISPLAY_CLOCK_333_MHZ (4 << 4) #define GC_DISPLAY_CLOCK_MASK (7 << 4) @@ -398272,9 +405633,52 @@ index 2955083..3f79635 100644 +#define I915_GC_RENDER_CLOCK_200_MHZ (1 << 0) +#define I915_GC_RENDER_CLOCK_333_MHZ (4 << 0) #define LBB 0xf4 ++#define GDRST 0xc0 ++#define GDRST_FULL (0<<2) ++#define GDRST_RENDER (1<<2) ++#define GDRST_MEDIA (3<<2) /* VGA stuff */ -@@ -553,9 +573,118 @@ + +@@ -324,9 +348,37 @@ + #define FBC_CTL_PLANEA (0<<0) + #define FBC_CTL_PLANEB (1<<0) + #define FBC_FENCE_OFF 0x0321b ++#define FBC_TAG 0x03300 + + #define FBC_LL_SIZE (1536) + ++/* Framebuffer compression for GM45+ */ ++#define DPFC_CB_BASE 0x3200 ++#define DPFC_CONTROL 0x3208 ++#define DPFC_CTL_EN (1<<31) ++#define DPFC_CTL_PLANEA (0<<30) ++#define DPFC_CTL_PLANEB (1<<30) ++#define DPFC_CTL_FENCE_EN (1<<29) ++#define DPFC_SR_EN (1<<10) ++#define DPFC_CTL_LIMIT_1X (0<<6) ++#define DPFC_CTL_LIMIT_2X (1<<6) ++#define DPFC_CTL_LIMIT_4X (2<<6) ++#define DPFC_RECOMP_CTL 0x320c ++#define DPFC_RECOMP_STALL_EN (1<<27) ++#define DPFC_RECOMP_STALL_WM_SHIFT (16) ++#define DPFC_RECOMP_STALL_WM_MASK (0x07ff0000) ++#define DPFC_RECOMP_TIMER_COUNT_SHIFT (0) ++#define DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f) ++#define DPFC_STATUS 0x3210 ++#define DPFC_INVAL_SEG_SHIFT (16) ++#define DPFC_INVAL_SEG_MASK (0x07ff0000) ++#define DPFC_COMP_SEG_SHIFT (0) ++#define DPFC_COMP_SEG_MASK (0x000003ff) ++#define DPFC_STATUS2 0x3214 ++#define DPFC_FENCE_YOFF 0x3218 ++#define DPFC_CHICKEN 0x3224 ++#define DPFC_HT_MODIFY (1<<31) ++ + /* + * GPIO regs + */ +@@ -553,9 +605,118 @@ #define DPLLA_TEST_M_BYPASS (1 << 2) #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) #define D_STATE 0x6104 @@ -398396,7 +405800,7 @@ index 2955083..3f79635 100644 /* * Palette regs -@@ -683,6 +812,7 @@ +@@ -683,6 +844,7 @@ #define SDVOB_HOTPLUG_INT_EN (1 << 26) #define SDVOC_HOTPLUG_INT_EN (1 << 25) #define TV_HOTPLUG_INT_EN (1 << 18) @@ -398404,7 +405808,7 @@ index 2955083..3f79635 100644 #define CRT_HOTPLUG_INT_EN (1 << 9) #define CRT_HOTPLUG_FORCE_DETECT (1 << 3) #define CRT_HOTPLUG_ACTIVATION_PERIOD_32 (0 << 8) -@@ -717,6 +847,7 @@ +@@ -717,6 +879,7 @@ #define DPC_HOTPLUG_INT_STATUS (1 << 28) #define HDMID_HOTPLUG_INT_STATUS (1 << 27) #define DPD_HOTPLUG_INT_STATUS (1 << 27) @@ -398412,7 +405816,7 @@ index 2955083..3f79635 100644 #define CRT_HOTPLUG_INT_STATUS (1 << 11) #define TV_HOTPLUG_INT_STATUS (1 << 10) #define CRT_HOTPLUG_MONITOR_MASK (3 << 8) -@@ -1586,6 +1717,7 @@ +@@ -1586,6 +1749,7 @@ #define PIPECONF_PROGRESSIVE (0 << 21) #define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21) #define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21) @@ -398420,7 +405824,7 @@ index 2955083..3f79635 100644 #define PIPEASTAT 0x70024 #define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31) #define PIPE_CRC_ERROR_ENABLE (1UL<<29) -@@ -1733,6 +1865,7 @@ +@@ -1733,6 +1897,7 @@ #define DISPPLANE_NO_LINE_DOUBLE 0 #define DISPPLANE_STEREO_POLARITY_FIRST 0 #define DISPPLANE_STEREO_POLARITY_SECOND (1<<18) @@ -398428,7 +405832,16 @@ index 2955083..3f79635 100644 #define DISPPLANE_TILED (1<<10) #define DSPAADDR 0x70184 #define DSPASTRIDE 0x70188 -@@ -1913,6 +2046,9 @@ +@@ -1867,6 +2032,8 @@ + #define PF_ENABLE (1<<31) + #define PFA_WIN_SZ 0x68074 + #define PFB_WIN_SZ 0x68874 ++#define PFA_WIN_POS 0x68070 ++#define PFB_WIN_POS 0x68870 + + /* legacy palette */ + #define LGC_PALETTE_A 0x4a000 +@@ -1913,6 +2080,9 @@ #define GTIIR 0x44018 #define GTIER 0x4401c @@ -398439,20 +405852,243 @@ index 2955083..3f79635 100644 /* south display engine interrupt */ diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c -index 1d04e19..20d4d19 100644 +index 1d04e19..bd6d8d9 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c -@@ -461,7 +461,7 @@ int i915_save_state(struct drm_device *dev) +@@ -228,6 +228,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) - /* Clock gating state */ - dev_priv->saveD_STATE = I915_READ(D_STATE); + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return; ++ + /* Pipe & plane A info */ + dev_priv->savePIPEACONF = I915_READ(PIPEACONF); + dev_priv->savePIPEASRC = I915_READ(PIPEASRC); +@@ -285,6 +286,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) + dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); + return; + } ++ + static void i915_restore_modeset_reg(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +@@ -379,19 +381,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) + + return; + } +-int i915_save_state(struct drm_device *dev) ++ ++void i915_save_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int i; +- +- pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); +- +- /* Render Standby */ +- if (IS_I965G(dev) && IS_MOBILE(dev)) +- dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); +- +- /* Hardware status page */ +- dev_priv->saveHWS = I915_READ(HWS_PGA); + + /* Display arbitration control */ + dev_priv->saveDSPARB = I915_READ(DSPARB); +@@ -399,6 +392,7 @@ int i915_save_state(struct drm_device *dev) + /* This is only meaningful in non-KMS mode */ + /* Don't save them in KMS mode */ + i915_save_modeset_reg(dev); ++ + /* Cursor state */ + dev_priv->saveCURACNTR = I915_READ(CURACNTR); + dev_priv->saveCURAPOS = I915_READ(CURAPOS); +@@ -448,81 +442,22 @@ int i915_save_state(struct drm_device *dev) + dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2); + dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL); + +- /* Interrupt state */ +- dev_priv->saveIIR = I915_READ(IIR); +- dev_priv->saveIER = I915_READ(IER); +- dev_priv->saveIMR = I915_READ(IMR); +- + /* VGA state */ + dev_priv->saveVGA0 = I915_READ(VGA0); + dev_priv->saveVGA1 = I915_READ(VGA1); + dev_priv->saveVGA_PD = I915_READ(VGA_PD); + dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); + +- /* Clock gating state */ +- dev_priv->saveD_STATE = I915_READ(D_STATE); - dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS); -+ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); +- +- /* Cache mode state */ +- dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); +- +- /* Memory Arbitration state */ +- dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); +- +- /* Scratch space */ +- for (i = 0; i < 16; i++) { +- dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); +- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); +- } +- for (i = 0; i < 3; i++) +- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); +- +- /* Fences */ +- if (IS_I965G(dev)) { +- for (i = 0; i < 16; i++) +- dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); +- } else { +- for (i = 0; i < 8; i++) +- dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); +- +- if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) +- for (i = 0; i < 8; i++) +- dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); +- } + i915_save_vga(dev); +- +- return 0; + } - /* Cache mode state */ - dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); -@@ -588,7 +588,7 @@ int i915_restore_state(struct drm_device *dev) +-int i915_restore_state(struct drm_device *dev) ++void i915_restore_display(struct drm_device *dev) + { + struct drm_i915_private *dev_priv = dev->dev_private; +- int i; +- +- pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); +- +- /* Render Standby */ +- if (IS_I965G(dev) && IS_MOBILE(dev)) +- I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); +- +- /* Hardware status page */ +- I915_WRITE(HWS_PGA, dev_priv->saveHWS); + /* Display arbitration */ + I915_WRITE(DSPARB, dev_priv->saveDSPARB); + +- /* Fences */ +- if (IS_I965G(dev)) { +- for (i = 0; i < 16; i++) +- I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); +- } else { +- for (i = 0; i < 8; i++) +- I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); +- if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) +- for (i = 0; i < 8; i++) +- I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); +- } +- + /* Display port ratios (must be done before clock is set) */ + if (SUPPORTS_INTEGRATED_DP(dev)) { + I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); +@@ -534,9 +469,11 @@ int i915_restore_state(struct drm_device *dev) + I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); + I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); + } ++ + /* This is only meaningful in non-KMS mode */ + /* Don't restore them in KMS mode */ + i915_restore_modeset_reg(dev); ++ + /* Cursor state */ + I915_WRITE(CURAPOS, dev_priv->saveCURAPOS); + I915_WRITE(CURACNTR, dev_priv->saveCURACNTR); +@@ -586,9 +523,98 @@ int i915_restore_state(struct drm_device *dev) + I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); + DRM_UDELAY(150); + ++ i915_restore_vga(dev); ++} ++ ++int i915_save_state(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int i; ++ ++ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); ++ ++ /* Render Standby */ ++ if (IS_I965G(dev) && IS_MOBILE(dev)) ++ dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); ++ ++ /* Hardware status page */ ++ dev_priv->saveHWS = I915_READ(HWS_PGA); ++ ++ i915_save_display(dev); ++ ++ /* Interrupt state */ ++ dev_priv->saveIER = I915_READ(IER); ++ dev_priv->saveIMR = I915_READ(IMR); ++ ++ /* Clock gating state */ ++ dev_priv->saveD_STATE = I915_READ(D_STATE); ++ dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D); /* Not sure about this */ ++ ++ /* Cache mode state */ ++ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); ++ ++ /* Memory Arbitration state */ ++ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE); ++ ++ /* Scratch space */ ++ for (i = 0; i < 16; i++) { ++ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2)); ++ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2)); ++ } ++ for (i = 0; i < 3; i++) ++ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); ++ ++ /* Fences */ ++ if (IS_I965G(dev)) { ++ for (i = 0; i < 16; i++) ++ dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); ++ } else { ++ for (i = 0; i < 8; i++) ++ dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); ++ ++ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) ++ for (i = 0; i < 8; i++) ++ dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); ++ } ++ ++ return 0; ++} ++ ++int i915_restore_state(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ int i; ++ ++ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); ++ ++ /* Render Standby */ ++ if (IS_I965G(dev) && IS_MOBILE(dev)) ++ I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); ++ ++ /* Hardware status page */ ++ I915_WRITE(HWS_PGA, dev_priv->saveHWS); ++ ++ /* Fences */ ++ if (IS_I965G(dev)) { ++ for (i = 0; i < 16; i++) ++ I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); ++ } else { ++ for (i = 0; i < 8; i++) ++ I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); ++ if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) ++ for (i = 0; i < 8; i++) ++ I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); ++ } ++ ++ i915_restore_display(dev); ++ ++ /* Interrupt state */ ++ I915_WRITE (IER, dev_priv->saveIER); ++ I915_WRITE (IMR, dev_priv->saveIMR); ++ /* Clock gating state */ I915_WRITE (D_STATE, dev_priv->saveD_STATE); - I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS); @@ -398460,11 +406096,368 @@ index 1d04e19..20d4d19 100644 /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); +@@ -603,8 +629,6 @@ int i915_restore_state(struct drm_device *dev) + for (i = 0; i < 3; i++) + I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); + +- i915_restore_vga(dev); +- + return 0; + } + +diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h +new file mode 100644 +index 0000000..5567a40 +--- /dev/null ++++ b/drivers/gpu/drm/i915/i915_trace.h +@@ -0,0 +1,315 @@ ++#if !defined(_I915_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) ++#define _I915_TRACE_H_ ++ ++#include ++#include ++#include ++ ++#include ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM i915 ++#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) ++#define TRACE_INCLUDE_FILE i915_trace ++ ++/* object tracking */ ++ ++TRACE_EVENT(i915_gem_object_create, ++ ++ TP_PROTO(struct drm_gem_object *obj), ++ ++ TP_ARGS(obj), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ __field(u32, size) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ __entry->size = obj->size; ++ ), ++ ++ TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) ++); ++ ++TRACE_EVENT(i915_gem_object_bind, ++ ++ TP_PROTO(struct drm_gem_object *obj, u32 gtt_offset), ++ ++ TP_ARGS(obj, gtt_offset), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ __field(u32, gtt_offset) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ __entry->gtt_offset = gtt_offset; ++ ), ++ ++ TP_printk("obj=%p, gtt_offset=%08x", ++ __entry->obj, __entry->gtt_offset) ++); ++ ++TRACE_EVENT(i915_gem_object_clflush, ++ ++ TP_PROTO(struct drm_gem_object *obj), ++ ++ TP_ARGS(obj), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ ), ++ ++ TP_printk("obj=%p", __entry->obj) ++); ++ ++TRACE_EVENT(i915_gem_object_change_domain, ++ ++ TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), ++ ++ TP_ARGS(obj, old_read_domains, old_write_domain), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ __field(u32, read_domains) ++ __field(u32, write_domain) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ __entry->read_domains = obj->read_domains | (old_read_domains << 16); ++ __entry->write_domain = obj->write_domain | (old_write_domain << 16); ++ ), ++ ++ TP_printk("obj=%p, read=%04x, write=%04x", ++ __entry->obj, ++ __entry->read_domains, __entry->write_domain) ++); ++ ++TRACE_EVENT(i915_gem_object_get_fence, ++ ++ TP_PROTO(struct drm_gem_object *obj, int fence, int tiling_mode), ++ ++ TP_ARGS(obj, fence, tiling_mode), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ __field(int, fence) ++ __field(int, tiling_mode) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ __entry->fence = fence; ++ __entry->tiling_mode = tiling_mode; ++ ), ++ ++ TP_printk("obj=%p, fence=%d, tiling=%d", ++ __entry->obj, __entry->fence, __entry->tiling_mode) ++); ++ ++TRACE_EVENT(i915_gem_object_unbind, ++ ++ TP_PROTO(struct drm_gem_object *obj), ++ ++ TP_ARGS(obj), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ ), ++ ++ TP_printk("obj=%p", __entry->obj) ++); ++ ++TRACE_EVENT(i915_gem_object_destroy, ++ ++ TP_PROTO(struct drm_gem_object *obj), ++ ++ TP_ARGS(obj), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_gem_object *, obj) ++ ), ++ ++ TP_fast_assign( ++ __entry->obj = obj; ++ ), ++ ++ TP_printk("obj=%p", __entry->obj) ++); ++ ++/* batch tracing */ ++ ++TRACE_EVENT(i915_gem_request_submit, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno), ++ ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) ++); ++ ++TRACE_EVENT(i915_gem_request_flush, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno, ++ u32 flush_domains, u32 invalidate_domains), ++ ++ TP_ARGS(dev, seqno, flush_domains, invalidate_domains), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ __field(u32, flush_domains) ++ __field(u32, invalidate_domains) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ __entry->flush_domains = flush_domains; ++ __entry->invalidate_domains = invalidate_domains; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u, flush=%04x, invalidate=%04x", ++ __entry->dev, __entry->seqno, ++ __entry->flush_domains, __entry->invalidate_domains) ++); ++ ++ ++TRACE_EVENT(i915_gem_request_complete, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno), ++ ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) ++); ++ ++TRACE_EVENT(i915_gem_request_retire, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno), ++ ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) ++); ++ ++TRACE_EVENT(i915_gem_request_wait_begin, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno), ++ ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) ++); ++ ++TRACE_EVENT(i915_gem_request_wait_end, ++ ++ TP_PROTO(struct drm_device *dev, u32 seqno), ++ ++ TP_ARGS(dev, seqno), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ __field(u32, seqno) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ __entry->seqno = seqno; ++ ), ++ ++ TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) ++); ++ ++TRACE_EVENT(i915_ring_wait_begin, ++ ++ TP_PROTO(struct drm_device *dev), ++ ++ TP_ARGS(dev), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ ), ++ ++ TP_printk("dev=%p", __entry->dev) ++); ++ ++TRACE_EVENT(i915_ring_wait_end, ++ ++ TP_PROTO(struct drm_device *dev), ++ ++ TP_ARGS(dev), ++ ++ TP_STRUCT__entry( ++ __field(struct drm_device *, dev) ++ ), ++ ++ TP_fast_assign( ++ __entry->dev = dev; ++ ), ++ ++ TP_printk("dev=%p", __entry->dev) ++); ++ ++#endif /* _I915_TRACE_H_ */ ++ ++/* This part must be outside protection */ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/i915 ++#include +diff --git a/drivers/gpu/drm/i915/i915_trace_points.c b/drivers/gpu/drm/i915/i915_trace_points.c +new file mode 100644 +index 0000000..ead876e +--- /dev/null ++++ b/drivers/gpu/drm/i915/i915_trace_points.c +@@ -0,0 +1,11 @@ ++/* ++ * Copyright © 2009 Intel Corporation ++ * ++ * Authors: ++ * Chris Wilson ++ */ ++ ++#include "i915_drv.h" ++ ++#define CREATE_TRACE_POINTS ++#include "i915_trace.h" diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c -index f806fcc..1e28c16 100644 +index f806fcc..4337414 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c -@@ -355,8 +355,14 @@ parse_driver_features(struct drm_i915_private *dev_priv, +@@ -217,6 +217,9 @@ parse_general_features(struct drm_i915_private *dev_priv, + if (IS_I85X(dev_priv->dev)) + dev_priv->lvds_ssc_freq = + general->ssc_freq ? 66 : 48; ++ else if (IS_IGDNG(dev_priv->dev)) ++ dev_priv->lvds_ssc_freq = ++ general->ssc_freq ? 100 : 120; + else + dev_priv->lvds_ssc_freq = + general->ssc_freq ? 100 : 96; +@@ -355,8 +358,14 @@ parse_driver_features(struct drm_i915_private *dev_priv, } driver = find_section(bdb, BDB_DRIVER_FEATURES); @@ -398481,7 +406474,7 @@ index f806fcc..1e28c16 100644 /** diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c -index 590f81c..88814fa 100644 +index 590f81c..212e227 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -64,6 +64,34 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode) @@ -398519,11 +406512,45 @@ index 590f81c..88814fa 100644 } static int intel_crt_mode_valid(struct drm_connector *connector, +@@ -151,13 +179,10 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; + struct drm_i915_private *dev_priv = dev->dev_private; +- u32 adpa, temp; ++ u32 adpa; + bool ret; + +- temp = adpa = I915_READ(PCH_ADPA); +- +- adpa &= ~ADPA_DAC_ENABLE; +- I915_WRITE(PCH_ADPA, adpa); ++ adpa = I915_READ(PCH_ADPA); + + adpa &= ~ADPA_CRT_HOTPLUG_MASK; + +@@ -184,8 +209,6 @@ static bool intel_igdng_crt_detect_hotplug(struct drm_connector *connector) + else + ret = false; + +- /* restore origin register */ +- I915_WRITE(PCH_ADPA, temp); + return ret; + } + diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 748ed50..0227b16 100644 +index 748ed50..93ff6c0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c -@@ -38,6 +38,7 @@ +@@ -24,6 +24,8 @@ + * Eric Anholt + */ + ++#include ++#include + #include + #include + #include "drmP.h" +@@ -38,6 +40,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type); static void intel_update_watermarks(struct drm_device *dev); @@ -398531,7 +406558,7 @@ index 748ed50..0227b16 100644 typedef struct { /* given values */ -@@ -67,6 +68,8 @@ struct intel_limit { +@@ -67,6 +70,8 @@ struct intel_limit { intel_p2_t p2; bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, int, int, intel_clock_t *); @@ -398540,7 +406567,7 @@ index 748ed50..0227b16 100644 }; #define I8XX_DOT_MIN 25000 -@@ -261,6 +264,9 @@ static bool +@@ -261,6 +266,9 @@ static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); static bool @@ -398550,7 +406577,7 @@ index 748ed50..0227b16 100644 intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock); static bool -@@ -286,6 +292,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = { +@@ -286,6 +294,7 @@ static const intel_limit_t intel_limits_i8xx_dvo = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, .find_pll = intel_find_best_PLL, @@ -398558,7 +406585,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_i8xx_lvds = { -@@ -300,6 +307,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = { +@@ -300,6 +309,7 @@ static const intel_limit_t intel_limits_i8xx_lvds = { .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, @@ -398566,7 +406593,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_i9xx_sdvo = { -@@ -314,6 +322,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { +@@ -314,6 +324,7 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, @@ -398574,7 +406601,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_i9xx_lvds = { -@@ -331,6 +340,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = { +@@ -331,6 +342,7 @@ static const intel_limit_t intel_limits_i9xx_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, .find_pll = intel_find_best_PLL, @@ -398582,7 +406609,7 @@ index 748ed50..0227b16 100644 }; /* below parameter and function is for G4X Chipset Family*/ -@@ -348,6 +358,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = { +@@ -348,6 +360,7 @@ static const intel_limit_t intel_limits_g4x_sdvo = { .p2_fast = G4X_P2_SDVO_FAST }, .find_pll = intel_g4x_find_best_PLL, @@ -398590,7 +406617,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_g4x_hdmi = { -@@ -364,6 +375,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = { +@@ -364,6 +377,7 @@ static const intel_limit_t intel_limits_g4x_hdmi = { .p2_fast = G4X_P2_HDMI_DAC_FAST }, .find_pll = intel_g4x_find_best_PLL, @@ -398598,7 +406625,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_g4x_single_channel_lvds = { -@@ -388,6 +400,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { +@@ -388,6 +402,7 @@ static const intel_limit_t intel_limits_g4x_single_channel_lvds = { .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, @@ -398606,7 +406633,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { -@@ -412,6 +425,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { +@@ -412,6 +427,7 @@ static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST }, .find_pll = intel_g4x_find_best_PLL, @@ -398614,7 +406641,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_g4x_display_port = { -@@ -449,6 +463,7 @@ static const intel_limit_t intel_limits_igd_sdvo = { +@@ -449,6 +465,7 @@ static const intel_limit_t intel_limits_igd_sdvo = { .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, .find_pll = intel_find_best_PLL, @@ -398622,7 +406649,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_igd_lvds = { -@@ -464,6 +479,7 @@ static const intel_limit_t intel_limits_igd_lvds = { +@@ -464,6 +481,7 @@ static const intel_limit_t intel_limits_igd_lvds = { .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, .find_pll = intel_find_best_PLL, @@ -398630,7 +406657,7 @@ index 748ed50..0227b16 100644 }; static const intel_limit_t intel_limits_igdng_sdvo = { -@@ -688,15 +704,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +@@ -688,15 +706,16 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, memset (best_clock, 0, sizeof (*best_clock)); @@ -398656,7 +406683,7 @@ index 748ed50..0227b16 100644 int this_err; intel_clock(dev, refclk, &clock); -@@ -717,6 +734,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +@@ -717,6 +736,46 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, return (err != target); } @@ -398703,7 +406730,7 @@ index 748ed50..0227b16 100644 static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int target, int refclk, intel_clock_t *best_clock) -@@ -747,7 +804,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +@@ -747,7 +806,7 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, max_n = limit->n.max; /* based on hardware requriment prefer smaller n to precision */ for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { @@ -398712,7 +406739,16 @@ index 748ed50..0227b16 100644 for (clock.m1 = limit->m1.max; clock.m1 >= limit->m1.min; clock.m1--) { for (clock.m2 = limit->m2.max; -@@ -832,15 +889,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, +@@ -818,7 +877,7 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, + refclk, best_clock); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { +- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == ++ if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP) + clock.p2 = limit->p2.p2_fast; + else +@@ -832,15 +891,14 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, memset(best_clock, 0, sizeof(*best_clock)); max_n = limit->n.max; @@ -398736,7 +406772,283 @@ index 748ed50..0227b16 100644 int this_err; intel_clock(dev, refclk, &clock); -@@ -1008,6 +1064,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, +@@ -896,6 +954,241 @@ intel_wait_for_vblank(struct drm_device *dev) + mdelay(20); + } + ++/* Parameters have changed, update FBC info */ ++static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb = crtc->fb; ++ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); ++ struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int plane, i; ++ u32 fbc_ctl, fbc_ctl2; ++ ++ dev_priv->cfb_pitch = dev_priv->cfb_size / FBC_LL_SIZE; ++ ++ if (fb->pitch < dev_priv->cfb_pitch) ++ dev_priv->cfb_pitch = fb->pitch; ++ ++ /* FBC_CTL wants 64B units */ ++ dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; ++ dev_priv->cfb_fence = obj_priv->fence_reg; ++ dev_priv->cfb_plane = intel_crtc->plane; ++ plane = dev_priv->cfb_plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; ++ ++ /* Clear old tags */ ++ for (i = 0; i < (FBC_LL_SIZE / 32) + 1; i++) ++ I915_WRITE(FBC_TAG + (i * 4), 0); ++ ++ /* Set it up... */ ++ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | plane; ++ if (obj_priv->tiling_mode != I915_TILING_NONE) ++ fbc_ctl2 |= FBC_CTL_CPU_FENCE; ++ I915_WRITE(FBC_CONTROL2, fbc_ctl2); ++ I915_WRITE(FBC_FENCE_OFF, crtc->y); ++ ++ /* enable it... */ ++ fbc_ctl = FBC_CTL_EN | FBC_CTL_PERIODIC; ++ fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; ++ fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; ++ if (obj_priv->tiling_mode != I915_TILING_NONE) ++ fbc_ctl |= dev_priv->cfb_fence; ++ I915_WRITE(FBC_CONTROL, fbc_ctl); ++ ++ DRM_DEBUG("enabled FBC, pitch %ld, yoff %d, plane %d, ", ++ dev_priv->cfb_pitch, crtc->y, dev_priv->cfb_plane); ++} ++ ++void i8xx_disable_fbc(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 fbc_ctl; ++ ++ if (!I915_HAS_FBC(dev)) ++ return; ++ ++ /* Disable compression */ ++ fbc_ctl = I915_READ(FBC_CONTROL); ++ fbc_ctl &= ~FBC_CTL_EN; ++ I915_WRITE(FBC_CONTROL, fbc_ctl); ++ ++ /* Wait for compressing bit to clear */ ++ while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) ++ ; /* nothing */ ++ ++ intel_wait_for_vblank(dev); ++ ++ DRM_DEBUG("disabled FBC\n"); ++} ++ ++static bool i8xx_fbc_enabled(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ return I915_READ(FBC_CONTROL) & FBC_CTL_EN; ++} ++ ++static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb = crtc->fb; ++ struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); ++ struct drm_i915_gem_object *obj_priv = intel_fb->obj->driver_private; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : ++ DPFC_CTL_PLANEB); ++ unsigned long stall_watermark = 200; ++ u32 dpfc_ctl; ++ ++ dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; ++ dev_priv->cfb_fence = obj_priv->fence_reg; ++ dev_priv->cfb_plane = intel_crtc->plane; ++ ++ dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; ++ if (obj_priv->tiling_mode != I915_TILING_NONE) { ++ dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->cfb_fence; ++ I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); ++ } else { ++ I915_WRITE(DPFC_CHICKEN, ~DPFC_HT_MODIFY); ++ } ++ ++ I915_WRITE(DPFC_CONTROL, dpfc_ctl); ++ I915_WRITE(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | ++ (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | ++ (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); ++ I915_WRITE(DPFC_FENCE_YOFF, crtc->y); ++ ++ /* enable it... */ ++ I915_WRITE(DPFC_CONTROL, I915_READ(DPFC_CONTROL) | DPFC_CTL_EN); ++ ++ DRM_DEBUG("enabled fbc on plane %d\n", intel_crtc->plane); ++} ++ ++void g4x_disable_fbc(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ u32 dpfc_ctl; ++ ++ /* Disable compression */ ++ dpfc_ctl = I915_READ(DPFC_CONTROL); ++ dpfc_ctl &= ~DPFC_CTL_EN; ++ I915_WRITE(DPFC_CONTROL, dpfc_ctl); ++ intel_wait_for_vblank(dev); ++ ++ DRM_DEBUG("disabled FBC\n"); ++} ++ ++static bool g4x_fbc_enabled(struct drm_crtc *crtc) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN; ++} ++ ++/** ++ * intel_update_fbc - enable/disable FBC as needed ++ * @crtc: CRTC to point the compressor at ++ * @mode: mode in use ++ * ++ * Set up the framebuffer compression hardware at mode set time. We ++ * enable it if possible: ++ * - plane A only (on pre-965) ++ * - no pixel mulitply/line duplication ++ * - no alpha buffer discard ++ * - no dual wide ++ * - framebuffer <= 2048 in width, 1536 in height ++ * ++ * We can't assume that any compression will take place (worst case), ++ * so the compressed buffer has to be the same size as the uncompressed ++ * one. It also must reside (along with the line length buffer) in ++ * stolen memory. ++ * ++ * We need to enable/disable FBC on a global basis. ++ */ ++static void intel_update_fbc(struct drm_crtc *crtc, ++ struct drm_display_mode *mode) ++{ ++ struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ struct drm_framebuffer *fb = crtc->fb; ++ struct intel_framebuffer *intel_fb; ++ struct drm_i915_gem_object *obj_priv; ++ struct intel_crtc *intel_crtc = to_intel_crtc(crtc); ++ int plane = intel_crtc->plane; ++ ++ if (!i915_powersave) ++ return; ++ ++ if (!dev_priv->display.fbc_enabled || ++ !dev_priv->display.enable_fbc || ++ !dev_priv->display.disable_fbc) ++ return; ++ ++ if (!crtc->fb) ++ return; ++ ++ intel_fb = to_intel_framebuffer(fb); ++ obj_priv = intel_fb->obj->driver_private; ++ ++ /* ++ * If FBC is already on, we just have to verify that we can ++ * keep it that way... ++ * Need to disable if: ++ * - changing FBC params (stride, fence, mode) ++ * - new fb is too large to fit in compressed buffer ++ * - going to an unsupported config (interlace, pixel multiply, etc.) ++ */ ++ if (intel_fb->obj->size > dev_priv->cfb_size) { ++ DRM_DEBUG("framebuffer too large, disabling compression\n"); ++ goto out_disable; ++ } ++ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) || ++ (mode->flags & DRM_MODE_FLAG_DBLSCAN)) { ++ DRM_DEBUG("mode incompatible with compression, disabling\n"); ++ goto out_disable; ++ } ++ if ((mode->hdisplay > 2048) || ++ (mode->vdisplay > 1536)) { ++ DRM_DEBUG("mode too large for compression, disabling\n"); ++ goto out_disable; ++ } ++ if ((IS_I915GM(dev) || IS_I945GM(dev)) && plane != 0) { ++ DRM_DEBUG("plane not 0, disabling compression\n"); ++ goto out_disable; ++ } ++ if (obj_priv->tiling_mode != I915_TILING_X) { ++ DRM_DEBUG("framebuffer not tiled, disabling compression\n"); ++ goto out_disable; ++ } ++ ++ if (dev_priv->display.fbc_enabled(crtc)) { ++ /* We can re-enable it in this case, but need to update pitch */ ++ if (fb->pitch > dev_priv->cfb_pitch) ++ dev_priv->display.disable_fbc(dev); ++ if (obj_priv->fence_reg != dev_priv->cfb_fence) ++ dev_priv->display.disable_fbc(dev); ++ if (plane != dev_priv->cfb_plane) ++ dev_priv->display.disable_fbc(dev); ++ } ++ ++ if (!dev_priv->display.fbc_enabled(crtc)) { ++ /* Now try to turn it back on if possible */ ++ dev_priv->display.enable_fbc(crtc, 500); ++ } ++ ++ return; ++ ++out_disable: ++ DRM_DEBUG("unsupported config, disabling FBC\n"); ++ /* Multiple disables should be harmless */ ++ if (dev_priv->display.fbc_enabled(crtc)) ++ dev_priv->display.disable_fbc(dev); ++} ++ + static int + intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) +@@ -908,12 +1201,13 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_i915_gem_object *obj_priv; + struct drm_gem_object *obj; + int pipe = intel_crtc->pipe; ++ int plane = intel_crtc->plane; + unsigned long Start, Offset; +- int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR); +- int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); +- int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; +- int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF); +- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; ++ int dspbase = (plane == 0 ? DSPAADDR : DSPBADDR); ++ int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); ++ int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; ++ int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); ++ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; + u32 dspcntr, alignment; + int ret; + +@@ -923,12 +1217,12 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + return 0; + } + +- switch (pipe) { ++ switch (plane) { + case 0: + case 1: + break; + default: +- DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); ++ DRM_ERROR("Can't update plane %d in SAREA\n", plane); + return -EINVAL; + } + +@@ -1008,6 +1302,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, dspcntr &= ~DISPPLANE_TILED; } @@ -398747,7 +407059,14 @@ index 748ed50..0227b16 100644 I915_WRITE(dspcntr_reg, dspcntr); Start = obj_priv->gtt_offset; -@@ -1030,8 +1090,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, +@@ -1026,12 +1324,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + I915_READ(dspbase); + } + ++ if ((IS_I965G(dev) || plane == 0)) ++ intel_update_fbc(crtc, &crtc->mode); ++ + intel_wait_for_vblank(dev); if (old_fb) { intel_fb = to_intel_framebuffer(old_fb); @@ -398759,16 +407078,89 @@ index 748ed50..0227b16 100644 mutex_unlock(&dev->struct_mutex); if (!dev->primary->master) -@@ -1581,6 +1644,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) - else - i9xx_crtc_dpms(crtc, mode); +@@ -1154,6 +1458,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF; + int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1; + int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ; ++ int pf_win_pos = (pipe == 0) ? PFA_WIN_POS : PFB_WIN_POS; + int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; +@@ -1205,6 +1510,19 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode) + } + } -+ intel_crtc->dpms_mode = mode; ++ /* Enable panel fitting for LVDS */ ++ if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { ++ temp = I915_READ(pf_ctl_reg); ++ I915_WRITE(pf_ctl_reg, temp | PF_ENABLE); + ++ /* currently full aspect */ ++ I915_WRITE(pf_win_pos, 0); ++ ++ I915_WRITE(pf_win_size, ++ (dev_priv->panel_fixed_mode->hdisplay << 16) | ++ (dev_priv->panel_fixed_mode->vdisplay)); ++ } ++ + /* Enable CPU pipe */ + temp = I915_READ(pipeconf_reg); + if ((temp & PIPEACONF_ENABLE) == 0) { +@@ -1469,9 +1787,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; ++ int plane = intel_crtc->plane; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; +- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; +- int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR; ++ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; ++ int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 temp; + +@@ -1514,6 +1833,9 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) + + intel_crtc_load_lut(crtc); + ++ if ((IS_I965G(dev) || plane == 0)) ++ intel_update_fbc(crtc, &crtc->mode); ++ + /* Give the overlay scaler a chance to enable if it's on this pipe */ + //intel_crtc_dpms_video(crtc, true); TODO + intel_update_watermarks(dev); +@@ -1523,6 +1845,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) + /* Give the overlay scaler a chance to disable if it's on this pipe */ + //intel_crtc_dpms_video(crtc, FALSE); TODO + ++ if (dev_priv->cfb_plane == plane && ++ dev_priv->display.disable_fbc) ++ dev_priv->display.disable_fbc(dev); ++ + /* Disable the VGA plane that we never use */ + i915_disable_vga(dev); + +@@ -1571,15 +1897,15 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) + static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) + { + struct drm_device *dev = crtc->dev; ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_master_private *master_priv; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + bool enabled; + +- if (IS_IGDNG(dev)) +- igdng_crtc_dpms(crtc, mode); +- else +- i9xx_crtc_dpms(crtc, mode); ++ dev_priv->display.dpms(crtc, mode); ++ ++ intel_crtc->dpms_mode = mode; + if (!dev->primary->master) return; - -@@ -1603,8 +1668,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) +@@ -1603,8 +1929,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) DRM_ERROR("Can't update pipe %d in SAREA\n", pipe); break; } @@ -398777,11 +407169,248 @@ index 748ed50..0227b16 100644 } static void intel_crtc_prepare (struct drm_crtc *crtc) -@@ -2054,6 +2117,18 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) +@@ -1646,56 +1970,68 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, + return true; + } + ++static int i945_get_display_clock_speed(struct drm_device *dev) ++{ ++ return 400000; ++} + +-/** Returns the core display clock speed for i830 - i945 */ +-static int intel_get_core_clock_speed(struct drm_device *dev) ++static int i915_get_display_clock_speed(struct drm_device *dev) + { ++ return 333000; ++} + +- /* Core clock values taken from the published datasheets. +- * The 830 may go up to 166 Mhz, which we should check. +- */ +- if (IS_I945G(dev)) +- return 400000; +- else if (IS_I915G(dev)) +- return 333000; +- else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) +- return 200000; +- else if (IS_I915GM(dev)) { +- u16 gcfgc = 0; ++static int i9xx_misc_get_display_clock_speed(struct drm_device *dev) ++{ ++ return 200000; ++} + +- pci_read_config_word(dev->pdev, GCFGC, &gcfgc); ++static int i915gm_get_display_clock_speed(struct drm_device *dev) ++{ ++ u16 gcfgc = 0; + +- if (gcfgc & GC_LOW_FREQUENCY_ENABLE) +- return 133000; +- else { +- switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { +- case GC_DISPLAY_CLOCK_333_MHZ: +- return 333000; +- default: +- case GC_DISPLAY_CLOCK_190_200_MHZ: +- return 190000; +- } +- } +- } else if (IS_I865G(dev)) +- return 266000; +- else if (IS_I855(dev)) { +- u16 hpllcc = 0; +- /* Assume that the hardware is in the high speed state. This +- * should be the default. +- */ +- switch (hpllcc & GC_CLOCK_CONTROL_MASK) { +- case GC_CLOCK_133_200: +- case GC_CLOCK_100_200: +- return 200000; +- case GC_CLOCK_166_250: +- return 250000; +- case GC_CLOCK_100_133: +- return 133000; ++ pci_read_config_word(dev->pdev, GCFGC, &gcfgc); ++ ++ if (gcfgc & GC_LOW_FREQUENCY_ENABLE) ++ return 133000; ++ else { ++ switch (gcfgc & GC_DISPLAY_CLOCK_MASK) { ++ case GC_DISPLAY_CLOCK_333_MHZ: ++ return 333000; ++ default: ++ case GC_DISPLAY_CLOCK_190_200_MHZ: ++ return 190000; + } +- } else /* 852, 830 */ ++ } ++} ++ ++static int i865_get_display_clock_speed(struct drm_device *dev) ++{ ++ return 266000; ++} ++ ++static int i855_get_display_clock_speed(struct drm_device *dev) ++{ ++ u16 hpllcc = 0; ++ /* Assume that the hardware is in the high speed state. This ++ * should be the default. ++ */ ++ switch (hpllcc & GC_CLOCK_CONTROL_MASK) { ++ case GC_CLOCK_133_200: ++ case GC_CLOCK_100_200: ++ return 200000; ++ case GC_CLOCK_166_250: ++ return 250000; ++ case GC_CLOCK_100_133: + return 133000; ++ } + +- return 0; /* Silence gcc warning */ ++ /* Shouldn't happen */ ++ return 0; ++} ++ ++static int i830_get_display_clock_speed(struct drm_device *dev) ++{ ++ return 133000; + } + + /** +@@ -1858,7 +2194,14 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, + { + long entries_required, wm_size; + +- entries_required = (clock_in_khz * pixel_size * latency_ns) / 1000000; ++ /* ++ * Note: we need to make sure we don't overflow for various clock & ++ * latency values. ++ * clocks go from a few thousand to several hundred thousand. ++ * latency is usually a few thousand ++ */ ++ entries_required = ((clock_in_khz / 1000) * pixel_size * latency_ns) / ++ 1000; + entries_required /= wm->cacheline_size; + + DRM_DEBUG("FIFO entries required for mode: %d\n", entries_required); +@@ -1923,14 +2266,13 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb, + for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { + latency = &cxsr_latency_table[i]; + if (is_desktop == latency->is_desktop && +- fsb == latency->fsb_freq && mem == latency->mem_freq) +- break; +- } +- if (i >= ARRAY_SIZE(cxsr_latency_table)) { +- DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); +- return NULL; ++ fsb == latency->fsb_freq && mem == latency->mem_freq) ++ return latency; + } +- return latency; ++ ++ DRM_DEBUG("Unknown FSB/MEM found, disable CxSR\n"); ++ ++ return NULL; + } + + static void igd_disable_cxsr(struct drm_device *dev) +@@ -2021,32 +2363,36 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, + */ + const static int latency_ns = 5000; + +-static int intel_get_fifo_size(struct drm_device *dev, int plane) ++static int i9xx_get_fifo_size(struct drm_device *dev, int plane) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t dsparb = I915_READ(DSPARB); + int size; + +- if (IS_I9XX(dev)) { +- if (plane == 0) +- size = dsparb & 0x7f; +- else +- size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - +- (dsparb & 0x7f); +- } else if (IS_I85X(dev)) { +- if (plane == 0) +- size = dsparb & 0x1ff; +- else +- size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - +- (dsparb & 0x1ff); +- size >>= 1; /* Convert to cachelines */ +- } else if (IS_845G(dev)) { +- size = dsparb & 0x7f; +- size >>= 2; /* Convert to cachelines */ +- } else { ++ if (plane == 0) + size = dsparb & 0x7f; +- size >>= 1; /* Convert to cachelines */ +- } ++ else ++ size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - ++ (dsparb & 0x7f); ++ ++ DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", ++ size); ++ ++ return size; ++} ++ ++static int i85x_get_fifo_size(struct drm_device *dev, int plane) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t dsparb = I915_READ(DSPARB); ++ int size; ++ ++ if (plane == 0) ++ size = dsparb & 0x1ff; ++ else ++ size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - ++ (dsparb & 0x1ff); ++ size >>= 1; /* Convert to cachelines */ + + DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", + size); +@@ -2054,7 +2400,51 @@ static int intel_get_fifo_size(struct drm_device *dev, int plane) return size; } -+static void g4x_update_wm(struct drm_device *dev) +-static void i965_update_wm(struct drm_device *dev) ++static int i845_get_fifo_size(struct drm_device *dev, int plane) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t dsparb = I915_READ(DSPARB); ++ int size; ++ ++ size = dsparb & 0x7f; ++ size >>= 2; /* Convert to cachelines */ ++ ++ DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", ++ size); ++ ++ return size; ++} ++ ++static int i830_get_fifo_size(struct drm_device *dev, int plane) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ uint32_t dsparb = I915_READ(DSPARB); ++ int size; ++ ++ size = dsparb & 0x7f; ++ size >>= 1; /* Convert to cachelines */ ++ ++ DRM_DEBUG("FIFO size - (0x%08x) %s: %d\n", dsparb, plane ? "B" : "A", ++ size); ++ ++ return size; ++} ++ ++static void g4x_update_wm(struct drm_device *dev, int unused, int unused2, ++ int unused3, int unused4) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 fw_blc_self = I915_READ(FW_BLC_SELF); @@ -398793,10 +407422,23 @@ index 748ed50..0227b16 100644 + I915_WRITE(FW_BLC_SELF, fw_blc_self); +} + - static void i965_update_wm(struct drm_device *dev) ++static void i965_update_wm(struct drm_device *dev, int unused, int unused2, ++ int unused3, int unused4) { struct drm_i915_private *dev_priv = dev->dev_private; -@@ -2105,7 +2180,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, + +@@ -2090,8 +2480,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, + cacheline_size = planea_params.cacheline_size; + + /* Update per-plane FIFO sizes */ +- planea_params.fifo_size = intel_get_fifo_size(dev, 0); +- planeb_params.fifo_size = intel_get_fifo_size(dev, 1); ++ planea_params.fifo_size = dev_priv->display.get_fifo_size(dev, 0); ++ planeb_params.fifo_size = dev_priv->display.get_fifo_size(dev, 1); + + planea_wm = intel_calculate_wm(planea_clock, &planea_params, + pixel_size, latency_ns); +@@ -2105,7 +2495,8 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, cwm = 2; /* Calc sr entries for one plane configs */ @@ -398806,7 +407448,7 @@ index 748ed50..0227b16 100644 /* self-refresh has much higher latency */ const static int sr_latency_ns = 6000; -@@ -2120,8 +2196,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, +@@ -2120,8 +2511,7 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, srwm = total_size - sr_entries; if (srwm < 0) srwm = 1; @@ -398816,7 +407458,32 @@ index 748ed50..0227b16 100644 } DRM_DEBUG("Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", -@@ -2195,9 +2270,6 @@ static void intel_update_watermarks(struct drm_device *dev) +@@ -2138,14 +2528,14 @@ static void i9xx_update_wm(struct drm_device *dev, int planea_clock, + I915_WRITE(FW_BLC2, fwater_hi); + } + +-static void i830_update_wm(struct drm_device *dev, int planea_clock, +- int pixel_size) ++static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, ++ int unused2, int pixel_size) + { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff; + int planea_wm; + +- i830_wm_info.fifo_size = intel_get_fifo_size(dev, 0); ++ i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0); + + planea_wm = intel_calculate_wm(planea_clock, &i830_wm_info, + pixel_size, latency_ns); +@@ -2189,15 +2579,13 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, + */ + static void intel_update_watermarks(struct drm_device *dev) + { ++ struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + struct intel_crtc *intel_crtc; + int sr_hdisplay = 0; unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; int enabled = 0, pixel_size = 0; @@ -398826,19 +407493,43 @@ index 748ed50..0227b16 100644 /* Get the clock config from both planes */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { intel_crtc = to_intel_crtc(crtc); -@@ -2230,7 +2302,9 @@ static void intel_update_watermarks(struct drm_device *dev) +@@ -2230,13 +2618,8 @@ static void intel_update_watermarks(struct drm_device *dev) else if (IS_IGD(dev)) igd_disable_cxsr(dev); - if (IS_I965G(dev)) -+ if (IS_G4X(dev)) -+ g4x_update_wm(dev); -+ else if (IS_I965G(dev)) - i965_update_wm(dev); - else if (IS_I9XX(dev) || IS_MOBILE(dev)) - i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, -@@ -2264,9 +2338,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, - int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; +- i965_update_wm(dev); +- else if (IS_I9XX(dev) || IS_MOBILE(dev)) +- i9xx_update_wm(dev, planea_clock, planeb_clock, sr_hdisplay, +- pixel_size); +- else +- i830_update_wm(dev, planea_clock, pixel_size); ++ dev_priv->display.update_wm(dev, planea_clock, planeb_clock, ++ sr_hdisplay, pixel_size); + } + + static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2249,10 +2632,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; ++ int plane = intel_crtc->plane; + int fp_reg = (pipe == 0) ? FPA0 : FPB0; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD; +- int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; ++ int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; +@@ -2260,13 +2644,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; +- int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; +- int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; ++ int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; ++ int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; int refclk, num_outputs = 0; - intel_clock_t clock; @@ -398850,7 +407541,7 @@ index 748ed50..0227b16 100644 bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; bool is_edp = false; struct drm_mode_config *mode_config = &dev->mode_config; -@@ -2349,6 +2423,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2349,6 +2733,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, return -EINVAL; } @@ -398865,7 +407556,7 @@ index 748ed50..0227b16 100644 /* SDVO TV has fixed PLL values depend on its clock range, this mirrors vbios setting. */ if (is_sdvo && is_tv) { -@@ -2394,10 +2476,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2394,10 +2786,17 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, link_bw, &m_n); } @@ -398885,7 +407576,7 @@ index 748ed50..0227b16 100644 if (!IS_IGDNG(dev)) dpll = DPLL_VGA_MODE_DIS; -@@ -2426,6 +2515,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2426,6 +2825,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* also FPA1 */ if (IS_IGDNG(dev)) dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; @@ -398894,7 +407585,41 @@ index 748ed50..0227b16 100644 } switch (clock.p2) { case 5: -@@ -2573,6 +2664,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2477,7 +2878,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + enable color space conversion */ + if (!IS_IGDNG(dev)) { + if (pipe == 0) +- dspcntr |= DISPPLANE_SEL_PIPE_A; ++ dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; + else + dspcntr |= DISPPLANE_SEL_PIPE_B; + } +@@ -2489,7 +2890,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + * XXX: No double-wide on 915GM pipe B. Is that the only reason for the + * pipe == 0 check? + */ +- if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10) ++ if (mode->clock > ++ dev_priv->display.get_display_clock_speed(dev) * 9 / 10) + pipeconf |= PIPEACONF_DOUBLE_WIDE; + else + pipeconf &= ~PIPEACONF_DOUBLE_WIDE; +@@ -2561,9 +2963,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, + udelay(150); + + if (IS_I965G(dev) && !IS_IGDNG(dev)) { +- sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; +- I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ++ if (is_sdvo) { ++ sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; ++ I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | + ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); ++ } else ++ I915_WRITE(dpll_md_reg, 0); + } else { + /* write it again -- the BIOS does, after all */ + I915_WRITE(dpll_reg, dpll); +@@ -2573,6 +2978,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, udelay(150); } @@ -398917,7 +407642,7 @@ index 748ed50..0227b16 100644 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | -@@ -2616,6 +2723,12 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, +@@ -2616,11 +3037,20 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_wait_for_vblank(dev); @@ -398930,7 +407655,34 @@ index 748ed50..0227b16 100644 I915_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ -@@ -2769,10 +2882,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) + ret = intel_pipe_set_base(crtc, x, y, old_fb); + ++ if ((IS_I965G(dev) || plane == 0)) ++ intel_update_fbc(crtc, &crtc->mode); ++ + intel_update_watermarks(dev); + + drm_vblank_post_modeset(dev, pipe); +@@ -2665,6 +3095,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + struct drm_gem_object *bo; + struct drm_i915_gem_object *obj_priv; + int pipe = intel_crtc->pipe; ++ int plane = intel_crtc->plane; + uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; + uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; + uint32_t temp = I915_READ(control); +@@ -2750,6 +3181,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, + i915_gem_object_unpin(intel_crtc->cursor_bo); + drm_gem_object_unreference(intel_crtc->cursor_bo); + } ++ ++ if ((IS_I965G(dev) || plane == 0)) ++ intel_update_fbc(crtc, &crtc->mode); ++ + mutex_unlock(&dev->struct_mutex); + + intel_crtc->cursor_addr = addr; +@@ -2769,10 +3204,16 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -398947,7 +407699,7 @@ index 748ed50..0227b16 100644 if (x < 0) { temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; x = -x; -@@ -3070,12 +3189,319 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, +@@ -3070,12 +3511,319 @@ struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, return mode; } @@ -399269,7 +408021,19 @@ index 748ed50..0227b16 100644 drm_crtc_cleanup(crtc); kfree(intel_crtc); } -@@ -3122,15 +3548,10 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) +@@ -3118,19 +3866,22 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) + intel_crtc->lut_b[i] = i; + } + ++ /* Swap pipes & planes for FBC on pre-965 */ ++ intel_crtc->pipe = pipe; ++ intel_crtc->plane = pipe; ++ if (IS_MOBILE(dev) && (IS_I9XX(dev) && !IS_I965G(dev))) { ++ DRM_DEBUG("swapping pipes & planes for FBC\n"); ++ intel_crtc->plane = ((pipe == 0) ? 1 : 0); ++ } ++ + intel_crtc->cursor_addr = 0; intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); @@ -399278,17 +408042,17 @@ index 748ed50..0227b16 100644 - intel_crtc->mode_set.num_connectors = 0; - - if (i915_fbpercrtc) { +- +- + intel_crtc->busy = false; -- -- - } + setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, + (unsigned long)intel_crtc); } int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, -@@ -3138,30 +3559,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, +@@ -3138,30 +3889,26 @@ int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; @@ -399327,7 +408091,7 @@ index 748ed50..0227b16 100644 } struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) -@@ -3362,8 +3779,56 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { +@@ -3362,8 +4109,123 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .fb_changed = intelfb_probe, }; @@ -399377,6 +408141,73 @@ index 748ed50..0227b16 100644 + I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); + } +} ++ ++/* Set up chip specific display functions */ ++static void intel_init_display(struct drm_device *dev) ++{ ++ struct drm_i915_private *dev_priv = dev->dev_private; ++ ++ /* We always want a DPMS function */ ++ if (IS_IGDNG(dev)) ++ dev_priv->display.dpms = igdng_crtc_dpms; ++ else ++ dev_priv->display.dpms = i9xx_crtc_dpms; ++ ++ /* Only mobile has FBC, leave pointers NULL for other chips */ ++ if (IS_MOBILE(dev)) { ++ if (IS_GM45(dev)) { ++ dev_priv->display.fbc_enabled = g4x_fbc_enabled; ++ dev_priv->display.enable_fbc = g4x_enable_fbc; ++ dev_priv->display.disable_fbc = g4x_disable_fbc; ++ } else if (IS_I965GM(dev) || IS_I945GM(dev) || IS_I915GM(dev)) { ++ dev_priv->display.fbc_enabled = i8xx_fbc_enabled; ++ dev_priv->display.enable_fbc = i8xx_enable_fbc; ++ dev_priv->display.disable_fbc = i8xx_disable_fbc; ++ } ++ /* 855GM needs testing */ ++ } ++ ++ /* Returns the core display clock speed */ ++ if (IS_I945G(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i945_get_display_clock_speed; ++ else if (IS_I915G(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i915_get_display_clock_speed; ++ else if (IS_I945GM(dev) || IS_845G(dev) || IS_IGDGM(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i9xx_misc_get_display_clock_speed; ++ else if (IS_I915GM(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i915gm_get_display_clock_speed; ++ else if (IS_I865G(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i865_get_display_clock_speed; ++ else if (IS_I855(dev)) ++ dev_priv->display.get_display_clock_speed = ++ i855_get_display_clock_speed; ++ else /* 852, 830 */ ++ dev_priv->display.get_display_clock_speed = ++ i830_get_display_clock_speed; ++ ++ /* For FIFO watermark updates */ ++ if (IS_G4X(dev)) ++ dev_priv->display.update_wm = g4x_update_wm; ++ else if (IS_I965G(dev)) ++ dev_priv->display.update_wm = i965_update_wm; ++ else if (IS_I9XX(dev) || IS_MOBILE(dev)) { ++ dev_priv->display.update_wm = i9xx_update_wm; ++ dev_priv->display.get_fifo_size = i9xx_get_fifo_size; ++ } else { ++ if (IS_I85X(dev)) ++ dev_priv->display.get_fifo_size = i85x_get_fifo_size; ++ else if (IS_845G(dev)) ++ dev_priv->display.get_fifo_size = i845_get_fifo_size; ++ else ++ dev_priv->display.get_fifo_size = i830_get_fifo_size; ++ dev_priv->display.update_wm = i830_update_wm; ++ } ++} + void intel_modeset_init(struct drm_device *dev) { @@ -399384,7 +408215,16 @@ index 748ed50..0227b16 100644 int num_pipe; int i; -@@ -3398,15 +3863,47 @@ void intel_modeset_init(struct drm_device *dev) +@@ -3374,6 +4236,8 @@ void intel_modeset_init(struct drm_device *dev) + + dev->mode_config.funcs = (void *)&intel_mode_funcs; + ++ intel_init_display(dev); ++ + if (IS_I965G(dev)) { + dev->mode_config.max_width = 8192; + dev->mode_config.max_height = 8192; +@@ -3398,15 +4262,50 @@ void intel_modeset_init(struct drm_device *dev) DRM_DEBUG("%d display pipe%s available.\n", num_pipe, num_pipe > 1 ? "s" : ""); @@ -399428,11 +408268,14 @@ index 748ed50..0227b16 100644 + del_timer_sync(&dev_priv->idle_timer); + + mutex_unlock(&dev->struct_mutex); ++ ++ if (dev_priv->display.disable_fbc) ++ dev_priv->display.disable_fbc(dev); + drm_mode_config_cleanup(dev); } -@@ -3420,3 +3917,20 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector) +@@ -3420,3 +4319,20 @@ struct drm_encoder *intel_best_encoder(struct drm_connector *connector) return &intel_output->enc; } @@ -399467,10 +408310,26 @@ index 2b914d7..f4856a5 100644 I915_WRITE(ch_data + i, d); } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h -index 26a6227..3ebbbab 100644 +index 26a6227..8aa4b7f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h -@@ -117,9 +117,9 @@ struct intel_crtc { +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include "i915_drv.h" + #include "drm_crtc.h" + + #include "drm_crtc_helper.h" +@@ -111,15 +112,15 @@ struct intel_output { + + struct intel_crtc { + struct drm_crtc base; +- int pipe; +- int plane; ++ enum pipe pipe; ++ enum plane plane; + struct drm_gem_object *cursor_bo; uint32_t cursor_addr; u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; @@ -399483,7 +408342,7 @@ index 26a6227..3ebbbab 100644 }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) -@@ -138,6 +138,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); +@@ -138,6 +139,7 @@ extern void intel_hdmi_init(struct drm_device *dev, int sdvox_reg); extern bool intel_sdvo_init(struct drm_device *dev, int output_device); extern void intel_dvo_init(struct drm_device *dev); extern void intel_tv_init(struct drm_device *dev); @@ -399491,7 +408350,7 @@ index 26a6227..3ebbbab 100644 extern void intel_lvds_init(struct drm_device *dev); extern void intel_dp_init(struct drm_device *dev, int dp_reg); void -@@ -178,4 +179,5 @@ extern int intel_framebuffer_create(struct drm_device *dev, +@@ -178,4 +180,5 @@ extern int intel_framebuffer_create(struct drm_device *dev, struct drm_mode_fb_cmd *mode_cmd, struct drm_framebuffer **fb, struct drm_gem_object *obj); @@ -400352,10 +409211,18 @@ index 62b8bea..c7eab72 100644 /* diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c -index 8df02ef..dafc0da 100644 +index 8df02ef..98ae3d7 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c -@@ -38,16 +38,6 @@ +@@ -27,6 +27,7 @@ + * Jesse Barnes + */ + ++#include + #include + #include + #include "drmP.h" +@@ -38,16 +39,6 @@ #include "i915_drv.h" #include @@ -400372,8 +409239,27 @@ index 8df02ef..dafc0da 100644 /* Private structure for the integrated LVDS support */ struct intel_lvds_priv { int fitting_mode; -@@ -336,7 +326,7 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, - I915_WRITE(BCLRPAT_B, 0); +@@ -305,6 +296,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, + goto out; + } + ++ /* full screen scale for now */ ++ if (IS_IGDNG(dev)) ++ goto out; ++ + /* 965+ wants fuzzy fitting */ + if (IS_I965G(dev)) + pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | +@@ -332,11 +327,13 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, + * to register description and PRM. + * Change the value here to see the borders for debugging + */ +- I915_WRITE(BCLRPAT_A, 0); +- I915_WRITE(BCLRPAT_B, 0); ++ if (!IS_IGDNG(dev)) { ++ I915_WRITE(BCLRPAT_A, 0); ++ I915_WRITE(BCLRPAT_B, 0); ++ } switch (lvds_priv->fitting_mode) { - case DRM_MODE_SCALE_NO_SCALE: @@ -400381,7 +409267,92 @@ index 8df02ef..dafc0da 100644 /* * For centered modes, we have to calculate border widths & * heights and modify the values programmed into the CRTC. -@@ -672,9 +662,8 @@ static int intel_lvds_set_property(struct drm_connector *connector, +@@ -582,7 +579,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, + * settings. + */ + +- /* No panel fitting yet, fixme */ + if (IS_IGDNG(dev)) + return; + +@@ -595,15 +591,33 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, + I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); + } + ++/* Some lid devices report incorrect lid status, assume they're connected */ ++static const struct dmi_system_id bad_lid_status[] = { ++ { ++ .ident = "Aspire One", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Acer"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"), ++ }, ++ }, ++ { } ++}; ++ + /** + * Detect the LVDS connection. + * +- * This always returns CONNECTOR_STATUS_CONNECTED. This connector should only have +- * been set up if the LVDS was actually connected anyway. ++ * Since LVDS doesn't have hotlug, we use the lid as a proxy. Open means ++ * connected and closed means disconnected. We also send hotplug events as ++ * needed, using lid status notification from the input layer. + */ + static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) + { +- return connector_status_connected; ++ enum drm_connector_status status = connector_status_connected; ++ ++ if (!acpi_lid_open() && !dmi_check_system(bad_lid_status)) ++ status = connector_status_disconnected; ++ ++ return status; + } + + /** +@@ -642,6 +656,24 @@ static int intel_lvds_get_modes(struct drm_connector *connector) + return 0; + } + ++static int intel_lid_notify(struct notifier_block *nb, unsigned long val, ++ void *unused) ++{ ++ struct drm_i915_private *dev_priv = ++ container_of(nb, struct drm_i915_private, lid_notifier); ++ struct drm_device *dev = dev_priv->dev; ++ ++ if (acpi_lid_open() && !dev_priv->suspended) { ++ mutex_lock(&dev->mode_config.mutex); ++ drm_helper_resume_force_mode(dev); ++ mutex_unlock(&dev->mode_config.mutex); ++ } ++ ++ drm_sysfs_hotplug_event(dev_priv->dev); ++ ++ return NOTIFY_OK; ++} ++ + /** + * intel_lvds_destroy - unregister and free LVDS structures + * @connector: connector to free +@@ -651,10 +683,14 @@ static int intel_lvds_get_modes(struct drm_connector *connector) + */ + static void intel_lvds_destroy(struct drm_connector *connector) + { ++ struct drm_device *dev = connector->dev; + struct intel_output *intel_output = to_intel_output(connector); ++ struct drm_i915_private *dev_priv = dev->dev_private; + + if (intel_output->ddc_bus) + intel_i2c_destroy(intel_output->ddc_bus); ++ if (dev_priv->lid_notifier.notifier_call) ++ acpi_lid_notifier_unregister(&dev_priv->lid_notifier); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); +@@ -672,9 +708,8 @@ static int intel_lvds_set_property(struct drm_connector *connector, connector->encoder) { struct drm_crtc *crtc = connector->encoder->crtc; struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; @@ -400393,7 +409364,7 @@ index 8df02ef..dafc0da 100644 return 0; } if (lvds_priv->fitting_mode == value) { -@@ -731,8 +720,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { +@@ -731,8 +766,7 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = { static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) { @@ -400403,7 +409374,16 @@ index 8df02ef..dafc0da 100644 return 1; } -@@ -1027,7 +1015,7 @@ out: +@@ -1023,11 +1057,16 @@ out: + pwm |= PWM_PCH_ENABLE; + I915_WRITE(BLC_PWM_PCH_CTL1, pwm); + } ++ dev_priv->lid_notifier.notifier_call = intel_lid_notify; ++ if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { ++ DRM_DEBUG("lid notifier registration failed\n"); ++ dev_priv->lid_notifier.notifier_call = NULL; ++ } + drm_sysfs_connector_add(connector); return; failed: @@ -400413,7 +409393,7 @@ index 8df02ef..dafc0da 100644 intel_i2c_destroy(intel_output->ddc_bus); drm_connector_cleanup(connector); diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c -index d3b74ba..0bf28ef 100644 +index d3b74ba..083bec2 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -37,7 +37,19 @@ @@ -400468,7 +409448,7 @@ index d3b74ba..0bf28ef 100644 /* * supported encoding mode, used to determine whether HDMI is * supported -@@ -114,6 +127,9 @@ struct intel_sdvo_priv { +@@ -114,11 +127,38 @@ struct intel_sdvo_priv { /* DDC bus used by this SDVO output */ uint8_t ddc_bus; @@ -400478,7 +409458,36 @@ index d3b74ba..0bf28ef 100644 int save_sdvo_mult; u16 save_active_outputs; struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; -@@ -188,7 +204,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, + struct intel_sdvo_dtd save_output_dtd[16]; + u32 save_SDVOX; ++ /* add the property for the SDVO-TV */ ++ struct drm_property *left_property; ++ struct drm_property *right_property; ++ struct drm_property *top_property; ++ struct drm_property *bottom_property; ++ struct drm_property *hpos_property; ++ struct drm_property *vpos_property; ++ ++ /* add the property for the SDVO-TV/LVDS */ ++ struct drm_property *brightness_property; ++ struct drm_property *contrast_property; ++ struct drm_property *saturation_property; ++ struct drm_property *hue_property; ++ ++ /* Add variable to record current setting for the above property */ ++ u32 left_margin, right_margin, top_margin, bottom_margin; ++ /* this is to get the range of margin.*/ ++ u32 max_hscan, max_vscan; ++ u32 max_hpos, cur_hpos; ++ u32 max_vpos, cur_vpos; ++ u32 cur_brightness, max_brightness; ++ u32 cur_contrast, max_contrast; ++ u32 cur_saturation, max_saturation; ++ u32 cur_hue, max_hue; + }; + + static bool +@@ -188,7 +228,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, return true; } @@ -400487,7 +409496,39 @@ index d3b74ba..0bf28ef 100644 return false; } -@@ -298,7 +314,7 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, +@@ -265,6 +305,31 @@ static const struct _sdvo_cmd_name { + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), ++ /* Add the op code for SDVO enhancements */ ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), ++ SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), + /* HDMI op code */ + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), +@@ -298,7 +363,7 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd, struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; @@ -400496,7 +409537,7 @@ index d3b74ba..0bf28ef 100644 SDVO_NAME(sdvo_priv), cmd); for (i = 0; i < args_len; i++) DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); -@@ -351,7 +367,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, +@@ -351,7 +416,7 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output, struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; int i; @@ -400505,7 +409546,7 @@ index d3b74ba..0bf28ef 100644 for (i = 0; i < response_len; i++) DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); for (; i < 8; i++) -@@ -668,10 +684,10 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) +@@ -668,10 +733,10 @@ static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output) status = intel_sdvo_read_response(intel_output, &response, 1); if (status != SDVO_CMD_STATUS_SUCCESS) { @@ -400518,7 +409559,7 @@ index d3b74ba..0bf28ef 100644 } return response; -@@ -945,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, +@@ -945,23 +1010,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, static void intel_sdvo_set_tv_format(struct intel_output *output) { @@ -400557,12 +409598,12 @@ index d3b74ba..0bf28ef 100644 + + status = intel_sdvo_read_response(output, NULL, 0); + if (status != SDVO_CMD_STATUS_SUCCESS) -+ DRM_DEBUG("%s: Failed to set TV format\n", ++ DRM_DEBUG_KMS("%s: Failed to set TV format\n", + SDVO_NAME(sdvo_priv)); } static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, -@@ -1230,8 +1251,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) +@@ -1230,8 +1300,8 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) * a given it the status is a success, we succeeded. */ if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { @@ -400573,7 +409614,7 @@ index d3b74ba..0bf28ef 100644 } if (0) -@@ -1326,8 +1347,8 @@ static void intel_sdvo_restore(struct drm_connector *connector) +@@ -1326,8 +1396,8 @@ static void intel_sdvo_restore(struct drm_connector *connector) intel_wait_for_vblank(dev); status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2); if (status == SDVO_CMD_STATUS_SUCCESS && !input1) @@ -400584,7 +409625,7 @@ index d3b74ba..0bf28ef 100644 } intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs); -@@ -1405,7 +1426,7 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) +@@ -1405,7 +1475,7 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) u8 response[2]; u8 status; struct intel_output *intel_output; @@ -400593,7 +409634,7 @@ index d3b74ba..0bf28ef 100644 if (!connector) return 0; -@@ -1478,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) +@@ -1478,6 +1548,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) return (caps > 1); } @@ -400630,7 +409671,7 @@ index d3b74ba..0bf28ef 100644 enum drm_connector_status intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) { -@@ -1488,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) +@@ -1488,6 +1588,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); @@ -400646,7 +409687,7 @@ index d3b74ba..0bf28ef 100644 if (edid != NULL) { /* Don't report the output as connected if it's a DVI-I * connector with a non-digital EDID coming out. -@@ -1516,10 +1576,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect +@@ -1516,10 +1625,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect struct intel_output *intel_output = to_intel_output(connector); struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; @@ -400660,7 +409701,7 @@ index d3b74ba..0bf28ef 100644 if (status != SDVO_CMD_STATUS_SUCCESS) return connector_status_unknown; -@@ -1540,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect +@@ -1540,50 +1650,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); @@ -400730,7 +409771,7 @@ index d3b74ba..0bf28ef 100644 } /* -@@ -1656,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) +@@ -1656,17 +1748,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) struct intel_output *output = to_intel_output(connector); struct intel_sdvo_priv *sdvo_priv = output->dev_priv; struct intel_sdvo_sdtv_resolution_request tv_res; @@ -400762,7 +409803,7 @@ index d3b74ba..0bf28ef 100644 intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, &tv_res, sizeof(tv_res)); status = intel_sdvo_read_response(output, &reply, 3); -@@ -1681,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) +@@ -1681,6 +1782,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) if (nmode) drm_mode_probed_add(connector, nmode); } @@ -400770,7 +409811,53 @@ index d3b74ba..0bf28ef 100644 } static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) -@@ -1748,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector) +@@ -1739,6 +1841,45 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) + return 1; + } + ++static ++void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) ++{ ++ struct intel_output *intel_output = to_intel_output(connector); ++ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; ++ struct drm_device *dev = connector->dev; ++ ++ if (sdvo_priv->is_tv) { ++ if (sdvo_priv->left_property) ++ drm_property_destroy(dev, sdvo_priv->left_property); ++ if (sdvo_priv->right_property) ++ drm_property_destroy(dev, sdvo_priv->right_property); ++ if (sdvo_priv->top_property) ++ drm_property_destroy(dev, sdvo_priv->top_property); ++ if (sdvo_priv->bottom_property) ++ drm_property_destroy(dev, sdvo_priv->bottom_property); ++ if (sdvo_priv->hpos_property) ++ drm_property_destroy(dev, sdvo_priv->hpos_property); ++ if (sdvo_priv->vpos_property) ++ drm_property_destroy(dev, sdvo_priv->vpos_property); ++ } ++ if (sdvo_priv->is_tv) { ++ if (sdvo_priv->saturation_property) ++ drm_property_destroy(dev, ++ sdvo_priv->saturation_property); ++ if (sdvo_priv->contrast_property) ++ drm_property_destroy(dev, ++ sdvo_priv->contrast_property); ++ if (sdvo_priv->hue_property) ++ drm_property_destroy(dev, sdvo_priv->hue_property); ++ } ++ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { ++ if (sdvo_priv->brightness_property) ++ drm_property_destroy(dev, ++ sdvo_priv->brightness_property); ++ } ++ return; ++} ++ + static void intel_sdvo_destroy(struct drm_connector *connector) + { + struct intel_output *intel_output = to_intel_output(connector); +@@ -1748,17 +1889,158 @@ static void intel_sdvo_destroy(struct drm_connector *connector) intel_i2c_destroy(intel_output->i2c_bus); if (intel_output->ddc_bus) intel_i2c_destroy(intel_output->ddc_bus); @@ -400784,6 +409871,9 @@ index d3b74ba..0bf28ef 100644 + if (sdvo_priv->tv_format_property) + drm_property_destroy(connector->dev, + sdvo_priv->tv_format_property); ++ ++ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) ++ intel_sdvo_destroy_enhance_property(connector); + drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -400802,6 +409892,8 @@ index d3b74ba..0bf28ef 100644 + struct drm_crtc *crtc = encoder->crtc; + int ret = 0; + bool changed = false; ++ uint8_t cmd, status; ++ uint16_t temp_value; + + ret = drm_connector_property_set_value(connector, property, val); + if (ret < 0) @@ -400818,11 +409910,102 @@ index d3b74ba..0bf28ef 100644 + + sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; + changed = true; -+ } else { -+ ret = -EINVAL; -+ goto out; + } + ++ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { ++ cmd = 0; ++ temp_value = val; ++ if (sdvo_priv->left_property == property) { ++ drm_connector_property_set_value(connector, ++ sdvo_priv->right_property, val); ++ if (sdvo_priv->left_margin == temp_value) ++ goto out; ++ ++ sdvo_priv->left_margin = temp_value; ++ sdvo_priv->right_margin = temp_value; ++ temp_value = sdvo_priv->max_hscan - ++ sdvo_priv->left_margin; ++ cmd = SDVO_CMD_SET_OVERSCAN_H; ++ } else if (sdvo_priv->right_property == property) { ++ drm_connector_property_set_value(connector, ++ sdvo_priv->left_property, val); ++ if (sdvo_priv->right_margin == temp_value) ++ goto out; ++ ++ sdvo_priv->left_margin = temp_value; ++ sdvo_priv->right_margin = temp_value; ++ temp_value = sdvo_priv->max_hscan - ++ sdvo_priv->left_margin; ++ cmd = SDVO_CMD_SET_OVERSCAN_H; ++ } else if (sdvo_priv->top_property == property) { ++ drm_connector_property_set_value(connector, ++ sdvo_priv->bottom_property, val); ++ if (sdvo_priv->top_margin == temp_value) ++ goto out; ++ ++ sdvo_priv->top_margin = temp_value; ++ sdvo_priv->bottom_margin = temp_value; ++ temp_value = sdvo_priv->max_vscan - ++ sdvo_priv->top_margin; ++ cmd = SDVO_CMD_SET_OVERSCAN_V; ++ } else if (sdvo_priv->bottom_property == property) { ++ drm_connector_property_set_value(connector, ++ sdvo_priv->top_property, val); ++ if (sdvo_priv->bottom_margin == temp_value) ++ goto out; ++ sdvo_priv->top_margin = temp_value; ++ sdvo_priv->bottom_margin = temp_value; ++ temp_value = sdvo_priv->max_vscan - ++ sdvo_priv->top_margin; ++ cmd = SDVO_CMD_SET_OVERSCAN_V; ++ } else if (sdvo_priv->hpos_property == property) { ++ if (sdvo_priv->cur_hpos == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_POSITION_H; ++ sdvo_priv->cur_hpos = temp_value; ++ } else if (sdvo_priv->vpos_property == property) { ++ if (sdvo_priv->cur_vpos == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_POSITION_V; ++ sdvo_priv->cur_vpos = temp_value; ++ } else if (sdvo_priv->saturation_property == property) { ++ if (sdvo_priv->cur_saturation == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_SATURATION; ++ sdvo_priv->cur_saturation = temp_value; ++ } else if (sdvo_priv->contrast_property == property) { ++ if (sdvo_priv->cur_contrast == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_CONTRAST; ++ sdvo_priv->cur_contrast = temp_value; ++ } else if (sdvo_priv->hue_property == property) { ++ if (sdvo_priv->cur_hue == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_HUE; ++ sdvo_priv->cur_hue = temp_value; ++ } else if (sdvo_priv->brightness_property == property) { ++ if (sdvo_priv->cur_brightness == temp_value) ++ goto out; ++ ++ cmd = SDVO_CMD_SET_BRIGHTNESS; ++ sdvo_priv->cur_brightness = temp_value; ++ } ++ if (cmd) { ++ intel_sdvo_write_cmd(intel_output, cmd, &temp_value, 2); ++ status = intel_sdvo_read_response(intel_output, ++ NULL, 0); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO command \n"); ++ return -EINVAL; ++ } ++ changed = true; ++ } ++ } + if (changed && crtc) + drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, + crtc->y, crtc->fb); @@ -400833,7 +410016,7 @@ index d3b74ba..0bf28ef 100644 static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { .dpms = intel_sdvo_dpms, .mode_fixup = intel_sdvo_mode_fixup, -@@ -1773,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { +@@ -1773,6 +2055,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { .restore = intel_sdvo_restore, .detect = intel_sdvo_detect, .fill_modes = drm_helper_probe_single_connector_modes, @@ -400841,7 +410024,16 @@ index d3b74ba..0bf28ef 100644 .destroy = intel_sdvo_destroy, }; -@@ -2013,10 +2112,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) +@@ -1991,6 +2274,8 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) + sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; + encoder->encoder_type = DRM_MODE_ENCODER_DAC; + connector->connector_type = DRM_MODE_CONNECTOR_VGA; ++ intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | ++ (1 << INTEL_ANALOG_CLONE_BIT); + } else if (flags & SDVO_OUTPUT_LVDS0) { + + sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0; +@@ -2013,10 +2298,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) sdvo_priv->controlled_output = 0; memcpy(bytes, &sdvo_priv->caps.output_flags, 2); @@ -400855,7 +410047,7 @@ index d3b74ba..0bf28ef 100644 ret = false; } intel_output->crtc_mask = (1 << 0) | (1 << 1); -@@ -2029,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) +@@ -2029,6 +2313,359 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) } @@ -400907,11 +410099,315 @@ index d3b74ba..0bf28ef 100644 + connector, sdvo_priv->tv_format_property, 0); + +} ++ ++static void intel_sdvo_create_enhance_property(struct drm_connector *connector) ++{ ++ struct intel_output *intel_output = to_intel_output(connector); ++ struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; ++ struct intel_sdvo_enhancements_reply sdvo_data; ++ struct drm_device *dev = connector->dev; ++ uint8_t status; ++ uint16_t response, data_value[2]; ++ ++ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, ++ NULL, 0); ++ status = intel_sdvo_read_response(intel_output, &sdvo_data, ++ sizeof(sdvo_data)); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS(" incorrect response is returned\n"); ++ return; ++ } ++ response = *((uint16_t *)&sdvo_data); ++ if (!response) { ++ DRM_DEBUG_KMS("No enhancement is supported\n"); ++ return; ++ } ++ if (sdvo_priv->is_tv) { ++ /* when horizontal overscan is supported, Add the left/right ++ * property ++ */ ++ if (sdvo_data.overscan_h) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO max " ++ "h_overscan\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_OVERSCAN_H, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); ++ return; ++ } ++ sdvo_priv->max_hscan = data_value[0]; ++ sdvo_priv->left_margin = data_value[0] - response; ++ sdvo_priv->right_margin = sdvo_priv->left_margin; ++ sdvo_priv->left_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "left_margin", 2); ++ sdvo_priv->left_property->values[0] = 0; ++ sdvo_priv->left_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->left_property, ++ sdvo_priv->left_margin); ++ sdvo_priv->right_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "right_margin", 2); ++ sdvo_priv->right_property->values[0] = 0; ++ sdvo_priv->right_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->right_property, ++ sdvo_priv->right_margin); ++ DRM_DEBUG_KMS("h_overscan: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ if (sdvo_data.overscan_v) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO max " ++ "v_overscan\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_OVERSCAN_V, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); ++ return; ++ } ++ sdvo_priv->max_vscan = data_value[0]; ++ sdvo_priv->top_margin = data_value[0] - response; ++ sdvo_priv->bottom_margin = sdvo_priv->top_margin; ++ sdvo_priv->top_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "top_margin", 2); ++ sdvo_priv->top_property->values[0] = 0; ++ sdvo_priv->top_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->top_property, ++ sdvo_priv->top_margin); ++ sdvo_priv->bottom_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "bottom_margin", 2); ++ sdvo_priv->bottom_property->values[0] = 0; ++ sdvo_priv->bottom_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->bottom_property, ++ sdvo_priv->bottom_margin); ++ DRM_DEBUG_KMS("v_overscan: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ if (sdvo_data.position_h) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_POSITION_H, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); ++ return; ++ } ++ sdvo_priv->max_hpos = data_value[0]; ++ sdvo_priv->cur_hpos = response; ++ sdvo_priv->hpos_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "hpos", 2); ++ sdvo_priv->hpos_property->values[0] = 0; ++ sdvo_priv->hpos_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->hpos_property, ++ sdvo_priv->cur_hpos); ++ DRM_DEBUG_KMS("h_position: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ if (sdvo_data.position_v) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_POSITION_V, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); ++ return; ++ } ++ sdvo_priv->max_vpos = data_value[0]; ++ sdvo_priv->cur_vpos = response; ++ sdvo_priv->vpos_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "vpos", 2); ++ sdvo_priv->vpos_property->values[0] = 0; ++ sdvo_priv->vpos_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->vpos_property, ++ sdvo_priv->cur_vpos); ++ DRM_DEBUG_KMS("v_position: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ } ++ if (sdvo_priv->is_tv) { ++ if (sdvo_data.saturation) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_SATURATION, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_SATURATION, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); ++ return; ++ } ++ sdvo_priv->max_saturation = data_value[0]; ++ sdvo_priv->cur_saturation = response; ++ sdvo_priv->saturation_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "saturation", 2); ++ sdvo_priv->saturation_property->values[0] = 0; ++ sdvo_priv->saturation_property->values[1] = ++ data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->saturation_property, ++ sdvo_priv->cur_saturation); ++ DRM_DEBUG_KMS("saturation: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ if (sdvo_data.contrast) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_CONTRAST, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); ++ return; ++ } ++ sdvo_priv->max_contrast = data_value[0]; ++ sdvo_priv->cur_contrast = response; ++ sdvo_priv->contrast_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "contrast", 2); ++ sdvo_priv->contrast_property->values[0] = 0; ++ sdvo_priv->contrast_property->values[1] = data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->contrast_property, ++ sdvo_priv->cur_contrast); ++ DRM_DEBUG_KMS("contrast: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ if (sdvo_data.hue) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_HUE, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_HUE, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); ++ return; ++ } ++ sdvo_priv->max_hue = data_value[0]; ++ sdvo_priv->cur_hue = response; ++ sdvo_priv->hue_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "hue", 2); ++ sdvo_priv->hue_property->values[0] = 0; ++ sdvo_priv->hue_property->values[1] = ++ data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->hue_property, ++ sdvo_priv->cur_hue); ++ DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ } ++ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { ++ if (sdvo_data.brightness) { ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &data_value, 4); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); ++ return; ++ } ++ intel_sdvo_write_cmd(intel_output, ++ SDVO_CMD_GET_BRIGHTNESS, NULL, 0); ++ status = intel_sdvo_read_response(intel_output, ++ &response, 2); ++ if (status != SDVO_CMD_STATUS_SUCCESS) { ++ DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); ++ return; ++ } ++ sdvo_priv->max_brightness = data_value[0]; ++ sdvo_priv->cur_brightness = response; ++ sdvo_priv->brightness_property = ++ drm_property_create(dev, DRM_MODE_PROP_RANGE, ++ "brightness", 2); ++ sdvo_priv->brightness_property->values[0] = 0; ++ sdvo_priv->brightness_property->values[1] = ++ data_value[0]; ++ drm_connector_attach_property(connector, ++ sdvo_priv->brightness_property, ++ sdvo_priv->cur_brightness); ++ DRM_DEBUG_KMS("brightness: max %d, " ++ "default %d, current %d\n", ++ data_value[0], data_value[1], response); ++ } ++ } ++ return; ++} + bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_connector *connector; -@@ -2066,18 +2213,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) +@@ -2066,18 +2703,22 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) /* Read the regs to test if we can talk to the device */ for (i = 0; i < 0x40; i++) { if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { @@ -400938,7 +410434,7 @@ index d3b74ba..0bf28ef 100644 if (intel_output->ddc_bus == NULL) goto err_i2c; -@@ -2090,7 +2241,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) +@@ -2090,7 +2731,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) if (intel_sdvo_output_setup(intel_output, sdvo_priv->caps.output_flags) != true) { @@ -400947,16 +410443,20 @@ index d3b74ba..0bf28ef 100644 output_device == SDVOB ? 'B' : 'C'); goto err_i2c; } -@@ -2111,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) +@@ -2111,6 +2752,12 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); + if (sdvo_priv->is_tv) + intel_sdvo_tv_create_property(connector); ++ ++ if (sdvo_priv->is_tv || sdvo_priv->is_lvds) ++ intel_sdvo_create_enhance_property(connector); ++ drm_sysfs_connector_add(connector); intel_sdvo_select_ddc_bus(sdvo_priv); -@@ -2123,7 +2276,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) +@@ -2123,7 +2770,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) &sdvo_priv->pixel_clock_max); @@ -400965,7 +410465,7 @@ index d3b74ba..0bf28ef 100644 "clock range %dMHz - %dMHz, " "input 1: %c, input 2: %c, " "output 1: %c, output 2: %c\n", -@@ -2143,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) +@@ -2143,6 +2790,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) return true; err_i2c: @@ -478493,10 +487993,30 @@ index c4a0264..219b103 100644 spin_unlock_irq(&send_cq->lock); } else { diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c -index 65ad359..056b2a4 100644 +index 65ad359..0aa0110 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c -@@ -88,6 +88,7 @@ static void handle_catas(struct mthca_dev *dev) +@@ -68,11 +68,16 @@ static void catas_reset(struct work_struct *work) + spin_unlock_irq(&catas_lock); + + list_for_each_entry_safe(dev, tmpdev, &tlist, catas_err.list) { ++ struct pci_dev *pdev = dev->pdev; + ret = __mthca_restart_one(dev->pdev); ++ /* 'dev' now is not valid */ + if (ret) +- mthca_err(dev, "Reset failed (%d)\n", ret); +- else +- mthca_dbg(dev, "Reset succeeded\n"); ++ printk(KERN_ERR "mthca %s: Reset failed (%d)\n", ++ pci_name(pdev), ret); ++ else { ++ struct mthca_dev *d = pci_get_drvdata(pdev); ++ mthca_dbg(d, "Reset succeeded\n"); ++ } + } + + mutex_unlock(&mthca_device_mutex); +@@ -88,6 +93,7 @@ static void handle_catas(struct mthca_dev *dev) event.device = &dev->ib_dev; event.event = IB_EVENT_DEVICE_FATAL; event.element.port_num = 0; @@ -479962,7 +489482,7 @@ index c3654c6..f28a41b 100644 #define nes_netif_rx netif_receive_skb diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c -index c6e6611..538e409 100644 +index c6e6611..e593af3 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c @@ -1508,7 +1508,7 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd @@ -479974,6 +489494,14 @@ index c6e6611..538e409 100644 .get_link = ethtool_op_get_link, .get_settings = nes_netdev_get_settings, .set_settings = nes_netdev_set_settings, +@@ -1566,7 +1566,6 @@ static const struct net_device_ops nes_netdev_ops = { + .ndo_set_mac_address = nes_netdev_set_mac_address, + .ndo_set_multicast_list = nes_netdev_set_multicast_list, + .ndo_change_mtu = nes_netdev_change_mtu, +- .ndo_set_mac_address = eth_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_vlan_rx_register = nes_netdev_vlan_rx_register, + }; diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index a282031..9687c39 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c @@ -480485,10 +490013,30 @@ index e319d91..2bf5116 100644 skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { /* put pseudoheader back on for next time */ diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -index a0e9753..25874fc 100644 +index a0e9753..8763c1e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -@@ -720,7 +720,9 @@ out: +@@ -362,12 +362,19 @@ void ipoib_mcast_carrier_on_task(struct work_struct *work) + { + struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, + carrier_on_task); ++ struct ib_port_attr attr; + + /* + * Take rtnl_lock to avoid racing with ipoib_stop() and + * turning the carrier back on while a device is being + * removed. + */ ++ if (ib_query_port(priv->ca, priv->port, &attr) || ++ attr.state != IB_PORT_ACTIVE) { ++ ipoib_dbg(priv, "Keeping carrier off until IB port is active\n"); ++ return; ++ } ++ + rtnl_lock(); + netif_carrier_on(priv->dev); + rtnl_unlock(); +@@ -720,7 +727,9 @@ out: } } @@ -480498,7 +490046,7 @@ index a0e9753..25874fc 100644 } unlock: -@@ -758,6 +760,20 @@ void ipoib_mcast_dev_flush(struct net_device *dev) +@@ -758,6 +767,20 @@ void ipoib_mcast_dev_flush(struct net_device *dev) } } @@ -480519,7 +490067,7 @@ index a0e9753..25874fc 100644 void ipoib_mcast_restart_task(struct work_struct *work) { struct ipoib_dev_priv *priv = -@@ -791,6 +807,11 @@ void ipoib_mcast_restart_task(struct work_struct *work) +@@ -791,6 +814,11 @@ void ipoib_mcast_restart_task(struct work_struct *work) for (mclist = dev->mc_list; mclist; mclist = mclist->next) { union ib_gid mgid; @@ -485200,16 +494748,17 @@ index 0000000..6032def +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:nuc900-keypad"); diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig -index 1acfa3a..76d6751 100644 +index 1acfa3a..02f4f8f 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig -@@ -222,6 +222,22 @@ config INPUT_SGI_BTNS +@@ -222,6 +222,23 @@ config INPUT_SGI_BTNS To compile this driver as a module, choose M here: the module will be called sgi_btns. +config INPUT_WINBOND_CIR + tristate "Winbond IR remote control" + depends on X86 && PNP ++ select NEW_LEDS + select LEDS_CLASS + select BITREVERSE + help @@ -485226,7 +494775,7 @@ index 1acfa3a..76d6751 100644 config HP_SDC_RTC tristate "HP SDC Real Time Clock" depends on (GSC || HP300) && SERIO -@@ -269,4 +285,34 @@ config INPUT_DM355EVM +@@ -269,4 +286,34 @@ config INPUT_DM355EVM To compile this driver as a module, choose M here: the module will be called dm355evm_keys. @@ -506195,7 +515744,7 @@ index 9c2589e..e17f004 100644 ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) { diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig -index 7c8e712..e4f599f 100644 +index 7c8e712..f65f090 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -150,9 +150,9 @@ config LEDS_LP3944 @@ -506225,18 +515774,37 @@ index 7c8e712..e4f599f 100644 config LEDS_WM8350 tristate "LED Support for WM8350 AudioPlus PMIC" depends on LEDS_CLASS && MFD_WM8350 +@@ -229,6 +236,15 @@ config LEDS_BD2802 + This option enables support for BD2802GU RGB LED driver chips + accessed via the I2C bus. + ++config LEDS_INTEL_SS4200 ++ tristate "LED driver for Intel NAS SS4200 series" ++ depends on LEDS_CLASS && PCI ++ help ++ This option enables support for the Intel SS4200 series of ++ Network Attached Storage servers. You may control the hard ++ drive or power LEDs on the front panel. Using this driver ++ can stop the front LED from blinking after startup. ++ + comment "LED Triggers" + + config LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile -index e8cdcf7..46d7270 100644 +index e8cdcf7..12b7a20 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile -@@ -26,6 +26,7 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o +@@ -26,8 +26,10 @@ obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o obj-$(CONFIG_LEDS_FSG) += leds-fsg.o obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o +obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_PWM) += leds-pwm.o ++obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o + # LED SPI Drivers + obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c index 1813c84..a498135 100644 --- a/drivers/leds/leds-clevo-mail.c @@ -506395,6 +515963,563 @@ index dba8921..708a801 100644 data->idev->id.product = 0x0001; data->idev->id.version = 0x0100; data->idev->evbit[0] = BIT_MASK(EV_SND); +diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c +new file mode 100644 +index 0000000..a88f3fb +--- /dev/null ++++ b/drivers/leds/leds-ss4200.c +@@ -0,0 +1,551 @@ ++/* ++ * SS4200-E Hardware API ++ * Copyright (c) 2009, Intel Corporation. ++ * Copyright IBM Corporation, 2009 ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Author: Dave Hansen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Rodney Girod , Dave Hansen "); ++MODULE_DESCRIPTION("Intel NAS/Home Server ICH7 GPIO Driver"); ++MODULE_LICENSE("GPL"); ++ ++/* ++ * ICH7 LPC/GPIO PCI Config register offsets ++ */ ++#define PMBASE 0x040 ++#define GPIO_BASE 0x048 ++#define GPIO_CTRL 0x04c ++#define GPIO_EN 0x010 ++ ++/* ++ * The ICH7 GPIO register block is 64 bytes in size. ++ */ ++#define ICH7_GPIO_SIZE 64 ++ ++/* ++ * Define register offsets within the ICH7 register block. ++ */ ++#define GPIO_USE_SEL 0x000 ++#define GP_IO_SEL 0x004 ++#define GP_LVL 0x00c ++#define GPO_BLINK 0x018 ++#define GPI_INV 0x030 ++#define GPIO_USE_SEL2 0x034 ++#define GP_IO_SEL2 0x038 ++#define GP_LVL2 0x03c ++ ++/* ++ * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives. ++ */ ++static struct pci_device_id ich7_lpc_pci_id[] = ++{ ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) }, ++ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_30) }, ++ { } /* NULL entry */ ++}; ++ ++MODULE_DEVICE_TABLE(pci, ich7_lpc_pci_id); ++ ++static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id) ++{ ++ printk(KERN_INFO KBUILD_MODNAME ": '%s' found\n", id->ident); ++ return 1; ++} ++ ++static unsigned int __initdata nodetect; ++module_param_named(nodetect, nodetect, bool, 0); ++MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); ++ ++/* ++ * struct nas_led_whitelist - List of known good models ++ * ++ * Contains the known good models this driver is compatible with. ++ * When adding a new model try to be as strict as possible. This ++ * makes it possible to keep the false positives (the model is ++ * detected as working, but in reality it is not) as low as ++ * possible. ++ */ ++static struct dmi_system_id __initdata nas_led_whitelist[] = { ++ { ++ .callback = ss4200_led_dmi_callback, ++ .ident = "Intel SS4200-E", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Intel"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "SS4200-E"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00") ++ } ++ }, ++}; ++ ++/* ++ * Base I/O address assigned to the Power Management register block ++ */ ++static u32 g_pm_io_base; ++ ++/* ++ * Base I/O address assigned to the ICH7 GPIO register block ++ */ ++static u32 nas_gpio_io_base; ++ ++/* ++ * When we successfully register a region, we are returned a resource. ++ * We use these to identify which regions we need to release on our way ++ * back out. ++ */ ++static struct resource *gp_gpio_resource; ++ ++struct nasgpio_led { ++ char *name; ++ u32 gpio_bit; ++ struct led_classdev led_cdev; ++}; ++ ++/* ++ * gpio_bit(s) are the ICH7 GPIO bit assignments ++ */ ++static struct nasgpio_led nasgpio_leds[] = { ++ { .name = "hdd1:blue:sata", .gpio_bit = 0 }, ++ { .name = "hdd1:amber:sata", .gpio_bit = 1 }, ++ { .name = "hdd2:blue:sata", .gpio_bit = 2 }, ++ { .name = "hdd2:amber:sata", .gpio_bit = 3 }, ++ { .name = "hdd3:blue:sata", .gpio_bit = 4 }, ++ { .name = "hdd3:amber:sata", .gpio_bit = 5 }, ++ { .name = "hdd4:blue:sata", .gpio_bit = 6 }, ++ { .name = "hdd4:amber:sata", .gpio_bit = 7 }, ++ { .name = "power:blue:power", .gpio_bit = 27}, ++ { .name = "power:amber:power", .gpio_bit = 28}, ++}; ++ ++#define NAS_RECOVERY 0x00000400 /* GPIO10 */ ++ ++static struct nasgpio_led * ++led_classdev_to_nasgpio_led(struct led_classdev *led_cdev) ++{ ++ return container_of(led_cdev, struct nasgpio_led, led_cdev); ++} ++ ++static struct nasgpio_led *get_led_named(char *name) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { ++ if (strcmp(nasgpio_leds[i].name, name)) ++ continue; ++ return &nasgpio_leds[i]; ++ } ++ return NULL; ++} ++ ++/* ++ * This protects access to the gpio ports. ++ */ ++static DEFINE_SPINLOCK(nasgpio_gpio_lock); ++ ++/* ++ * There are two gpio ports, one for blinking and the other ++ * for power. @port tells us if we're doing blinking or ++ * power control. ++ * ++ * Caller must hold nasgpio_gpio_lock ++ */ ++void nasgpio_led_set_attr(struct led_classdev *led_cdev, u32 port, u32 value) ++{ ++ struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); ++ u32 gpio_out; ++ ++ gpio_out = inl(nas_gpio_io_base + port); ++ if (value) ++ gpio_out |= (1<gpio_bit); ++ else ++ gpio_out &= ~(1<gpio_bit); ++ ++ outl(gpio_out, nas_gpio_io_base + port); ++} ++ ++u32 nasgpio_led_get_attr(struct led_classdev *led_cdev, u32 port) ++{ ++ struct nasgpio_led *led = led_classdev_to_nasgpio_led(led_cdev); ++ u32 gpio_in; ++ ++ spin_lock(&nasgpio_gpio_lock); ++ gpio_in = inl(nas_gpio_io_base + port); ++ spin_unlock(&nasgpio_gpio_lock); ++ if (gpio_in & (1<gpio_bit)) ++ return 1; ++ return 0; ++} ++ ++/* ++ * There is actual brightness control in the hardware, ++ * but it is via smbus commands and not implemented ++ * in this driver. ++ */ ++static void nasgpio_led_set_brightness(struct led_classdev *led_cdev, ++ enum led_brightness brightness) ++{ ++ u32 setting = 0; ++ if (brightness >= LED_HALF) ++ setting = 1; ++ /* ++ * Hold the lock across both operations. This ensures ++ * consistency so that both the "turn off blinking" ++ * and "turn light off" operations complete as a set. ++ */ ++ spin_lock(&nasgpio_gpio_lock); ++ /* ++ * LED class documentation asks that past blink state ++ * be disabled when brightness is turned to zero. ++ */ ++ if (brightness == 0) ++ nasgpio_led_set_attr(led_cdev, GPO_BLINK, 0); ++ nasgpio_led_set_attr(led_cdev, GP_LVL, setting); ++ spin_unlock(&nasgpio_gpio_lock); ++} ++ ++static int nasgpio_led_set_blink(struct led_classdev *led_cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ u32 setting = 1; ++ if (!(*delay_on == 0 && *delay_off == 0) && ++ !(*delay_on == 500 && *delay_off == 500)) ++ return -EINVAL; ++ /* ++ * These are very approximate. ++ */ ++ *delay_on = 500; ++ *delay_off = 500; ++ ++ spin_lock(&nasgpio_gpio_lock); ++ nasgpio_led_set_attr(led_cdev, GPO_BLINK, setting); ++ spin_unlock(&nasgpio_gpio_lock); ++ ++ return 0; ++} ++ ++ ++/* ++ * Initialize the ICH7 GPIO registers for NAS usage. The BIOS should have ++ * already taken care of this, but we will do so in a non destructive manner ++ * so that we have what we need whether the BIOS did it or not. ++ */ ++static int ich7_gpio_init(struct device *dev) ++{ ++ int i; ++ u32 config_data = 0; ++ u32 all_nas_led = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) ++ all_nas_led |= (1<dev, ++ "ERROR: The LPC GPIO Block has not been enabled.\n"); ++ goto out; ++ } ++ ++ status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); ++ if (0 > status) { ++ dev_printk(KERN_INFO, &dev->dev, "Unable to read GPIOBASE.\n"); ++ goto out; ++ } ++ dev_printk(KERN_DEBUG, &dev->dev, ++ "GPIOBASE = 0x%08x\n", nas_gpio_io_base); ++ nas_gpio_io_base &= 0x00000ffc0; ++ ++ /* ++ * Insure that we have exclusive access to the GPIO I/O address range. ++ */ ++ gp_gpio_resource = request_region(nas_gpio_io_base, ++ ICH7_GPIO_SIZE, KBUILD_MODNAME); ++ if (NULL == gp_gpio_resource) { ++ dev_printk(KERN_INFO, &dev->dev, ++ "ERROR Unable to register GPIO I/O addresses.\n"); ++ status = -1; ++ goto out; ++ } ++ ++ /* ++ * Initialize the GPIO for NAS/Home Server Use ++ */ ++ ich7_gpio_init(&dev->dev); ++ ++out: ++ if (status) ++ ich7_lpc_cleanup(&dev->dev); ++ return status; ++} ++ ++static void ich7_lpc_remove(struct pci_dev *dev) ++{ ++ ich7_lpc_cleanup(&dev->dev); ++} ++ ++/* ++ * pci_driver structure passed to the PCI modules ++ */ ++static struct pci_driver nas_gpio_pci_driver = { ++ .name = KBUILD_MODNAME, ++ .id_table = ich7_lpc_pci_id, ++ .probe = ich7_lpc_probe, ++ .remove = ich7_lpc_remove, ++}; ++ ++static struct led_classdev *get_classdev_for_led_nr(int nr) ++{ ++ struct nasgpio_led *nas_led = &nasgpio_leds[nr]; ++ struct led_classdev *led = &nas_led->led_cdev; ++ return led; ++} ++ ++ ++void set_power_light_amber_noblink(void) ++{ ++ struct nasgpio_led *amber = get_led_named("power:amber:power"); ++ struct nasgpio_led *blue = get_led_named("power:blue:power"); ++ ++ if (!amber || !blue) ++ return; ++ /* ++ * LED_OFF implies disabling future blinking ++ */ ++ printk(KERN_DEBUG "setting blue off and amber on\n"); ++ ++ nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF); ++ nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL); ++} ++ ++static ssize_t nas_led_blink_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct led_classdev *led = dev_get_drvdata(dev); ++ int blinking = 0; ++ if (nasgpio_led_get_attr(led, GPO_BLINK)) ++ blinking = 1; ++ return sprintf(buf, "%u\n", blinking); ++} ++ ++static ssize_t nas_led_blink_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t size) ++{ ++ int ret; ++ struct led_classdev *led = dev_get_drvdata(dev); ++ unsigned long blink_state; ++ ++ ret = strict_strtoul(buf, 10, &blink_state); ++ if (ret) ++ return ret; ++ ++ spin_lock(&nasgpio_gpio_lock); ++ nasgpio_led_set_attr(led, GPO_BLINK, blink_state); ++ spin_unlock(&nasgpio_gpio_lock); ++ ++ return size; ++} ++ ++static DEVICE_ATTR(blink, 0644, nas_led_blink_show, nas_led_blink_store); ++ ++int register_nasgpio_led(int led_nr) ++{ ++ int ret; ++ struct nasgpio_led *nas_led = &nasgpio_leds[led_nr]; ++ struct led_classdev *led = get_classdev_for_led_nr(led_nr); ++ ++ led->name = nas_led->name; ++ led->brightness = LED_OFF; ++ if (nasgpio_led_get_attr(led, GP_LVL)) ++ led->brightness = LED_FULL; ++ led->brightness_set = nasgpio_led_set_brightness; ++ led->blink_set = nasgpio_led_set_blink; ++ ret = led_classdev_register(&nas_gpio_pci_dev->dev, led); ++ if (ret) ++ return ret; ++ ret = device_create_file(led->dev, &dev_attr_blink); ++ if (ret) ++ led_classdev_unregister(led); ++ return ret; ++} ++ ++void unregister_nasgpio_led(int led_nr) ++{ ++ struct led_classdev *led = get_classdev_for_led_nr(led_nr); ++ led_classdev_unregister(led); ++ device_remove_file(led->dev, &dev_attr_blink); ++} ++/* ++ * module load/initialization ++ */ ++static int __init nas_gpio_init(void) ++{ ++ int i; ++ int ret = 0; ++ int nr_devices = 0; ++ ++ nr_devices = dmi_check_system(nas_led_whitelist); ++ if (nodetect) { ++ printk(KERN_INFO "%s: skipping hardware autodetection\n", ++ KBUILD_MODNAME); ++ printk(KERN_INFO "\tif this works, please send the output "); ++ printk(KERN_INFO "of 'dmidecode' to dave@sr71.net\n"); ++ nr_devices++; ++ } ++ ++ if (nr_devices <= 0) { ++ printk(KERN_INFO "%s: no LED devices found\n", ++ KBUILD_MODNAME); ++ return -ENODEV; ++ } ++ ++ printk(KERN_INFO "registering %s PCI driver\n", KBUILD_MODNAME); ++ ret = pci_register_driver(&nas_gpio_pci_driver); ++ if (ret) ++ return ret; ++ for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) { ++ ret = register_nasgpio_led(i); ++ if (ret) ++ goto out_err; ++ } ++ /* ++ * When the system powers on, the BIOS leaves the power ++ * light blue and blinking. This will turn it solid ++ * amber once the driver is loaded. ++ */ ++ set_power_light_amber_noblink(); ++ return 0; ++out_err: ++ for (; i >= 0; i--) ++ unregister_nasgpio_led(i); ++ pci_unregister_driver(&nas_gpio_pci_driver); ++ return ret; ++} ++ ++/* ++ * module unload ++ */ ++static void __exit nas_gpio_exit(void) ++{ ++ int i; ++ printk(KERN_INFO "Unregistering %s driver\n", KBUILD_MODNAME); ++ for (i = 0; i < ARRAY_SIZE(nasgpio_leds); i++) ++ unregister_nasgpio_led(i); ++ pci_unregister_driver(&nas_gpio_pci_driver); ++} ++ ++module_init(nas_gpio_init); ++module_exit(nas_gpio_exit); diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c new file mode 100644 index 0000000..c586d05 @@ -517615,27 +527740,27 @@ index 479dd05..94159b9 100644 error: diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h -index 487919b..895e2ef 100644 +index 487919b..01fc704 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h -@@ -30,7 +30,12 @@ +@@ -30,7 +30,11 @@ #define DVB_MAJOR 212 +-#define DVB_MAX_ADAPTERS 8 +#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0 -+#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS ++ #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS +#else -+#warning invalid CONFIG_DVB_MAX_ADAPTERS value - #define DVB_MAX_ADAPTERS 8 ++ #define DVB_MAX_ADAPTERS 8 +#endif #define DVB_UNSET (-1) diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig -index 496c1a3..0e4b97f 100644 +index 496c1a3..9744b06 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig -@@ -71,6 +71,7 @@ config DVB_USB_DIB0700 +@@ -71,10 +71,11 @@ config DVB_USB_DIB0700 depends on DVB_USB select DVB_DIB7000P if !DVB_FE_CUSTOMISE select DVB_DIB7000M if !DVB_FE_CUSTOMISE @@ -517643,6 +527768,11 @@ index 496c1a3..0e4b97f 100644 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT3305 if !DVB_FE_CUSTOMISE +- select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE ++ select DVB_TUNER_DIB0070 + select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE @@ -87,7 +88,7 @@ config DVB_USB_DIB0700 Avermedia and other big and small companies. @@ -570649,7 +580779,7 @@ index 0000000..4b329fd +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c new file mode 100644 -index 0000000..bb6df1b +index 0000000..6f094a9 --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-api.c @@ -0,0 +1,600 @@ @@ -571070,7 +581200,7 @@ index 0000000..bb6df1b + goto out; + } + -+ if (debug & DBGLVL_API) ++ if (saa_debug & DBGLVL_API) + saa7164_dumphex16(dev, buf, (buflen/16)*16); + + saa7164_api_dump_subdevs(dev, buf, buflen); @@ -571135,7 +581265,7 @@ index 0000000..bb6df1b + + dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len); + -+ if (debug & DBGLVL_I2C) ++ if (saa_debug & DBGLVL_I2C) + saa7164_dumphex16(dev, buf, 2 * 16); + + ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR, @@ -571143,7 +581273,7 @@ index 0000000..bb6df1b + if (ret != SAA_OK) + printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret); + else { -+ if (debug & DBGLVL_I2C) ++ if (saa_debug & DBGLVL_I2C) + saa7164_dumphex16(dev, buf, sizeof(buf)); + memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen); + } @@ -571203,7 +581333,7 @@ index 0000000..bb6df1b + *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen; + memcpy((buf + 2 * sizeof(u32)), data, datalen); + -+ if (debug & DBGLVL_I2C) ++ if (saa_debug & DBGLVL_I2C) + saa7164_dumphex16(dev, buf, sizeof(buf)); + + ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR, @@ -572500,7 +582630,7 @@ index 0000000..a3c2994 + diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c new file mode 100644 -index 0000000..e097f1a +index 0000000..c45966e --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-cmd.c @@ -0,0 +1,572 @@ @@ -572756,7 +582886,7 @@ index 0000000..e097f1a + unsigned long stamp; + int r; + -+ if (debug >= 4) ++ if (saa_debug >= 4) + saa7164_bus_dump(dev); + + dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno); @@ -573078,7 +583208,7 @@ index 0000000..e097f1a + diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c new file mode 100644 -index 0000000..f0dbead +index 0000000..709affc --- /dev/null +++ b/drivers/media/video/saa7164/saa7164-core.c @@ -0,0 +1,740 @@ @@ -573129,8 +583259,8 @@ index 0000000..f0dbead + 32 bus + */ + -+unsigned int debug; -+module_param(debug, int, 0644); ++unsigned int saa_debug; ++module_param_named(debug, saa_debug, int, 0644); +MODULE_PARM_DESC(debug, "enable debug messages"); + +unsigned int waitsecs = 10; @@ -573737,7 +583867,7 @@ index 0000000..f0dbead + printk(KERN_ERR "%s() Unsupported board detected, " + "registering without firmware\n", __func__); + -+ dprintk(1, "%s() parameter debug = %d\n", __func__, debug); ++ dprintk(1, "%s() parameter debug = %d\n", __func__, saa_debug); + dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs); + +fail_fw: @@ -575663,7 +585793,7 @@ index 0000000..99093f2 + diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h new file mode 100644 -index 0000000..6753008 +index 0000000..42660b5 --- /dev/null +++ b/drivers/media/video/saa7164/saa7164.h @@ -0,0 +1,400 @@ @@ -576044,9 +586174,9 @@ index 0000000..6753008 + +/* ----------------------------------------------------------- */ + -+extern unsigned int debug; ++extern unsigned int saa_debug; +#define dprintk(level, fmt, arg...)\ -+ do { if (debug & level)\ ++ do { if (saa_debug & level)\ + printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ + } while (0) + @@ -581569,11 +591699,31 @@ index aa5065e..269ab04 100644 i2c_set_clientdata(client, NULL); kfree(priv); return 0; +diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c +index 6ba16ab..e0f91e4 100644 +--- a/drivers/media/video/usbvision/usbvision-core.c ++++ b/drivers/media/video/usbvision/usbvision-core.c +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c -index 1fe5bef..f97fd06 100644 +index 1fe5bef..c19f51d 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c -@@ -246,9 +246,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -246,9 +245,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) switch (usbvision_device_data[usbvision->DevModel].Codec) { case CODEC_SAA7113: case CODEC_SAA7111: @@ -581585,7 +591735,7 @@ index 1fe5bef..f97fd06 100644 break; } if (usbvision_device_data[usbvision->DevModel].Tuner == 1) { -@@ -256,16 +256,16 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) +@@ -256,16 +255,16 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision) enum v4l2_i2c_tuner_type type; struct tuner_setup tun_setup; @@ -581606,6 +591756,18 @@ index 1fe5bef..f97fd06 100644 if (usbvision->tuner_type != -1) { tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; +diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c +index 90d9b5c..a2a50d6 100644 +--- a/drivers/media/video/usbvision/usbvision-video.c ++++ b/drivers/media/video/usbvision/usbvision-video.c +@@ -52,7 +52,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 36a6ba9..c3225a5 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c @@ -588334,6 +598496,21 @@ index 2622a6e..9aae011 100644 } +diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c +index a5b448e..b3bf1c4 100644 +--- a/drivers/memstick/core/memstick.c ++++ b/drivers/memstick/core/memstick.c +@@ -339,9 +339,9 @@ static int h_memstick_read_dev_id(struct memstick_dev *card, + card->id.type = id_reg.type; + card->id.category = id_reg.category; + card->id.class = id_reg.class; ++ dev_dbg(&card->dev, "if_mode = %02x\n", id_reg.if_mode); + } + complete(&card->mrq_complete); +- dev_dbg(&card->dev, "if_mode = %02x\n", id_reg.if_mode); + return -EAGAIN; + } + } diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 7847bbc..bd83fa0 100644 --- a/drivers/memstick/core/mspro_block.c @@ -596002,6 +606179,35 @@ index 1bfe5d1..3648b23 100644 lkdtm.entry = (kprobe_opcode_t*) jp_do_irq; break; case INT_HW_IRQ_EN: +diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c +index 79689b1..766e21e 100644 +--- a/drivers/misc/sgi-gru/grukservices.c ++++ b/drivers/misc/sgi-gru/grukservices.c +@@ -937,6 +937,8 @@ static int quicktest1(unsigned long arg) + + /* Need 1K cacheline aligned that does not cross page boundary */ + p = kmalloc(4096, 0); ++ if (p == NULL) ++ return -ENOMEM; + mq = ALIGNUP(p, 1024); + memset(mes, 0xee, sizeof(mes)); + dw = mq; +diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c +index 9cbf95b..ccd4408 100644 +--- a/drivers/misc/sgi-gru/gruprocfs.c ++++ b/drivers/misc/sgi-gru/gruprocfs.c +@@ -340,10 +340,9 @@ static struct proc_dir_entry *proc_gru __read_mostly; + + static int create_proc_file(struct proc_entry *p) + { +- p->entry = create_proc_entry(p->name, p->mode, proc_gru); ++ p->entry = proc_create(p->name, p->mode, proc_gru, p->fops); + if (!p->entry) + return -1; +- p->entry->proc_fops = p->fops; + return 0; + } + diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index 915a3b4..8b70e03 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c @@ -602309,7 +612515,7 @@ index 578de1c..f4359fe 100644 addr = instr->addr; len = instr->len; diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c -index 10ed195..379c316 100644 +index 10ed195..933267a 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -44,6 +44,11 @@ @@ -602485,7 +612691,23 @@ index 10ed195..379c316 100644 /* ST Microelectronics -- newer production may have feature updates */ { "m25p05", 0x202010, 0, 32 * 1024, 2, }, -@@ -667,7 +795,12 @@ static int __devinit m25p_probe(struct spi_device *spi) +@@ -647,11 +775,12 @@ static int __devinit m25p_probe(struct spi_device *spi) + dev_set_drvdata(&spi->dev, flash); + + /* +- * Atmel serial flash tend to power up +- * with the software protection bits set ++ * Atmel and SST serial flash tend to power ++ * up with the software protection bits set + */ + +- if (info->jedec_id >> 16 == 0x1f) { ++ if (info->jedec_id >> 16 == 0x1f || ++ info->jedec_id >> 16 == 0xbf) { + write_enable(flash); + write_sr(flash, 0); + } +@@ -667,7 +796,12 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.size = info->sector_size * info->n_sectors; flash->mtd.erase = m25p80_erase; flash->mtd.read = m25p80_read; @@ -602499,7 +612721,7 @@ index 10ed195..379c316 100644 /* prefer "small sector" erase if possible */ if (info->flags & SECT_4K) { -@@ -776,13 +909,13 @@ static struct spi_driver m25p80_driver = { +@@ -776,13 +910,13 @@ static struct spi_driver m25p80_driver = { }; @@ -603191,7 +613413,7 @@ index d8cf29c..8aca552 /* * Hopefully we free something, lets try again. diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig -index 7a58bd5..841e085 100644 +index 7a58bd5..14be075 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -74,7 +74,7 @@ config MTD_PHYSMAP_BANKWIDTH @@ -603203,12 +613425,13 @@ index 7a58bd5..841e085 100644 help This provides a 'mapping' driver which allows the NOR Flash and ROM driver code to communicate with chips which are mapped -@@ -484,9 +484,19 @@ config MTD_BFIN_ASYNC +@@ -484,9 +484,20 @@ config MTD_BFIN_ASYNC If compiled as a module, it will be called bfin-async-flash. +config MTD_GPIO_ADDR + tristate "GPIO-assisted Flash Chip Support" ++ depends on GENERIC_GPIO || GPIOLIB + depends on MTD_COMPLEX_MAPPINGS + select MTD_PARTITIONS + help @@ -603283,10 +613506,10 @@ index 42969fe..b3cb3a1 100644 MODULE_DESCRIPTION("MTD map driver for DC21285 boards"); diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c new file mode 100644 -index 0000000..44ef9a4 +index 0000000..1ad5caf --- /dev/null +++ b/drivers/mtd/maps/gpio-addr-flash.c -@@ -0,0 +1,311 @@ +@@ -0,0 +1,310 @@ +/* + * drivers/mtd/maps/gpio-addr-flash.c + * @@ -603302,7 +613525,9 @@ index 0000000..44ef9a4 + * Licensed under the GPL-2 or later. + */ + ++#include +#include ++#include +#include +#include +#include @@ -603312,9 +613537,6 @@ index 0000000..44ef9a4 +#include +#include + -+#include -+#include -+ +#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) + +#define DRIVER_NAME "gpio-addr-flash" @@ -604310,7 +614532,7 @@ index 76beea4..65b26d5 100644 if (this->ecc.mode == NAND_ECC_HW) { switch (mtd->oobsize) { diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c -index 8c21b89..2211386 100644 +index 8c21b89..2957cc7 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -688,8 +688,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) @@ -604323,7 +614545,12 @@ index 8c21b89..2211386 100644 if (!chip->controller->active) chip->controller->active = chip; -@@ -766,7 +765,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) +@@ -762,11 +761,12 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data ++ * @page: page number to read + * * Not for syndrome calculating ecc controllers, which use a special oob layout */ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, @@ -604332,7 +614559,12 @@ index 8c21b89..2211386 100644 { chip->read_buf(mtd, buf, mtd->writesize); chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); -@@ -782,7 +781,7 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, +@@ -778,11 +778,12 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data ++ * @page: page number to read + * * We need a special oob layout and handling even when OOB isn't used. */ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip, @@ -604341,8 +614573,11 @@ index 8c21b89..2211386 100644 { int eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; -@@ -821,7 +820,7 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *c +@@ -819,9 +820,10 @@ static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *c + * @mtd: mtd info structure + * @chip: nand chip info structure * @buf: buffer to store read data ++ * @page: page number to read */ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, - uint8_t *buf) @@ -604350,7 +614585,7 @@ index 8c21b89..2211386 100644 { int i, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; -@@ -831,7 +830,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, +@@ -831,7 +833,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *ecc_code = chip->buffers->ecccode; uint32_t *eccpos = chip->ecc.layout->eccpos; @@ -604359,7 +614594,12 @@ index 8c21b89..2211386 100644 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) chip->ecc.calculate(mtd, p, &ecc_calc[i]); -@@ -944,7 +943,7 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3 +@@ -940,11 +942,12 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint3 + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data ++ * @page: page number to read + * * Not for syndrome calculating ecc controllers which need a special oob layout */ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, @@ -604368,7 +614608,7 @@ index 8c21b89..2211386 100644 { int i, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; -@@ -980,6 +979,54 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, +@@ -980,16 +983,66 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, } /** @@ -604376,6 +614616,7 @@ index 8c21b89..2211386 100644 + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data ++ * @page: page number to read + * + * Hardware ECC for large page chips, require OOB to be read first. + * For this ECC mode, the write_page method is re-used from ECC_HW. @@ -604423,7 +614664,10 @@ index 8c21b89..2211386 100644 * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read * @mtd: mtd info structure * @chip: nand chip info structure -@@ -989,7 +1036,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, + * @buf: buffer to store read data ++ * @page: page number to read + * + * The hw generator calculates the error syndrome automatically. Therefor * we need a special oob layout and handling. */ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, @@ -604432,7 +614676,7 @@ index 8c21b89..2211386 100644 { int i, eccsize = chip->ecc.size; int eccbytes = chip->ecc.bytes; -@@ -1131,11 +1178,13 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, +@@ -1131,11 +1184,13 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, /* Now read the page into the buffer */ if (unlikely(ops->mode == MTD_OOB_RAW)) @@ -604448,7 +614692,7 @@ index 8c21b89..2211386 100644 if (ret < 0) break; -@@ -1413,8 +1462,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, +@@ -1413,8 +1468,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, int len; uint8_t *buf = ops->oobbuf; @@ -604459,7 +614703,7 @@ index 8c21b89..2211386 100644 if (ops->mode == MTD_OOB_AUTO) len = chip->ecc.layout->oobavail; -@@ -1422,8 +1471,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, +@@ -1422,8 +1477,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, len = mtd->oobsize; if (unlikely(ops->ooboffs >= len)) { @@ -604470,7 +614714,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -1431,8 +1480,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, +@@ -1431,8 +1486,8 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, if (unlikely(from >= mtd->size || ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) - (from >> chip->page_shift)) * len)) { @@ -604481,7 +614725,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -1506,8 +1555,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, +@@ -1506,8 +1561,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, /* Do not allow reads past end of device */ if (ops->datbuf && (from + ops->len) > mtd->size) { @@ -604492,7 +614736,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -1816,8 +1865,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, +@@ -1816,8 +1871,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, /* reject writes, which are not page aligned */ if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { @@ -604503,7 +614747,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -1944,8 +1993,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +@@ -1944,8 +1999,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, int chipnr, page, status, len; struct nand_chip *chip = mtd->priv; @@ -604514,7 +614758,7 @@ index 8c21b89..2211386 100644 if (ops->mode == MTD_OOB_AUTO) len = chip->ecc.layout->oobavail; -@@ -1954,14 +2003,14 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +@@ -1954,14 +2009,14 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, /* Do not allow write past end of page */ if ((ops->ooboffs + ops->ooblen) > len) { @@ -604533,7 +614777,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -1970,8 +2019,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, +@@ -1970,8 +2025,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, ops->ooboffs + ops->ooblen > ((mtd->size >> chip->page_shift) - (to >> chip->page_shift)) * len)) { @@ -604544,7 +614788,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -2026,8 +2075,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, +@@ -2026,8 +2081,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, /* Do not allow writes past end of device */ if (ops->datbuf && (to + ops->len) > mtd->size) { @@ -604555,7 +614799,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -2117,26 +2166,27 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, +@@ -2117,26 +2172,27 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, unsigned int bbt_masked_page = 0xffffffff; loff_t len; @@ -604590,7 +614834,7 @@ index 8c21b89..2211386 100644 return -EINVAL; } -@@ -2157,8 +2207,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, +@@ -2157,8 +2213,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, /* Check, if it is write protected */ if (nand_check_wp(mtd)) { @@ -604601,7 +614845,7 @@ index 8c21b89..2211386 100644 instr->state = MTD_ERASE_FAILED; goto erase_exit; } -@@ -2183,8 +2233,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, +@@ -2183,8 +2239,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, */ if (nand_block_checkbad(mtd, ((loff_t) page) << chip->page_shift, 0, allowbbt)) { @@ -604612,7 +614856,7 @@ index 8c21b89..2211386 100644 instr->state = MTD_ERASE_FAILED; goto erase_exit; } -@@ -2211,8 +2261,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, +@@ -2211,8 +2267,8 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, /* See if block erase succeeded */ if (status & NAND_STATUS_FAIL) { @@ -604623,7 +614867,7 @@ index 8c21b89..2211386 100644 instr->state = MTD_ERASE_FAILED; instr->fail_addr = ((loff_t)page << chip->page_shift); -@@ -2272,9 +2322,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, +@@ -2272,9 +2328,9 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, if (!rewrite_bbt[chipnr]) continue; /* update the BBT for chip */ @@ -604636,7 +614880,7 @@ index 8c21b89..2211386 100644 nand_update_bbt(mtd, rewrite_bbt[chipnr]); } -@@ -2292,7 +2342,7 @@ static void nand_sync(struct mtd_info *mtd) +@@ -2292,7 +2348,7 @@ static void nand_sync(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; @@ -604645,7 +614889,7 @@ index 8c21b89..2211386 100644 /* Grab the lock and see if the device is available */ nand_get_device(chip, mtd, FL_SYNCING); -@@ -2356,8 +2406,8 @@ static void nand_resume(struct mtd_info *mtd) +@@ -2356,8 +2412,8 @@ static void nand_resume(struct mtd_info *mtd) if (chip->state == FL_PM_SUSPENDED) nand_release_device(mtd); else @@ -604656,7 +614900,7 @@ index 8c21b89..2211386 100644 } /* -@@ -2671,6 +2721,17 @@ int nand_scan_tail(struct mtd_info *mtd) +@@ -2671,6 +2727,17 @@ int nand_scan_tail(struct mtd_info *mtd) */ switch (chip->ecc.mode) { @@ -604674,7 +614918,7 @@ index 8c21b89..2211386 100644 case NAND_ECC_HW: /* Use standard hwecc read page function ? */ if (!chip->ecc.read_page) -@@ -2693,7 +2754,7 @@ int nand_scan_tail(struct mtd_info *mtd) +@@ -2693,7 +2760,7 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.read_page == nand_read_page_hwecc || !chip->ecc.write_page || chip->ecc.write_page == nand_write_page_hwecc)) { @@ -604683,7 +614927,7 @@ index 8c21b89..2211386 100644 "Hardware ECC not possible\n"); BUG(); } -@@ -2728,7 +2789,8 @@ int nand_scan_tail(struct mtd_info *mtd) +@@ -2728,7 +2795,8 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.write_page_raw = nand_write_page_raw; chip->ecc.read_oob = nand_read_oob_std; chip->ecc.write_oob = nand_write_oob_std; @@ -604693,7 +614937,7 @@ index 8c21b89..2211386 100644 chip->ecc.bytes = 3; break; -@@ -2858,7 +2920,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) +@@ -2858,7 +2926,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips) /* Many callers got this wrong, so check for it for a while... */ if (!mtd->owner && caller_is_module()) { @@ -606993,9 +617237,18 @@ index 69f5b7d..b1e5764 100644 EXPORT_SYMBOL_GPL(lance_start_xmit); diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c -index d0dbbf3..462d9f5 100644 +index d0dbbf3..83a1922 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c +@@ -87,7 +87,7 @@ + + /* These identify the driver base version and may not be removed. */ + static char version[] = +-KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; ++DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n"; + + MODULE_AUTHOR("Jeff Garzik "); + MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver"); @@ -736,7 +736,8 @@ static void cp_tx (struct cp_private *cp) netif_wake_queue(cp->dev); } @@ -607148,7 +617401,7 @@ index d225c29..a2a64ea 100644 return __ei_start_xmit(skb, dev); } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig -index 5ce7cba..ed5741b 100644 +index 5ce7cba..2bea67c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -209,7 +209,7 @@ config MII @@ -607169,6 +617422,15 @@ index 5ce7cba..ed5741b 100644 select PHYLIB help TI AR7 CPMAC Ethernet support +@@ -1875,7 +1875,7 @@ config 68360_ENET + + config FEC + bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" +- depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 ++ depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 || ARCH_MX25 + help + Say Y here if you want to use the built-in 10/100 Fast ethernet + controller on some Motorola ColdFire and Freescale i.MX processors. @@ -1928,6 +1928,21 @@ config ATL2 To compile this driver as a module, choose M here. The module will be called atl2. @@ -608144,7 +618406,7 @@ index 00d11b4..9b1e0ea 100644 .set_settings = atl1c_set_settings, .get_drvinfo = atl1c_get_drvinfo, diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c -index a383122..be2c6cf 100644 +index a383122..1372e9a 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -534,10 +534,6 @@ static int atl1c_mii_ioctl(struct net_device *netdev, @@ -608187,6 +618449,15 @@ index a383122..be2c6cf 100644 { struct atl1c_adapter *adapter = netdev_priv(netdev); unsigned long flags; +@@ -2304,7 +2296,7 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) + u32 ctrl; + u32 mac_ctrl_data; + u32 master_ctrl_data; +- u32 wol_ctrl_data; ++ u32 wol_ctrl_data = 0; + u16 mii_bmsr_data; + u16 save_autoneg_advertised; + u16 mii_intr_status_data; @@ -2678,6 +2670,9 @@ static pci_ers_result_t atl1c_io_error_detected(struct pci_dev *pdev, netif_device_detach(netdev); @@ -628660,7 +638931,7 @@ index 6290a50..6824771 100644 struct tlb_slave_info tlb_info; }; diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig -index 33821a8..6ac5aa5 100644 +index 33821a8..df32c10 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -41,6 +41,13 @@ config CAN_SJA1000 @@ -628700,17 +638971,31 @@ index 33821a8..6ac5aa5 100644 config CAN_KVASER_PCI tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards" +@@ -74,6 +89,12 @@ config CAN_KVASER_PCI + This driver is for the the PCIcanx and PCIcan cards (1, 2 or + 4 channel) from Kvaser (http://www.kvaser.com). + ++config CAN_AT91 ++ tristate "Atmel AT91 onchip CAN controller" ++ depends on CAN && CAN_DEV && ARCH_AT91SAM9263 ++ ---help--- ++ This is a driver for the SoC CAN controller in Atmel's AT91SAM9263. ++ + config CAN_DEBUG_DEVICES + bool "CAN devices debugging messages" + depends on CAN diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile -index 523a941..9b035ec 100644 +index 523a941..0dea627 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile -@@ -7,6 +7,8 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o +@@ -7,6 +7,9 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o obj-$(CONFIG_CAN_DEV) += can-dev.o can-dev-y := dev.o +obj-y += usb/ + obj-$(CONFIG_CAN_SJA1000) += sja1000/ ++obj-$(CONFIG_CAN_AT91) += at91_can.o ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c @@ -630645,9 +640930,27 @@ index 8c94051..00cc37f 100644 void t1_sge_start(struct sge *); void t1_sge_stop(struct sge *); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c -index 74c3429..d45eacb 100644 +index 74c3429..211c8e9 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c +@@ -85,8 +85,6 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) + + cp->uio_dev = iminor(inode); + +- cnic_shutdown_bnx2_rx_ring(dev); +- + cnic_init_bnx2_tx_ring(dev); + cnic_init_bnx2_rx_ring(dev); + +@@ -98,6 +96,8 @@ static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) + struct cnic_dev *dev = uinfo->priv; + struct cnic_local *cp = dev->cnic_priv; + ++ cnic_shutdown_bnx2_rx_ring(dev); ++ + cp->uio_dev = -1; + return 0; + } @@ -774,42 +774,34 @@ static int cnic_alloc_context(struct cnic_dev *dev) return 0; } @@ -630668,11 +640971,11 @@ index 74c3429..d45eacb 100644 - if (ret) - goto error; - cp->kcq = (struct kcqe **) cp->kcq_info.pg_arr; -- + - ret = cnic_alloc_context(dev); - if (ret) - goto error; - +- - cp->l2_ring_size = 2 * BCM_PAGE_SIZE; + cp->l2_ring_size = pages * BCM_PAGE_SIZE; cp->l2_ring = pci_alloc_consistent(dev->pcidev, cp->l2_ring_size, @@ -634341,6 +644644,18 @@ index 1f016d6..592de8f 100644 } /* +diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c +index 977c3d3..41bd7ae 100644 +--- a/drivers/net/ehea/ehea_main.c ++++ b/drivers/net/ehea/ehea_main.c +@@ -3083,7 +3083,6 @@ static const struct net_device_ops ehea_netdev_ops = { + .ndo_poll_controller = ehea_netpoll, + #endif + .ndo_get_stats = ehea_get_stats, +- .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = ehea_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_multicast_list = ehea_set_multicast_list, diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 3747457..bc7c5b7 100644 --- a/drivers/net/ehea/ehea_qmr.c @@ -643641,6 +653956,36 @@ index b9ceddd..bffb799 100644 if (err) goto err_out_async; +diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c +index cee199c..3c16602 100644 +--- a/drivers/net/mlx4/fw.c ++++ b/drivers/net/mlx4/fw.c +@@ -33,6 +33,7 @@ + */ + + #include ++#include + + #include "fw.h" + #include "icm.h" +@@ -698,6 +699,7 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) + #define INIT_HCA_IN_SIZE 0x200 + #define INIT_HCA_VERSION_OFFSET 0x000 + #define INIT_HCA_VERSION 2 ++#define INIT_HCA_CACHELINE_SZ_OFFSET 0x0e + #define INIT_HCA_FLAGS_OFFSET 0x014 + #define INIT_HCA_QPC_OFFSET 0x020 + #define INIT_HCA_QPC_BASE_OFFSET (INIT_HCA_QPC_OFFSET + 0x10) +@@ -735,6 +737,9 @@ int mlx4_INIT_HCA(struct mlx4_dev *dev, struct mlx4_init_hca_param *param) + + *((u8 *) mailbox->buf + INIT_HCA_VERSION_OFFSET) = INIT_HCA_VERSION; + ++ *((u8 *) mailbox->buf + INIT_HCA_CACHELINE_SZ_OFFSET) = ++ (ilog2(cache_line_size()) - 4) << 5; ++ + #if defined(__LITTLE_ENDIAN) + *(inbox + INIT_HCA_FLAGS_OFFSET / 4) &= ~cpu_to_be32(1 << 1); + #elif defined(__BIG_ENDIAN) diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c index baf4bf6..04b382f 100644 --- a/drivers/net/mlx4/icm.c @@ -647908,7 +658253,7 @@ index 5d3343e..91c2bc6 100644 } spin_unlock(&rds_ring->lock); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c -index 28f270f..f7bdde1 100644 +index 28f270f..b5aa974 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -1,5 +1,6 @@ @@ -648865,7 +659210,7 @@ index 28f270f..f7bdde1 100644 if (err) { dev_err(&pdev->dev, "failed to start firmware\n"); return err; -@@ -1269,16 +1457,24 @@ netxen_nic_resume(struct pci_dev *pdev) +@@ -1269,16 +1457,25 @@ netxen_nic_resume(struct pci_dev *pdev) if (netif_running(netdev)) { err = netxen_nic_attach(adapter); if (err) @@ -648882,8 +659227,8 @@ index 28f270f..f7bdde1 100644 + netxen_config_indev_addr(netdev, NETDEV_UP); } -- return 0; + netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY); + return 0; + +err_out_detach: + netxen_nic_detach(adapter); @@ -648893,7 +659238,7 @@ index 28f270f..f7bdde1 100644 } #endif -@@ -1290,11 +1486,9 @@ static int netxen_nic_open(struct net_device *netdev) +@@ -1290,11 +1487,9 @@ static int netxen_nic_open(struct net_device *netdev) if (adapter->driver_mismatch) return -EIO; @@ -648908,7 +659253,7 @@ index 28f270f..f7bdde1 100644 err = netxen_nic_up(adapter, netdev); if (err) -@@ -1320,30 +1514,52 @@ static int netxen_nic_close(struct net_device *netdev) +@@ -1320,30 +1515,52 @@ static int netxen_nic_close(struct net_device *netdev) return 0; } @@ -648970,7 +659315,7 @@ index 28f270f..f7bdde1 100644 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { u8 l4proto; -@@ -1364,55 +1580,133 @@ static bool netxen_tso_check(struct net_device *netdev, +@@ -1364,55 +1581,133 @@ static bool netxen_tso_check(struct net_device *netdev, opcode = TX_UDPV6_PKT; } } @@ -649052,22 +659397,22 @@ index 28f270f..f7bdde1 100644 + + nr_frags = skb_shinfo(skb)->nr_frags; + nf = &pbuf->frag_array[0]; - -- buffrag = &pbuf->frag_array[0]; -- pci_unmap_single(pdev, buffrag->dma, -- buffrag->length, PCI_DMA_TODEVICE); ++ + map = pci_map_single(pdev, skb->data, + skb_headlen(skb), PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, map)) + goto out_err; +- buffrag = &pbuf->frag_array[0]; +- pci_unmap_single(pdev, buffrag->dma, +- buffrag->length, PCI_DMA_TODEVICE); ++ nf->dma = map; ++ nf->length = skb_headlen(skb); + - for (k = 1; k < last; k++) { - buffrag = &pbuf->frag_array[k]; - pci_unmap_page(pdev, buffrag->dma, - buffrag->length, PCI_DMA_TODEVICE); -+ nf->dma = map; -+ nf->length = skb_headlen(skb); -+ + for (i = 0; i < nr_frags; i++) { + frag = &skb_shinfo(skb)->frags[i]; + nf = &pbuf->frag_array[i+1]; @@ -649079,7 +659424,7 @@ index 28f270f..f7bdde1 100644 + + nf->dma = map; + nf->length = frag->size; - } ++ } + + return 0; + @@ -649087,7 +659432,7 @@ index 28f270f..f7bdde1 100644 + while (--i >= 0) { + nf = &pbuf->frag_array[i+1]; + pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE); -+ } + } + + nf = &pbuf->frag_array[0]; + pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE); @@ -649129,7 +659474,7 @@ index 28f270f..f7bdde1 100644 frag_count = skb_shinfo(skb)->nr_frags + 1; -@@ -1425,121 +1719,60 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +@@ -1425,121 +1720,60 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } producer = tx_ring->producer; @@ -649274,7 +659619,7 @@ index 28f270f..f7bdde1 100644 adapter->stats.xmitcalled++; return NETDEV_TX_OK; -@@ -1635,58 +1868,14 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) +@@ -1635,58 +1869,14 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) netxen_advert_link_change(adapter, linkup); } @@ -649322,14 +659667,14 @@ index 28f270f..f7bdde1 100644 + if (test_bit(__NX_RESETTING, &adapter->state)) return; - } -- + - if (adapter->link_changed) - netxen_nic_set_link_parameters(adapter); - - if (netif_running(adapter->netdev)) - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); -} - +- -static void netxen_tx_timeout(struct net_device *netdev) -{ - struct netxen_adapter *adapter = netdev_priv(netdev); @@ -649337,7 +659682,7 @@ index 28f270f..f7bdde1 100644 schedule_work(&adapter->tx_timeout_task); } -@@ -1698,15 +1887,37 @@ static void netxen_tx_timeout_task(struct work_struct *work) +@@ -1698,15 +1888,36 @@ static void netxen_tx_timeout_task(struct work_struct *work) if (!netif_running(adapter->netdev)) return; @@ -649349,26 +659694,27 @@ index 28f270f..f7bdde1 100644 - netxen_napi_disable(adapter); + if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS) + goto request_reset; - -- adapter->netdev->trans_start = jiffies; ++ + if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { + /* try to scrub interrupt */ + netxen_napi_disable(adapter); +- adapter->netdev->trans_start = jiffies; ++ adapter->netdev->trans_start = jiffies; + - netxen_napi_enable(adapter); - netif_wake_queue(adapter->netdev); -+ adapter->netdev->trans_start = jiffies; -+ + netxen_napi_enable(adapter); + + netif_wake_queue(adapter->netdev); + -+ goto done; ++ clear_bit(__NX_RESETTING, &adapter->state); + + } else { ++ clear_bit(__NX_RESETTING, &adapter->state); + if (!netxen_nic_reset_context(adapter)) { + adapter->netdev->trans_start = jiffies; -+ goto done; ++ return; + } + + /* context reset failed, fall through for fw reset */ @@ -649376,8 +659722,6 @@ index 28f270f..f7bdde1 100644 + +request_reset: + adapter->need_fw_reset = 1; -+done: -+ clear_bit(__NX_RESETTING, &adapter->state); } struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) @@ -651227,7 +661571,7 @@ index 36de91b..5ed6339 100644 /* ---------------------------------------------------------------------------- diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c -index 9ef1c1b..97db1c7 100644 +index 9ef1c1b..474876c 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -40,6 +40,7 @@ @@ -651238,7 +661582,25 @@ index 9ef1c1b..97db1c7 100644 #include "../8390.h" #include -@@ -1191,7 +1192,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { +@@ -339,12 +340,11 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link) + base = &virt[hw_info[i].offset & (req.Size-1)]; + if ((readb(base+0) == hw_info[i].a0) && + (readb(base+2) == hw_info[i].a1) && +- (readb(base+4) == hw_info[i].a2)) +- break; +- } +- if (i < NR_INFO) { +- for (j = 0; j < 6; j++) +- dev->dev_addr[j] = readb(base + (j<<1)); ++ (readb(base+4) == hw_info[i].a2)) { ++ for (j = 0; j < 6; j++) ++ dev->dev_addr[j] = readb(base + (j<<1)); ++ break; ++ } + } + + iounmap(virt); +@@ -1191,7 +1191,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { pcnet_dev_t *info = PRIV(dev); @@ -651247,7 +661609,7 @@ index 9ef1c1b..97db1c7 100644 unsigned int mii_addr = dev->base_addr + DLINK_GPIO; if (!(info->flags & (IS_DL10019|IS_DL10022))) -@@ -1199,14 +1200,12 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +@@ -1199,14 +1199,12 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) switch (cmd) { case SIOCGMIIPHY: @@ -651265,7 +661627,7 @@ index 9ef1c1b..97db1c7 100644 return 0; } return -EOPNOTSUPP; -@@ -1751,11 +1750,11 @@ static struct pcmcia_device_id pcnet_ids[] = { +@@ -1751,11 +1749,11 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078), /* too generic! */ /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */ @@ -660937,7 +671299,7 @@ index 543af20..55bad40 100644 struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c -index 0a551d8..15140f9 100644 +index 0a551d8..ef11657 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -50,7 +50,7 @@ @@ -661318,7 +671680,15 @@ index 0a551d8..15140f9 100644 sky2_mac_init(hw, port); /* Register is number of 4K blocks on internal RAM buffer. */ -@@ -1482,14 +1524,12 @@ static int sky2_up(struct net_device *dev) +@@ -1455,7 +1497,6 @@ static int sky2_up(struct net_device *dev) + if (ramsize > 0) { + u32 rxspace; + +- hw->flags |= SKY2_HW_RAM_BUFFER; + pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize); + if (ramsize < 16) + rxspace = ramsize / 2; +@@ -1482,14 +1523,12 @@ static int sky2_up(struct net_device *dev) sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV); sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, @@ -661334,7 +671704,7 @@ index 0a551d8..15140f9 100644 err = sky2_rx_start(sky2); if (err) goto err_out; -@@ -1500,47 +1540,26 @@ static int sky2_up(struct net_device *dev) +@@ -1500,47 +1539,26 @@ static int sky2_up(struct net_device *dev) sky2_write32(hw, B0_IMSK, imask); sky2_read32(hw, B0_IMSK); @@ -661387,7 +671757,7 @@ index 0a551d8..15140f9 100644 } /* Estimate of number of transmit list elements required */ -@@ -1548,11 +1567,13 @@ static unsigned tx_le_req(const struct sk_buff *skb) +@@ -1548,11 +1566,13 @@ static unsigned tx_le_req(const struct sk_buff *skb) { unsigned count; @@ -661403,7 +671773,7 @@ index 0a551d8..15140f9 100644 if (skb->ip_summed == CHECKSUM_PARTIAL) ++count; -@@ -1560,20 +1581,36 @@ static unsigned tx_le_req(const struct sk_buff *skb) +@@ -1560,20 +1580,36 @@ static unsigned tx_le_req(const struct sk_buff *skb) return count; } @@ -661442,7 +671812,7 @@ index 0a551d8..15140f9 100644 u16 mss; u8 ctrl; -@@ -1586,15 +1623,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1586,15 +1622,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) if (pci_dma_mapping_error(hw->pdev, mapping)) goto mapping_error; @@ -661465,7 +671835,7 @@ index 0a551d8..15140f9 100644 le->opcode = OP_ADDR64 | HW_OWNER; } -@@ -1606,7 +1645,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1606,7 +1644,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); if (mss != sky2->tx_last_mss) { @@ -661474,7 +671844,7 @@ index 0a551d8..15140f9 100644 le->addr = cpu_to_le32(mss); if (hw->flags & SKY2_HW_NEW_LE) -@@ -1622,7 +1661,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1622,7 +1660,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ if (sky2->vlgrp && vlan_tx_tag_present(skb)) { if (!le) { @@ -661483,7 +671853,7 @@ index 0a551d8..15140f9 100644 le->addr = 0; le->opcode = OP_VLAN|HW_OWNER; } else -@@ -1651,7 +1690,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1651,7 +1689,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) if (tcpsum != sky2->tx_tcpsum) { sky2->tx_tcpsum = tcpsum; @@ -661492,7 +671862,7 @@ index 0a551d8..15140f9 100644 le->addr = cpu_to_le32(tcpsum); le->length = 0; /* initial checksum value */ le->ctrl = 1; /* one packet */ -@@ -1660,16 +1699,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1660,16 +1698,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) } } @@ -661516,7 +671886,7 @@ index 0a551d8..15140f9 100644 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; -@@ -1680,27 +1720,31 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1680,27 +1719,31 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) if (pci_dma_mapping_error(hw->pdev, mapping)) goto mapping_unwind; @@ -661559,7 +671929,7 @@ index 0a551d8..15140f9 100644 if (tx_avail(sky2) <= MAX_SKB_TX_LE) netif_stop_queue(dev); -@@ -1709,27 +1753,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) +@@ -1709,27 +1752,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; mapping_unwind: @@ -661589,7 +671959,7 @@ index 0a551d8..15140f9 100644 mapping_error: if (net_ratelimit()) dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name); -@@ -1740,40 +1769,28 @@ mapping_error: +@@ -1740,40 +1768,28 @@ mapping_error: /* * Free ring elements from starting at tx_cons until "done" * @@ -661640,7 +672010,7 @@ index 0a551d8..15140f9 100644 if (unlikely(netif_msg_tx_done(sky2))) printk(KERN_DEBUG "%s: tx done %u\n", dev->name, idx); -@@ -1781,14 +1798,9 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) +@@ -1781,14 +1797,9 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; @@ -661657,7 +672027,7 @@ index 0a551d8..15140f9 100644 } } -@@ -1799,14 +1811,26 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) +@@ -1799,14 +1810,26 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) netif_wake_queue(dev); } @@ -661690,7 +672060,7 @@ index 0a551d8..15140f9 100644 } /* Network shutdown */ -@@ -1825,10 +1849,6 @@ static int sky2_down(struct net_device *dev) +@@ -1825,10 +1848,6 @@ static int sky2_down(struct net_device *dev) if (netif_msg_ifdown(sky2)) printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); @@ -661701,7 +672071,7 @@ index 0a551d8..15140f9 100644 /* Force flow control off */ sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); -@@ -1850,26 +1870,7 @@ static int sky2_down(struct net_device *dev) +@@ -1850,26 +1869,7 @@ static int sky2_down(struct net_device *dev) && port == 0 && hw->dev[1] && netif_running(hw->dev[1]))) sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); @@ -661728,7 +672098,7 @@ index 0a551d8..15140f9 100644 /* Force any delayed status interrrupt and NAPI */ sky2_write32(hw, STAT_LEV_TIMER_CNT, 0); -@@ -1888,28 +1889,18 @@ static int sky2_down(struct net_device *dev) +@@ -1888,28 +1888,18 @@ static int sky2_down(struct net_device *dev) synchronize_irq(hw->pdev->irq); napi_synchronize(&hw->napi); @@ -661738,33 +672108,33 @@ index 0a551d8..15140f9 100644 - /* turn off LED's */ - sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); -- ++ sky2_tx_reset(hw, port); + - sky2_tx_clean(dev); - sky2_rx_clean(sky2); - - pci_free_consistent(hw->pdev, RX_LE_BYTES, - sky2->rx_le, sky2->rx_le_map); - kfree(sky2->rx_ring); -+ sky2_tx_reset(hw, port); ++ /* Free any pending frames stuck in HW queue */ ++ sky2_tx_complete(sky2, sky2->tx_prod); - pci_free_consistent(hw->pdev, - TX_RING_SIZE * sizeof(struct sky2_tx_le), - sky2->tx_le, sky2->tx_le_map); - kfree(sky2->tx_ring); -+ /* Free any pending frames stuck in HW queue */ -+ sky2_tx_complete(sky2, sky2->tx_prod); ++ sky2_rx_clean(sky2); - sky2->tx_le = NULL; - sky2->rx_le = NULL; -+ sky2_rx_clean(sky2); - +- - sky2->rx_ring = NULL; - sky2->tx_ring = NULL; + sky2_free_buffers(sky2); return 0; } -@@ -2083,7 +2074,7 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) +@@ -2083,7 +2073,7 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", sky2->netdev->name, istatus, phystat); @@ -661773,7 +672143,7 @@ index 0a551d8..15140f9 100644 if (sky2_autoneg_done(sky2, phystat) == 0) sky2_link_up(sky2); goto out; -@@ -2370,11 +2361,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) +@@ -2370,11 +2360,8 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) { struct sky2_port *sky2 = netdev_priv(dev); @@ -661786,7 +672156,7 @@ index 0a551d8..15140f9 100644 } static inline void sky2_skb_rx(const struct sky2_port *sky2, -@@ -2452,7 +2440,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) +@@ -2452,7 +2439,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) /* This chip reports checksum status differently */ if (hw->flags & SKY2_HW_NEW_LE) { @@ -661795,7 +672165,7 @@ index 0a551d8..15140f9 100644 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && (le->css & CSS_TCPUDPCSOK)) skb->ip_summed = CHECKSUM_UNNECESSARY; -@@ -2479,7 +2467,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) +@@ -2479,7 +2466,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) /* fall through */ #endif case OP_RXCHKS: @@ -661804,7 +672174,7 @@ index 0a551d8..15140f9 100644 break; /* If this happens then driver assuming wrong format */ -@@ -2504,7 +2492,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) +@@ -2504,7 +2491,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) printk(KERN_NOTICE PFX "%s: hardware receive " "checksum problem (status = %#x)\n", dev->name, status); @@ -661814,7 +672184,7 @@ index 0a551d8..15140f9 100644 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_DIS_RX_CHKSUM); -@@ -2513,7 +2502,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) +@@ -2513,7 +2501,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) case OP_TXINDEXLE: /* TX index reports status for both ports */ @@ -661822,7 +672192,7 @@ index 0a551d8..15140f9 100644 sky2_tx_done(hw->dev[0], status & 0xfff); if (hw->dev[1]) sky2_tx_done(hw->dev[1], -@@ -2657,19 +2645,15 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) +@@ -2657,19 +2644,15 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) } /* This should never happen it is a bug. */ @@ -661848,7 +672218,7 @@ index 0a551d8..15140f9 100644 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); } -@@ -2755,16 +2739,16 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status) +@@ -2755,16 +2738,16 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status) sky2_mac_intr(hw, 1); if (status & Y2_IS_CHK_RX1) @@ -661869,7 +672239,17 @@ index 0a551d8..15140f9 100644 } static int sky2_poll(struct napi_struct *napi, int work_limit) -@@ -3009,8 +2993,6 @@ static void sky2_reset(struct sky2_hw *hw) +@@ -2942,6 +2925,9 @@ static int __devinit sky2_init(struct sky2_hw *hw) + ++hw->ports; + } + ++ if (sky2_read8(hw, B2_E_0)) ++ hw->flags |= SKY2_HW_RAM_BUFFER; ++ + return 0; + } + +@@ -3009,8 +2995,6 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B2_TI_CTRL, TIM_STOP); sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ); @@ -661878,7 +672258,7 @@ index 0a551d8..15140f9 100644 /* Turn off descriptor polling */ sky2_write32(hw, B28_DPT_CTRL, DPT_STOP); -@@ -3078,18 +3060,46 @@ static void sky2_reset(struct sky2_hw *hw) +@@ -3078,18 +3062,46 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); } @@ -661932,7 +672312,7 @@ index 0a551d8..15140f9 100644 napi_disable(&hw->napi); sky2_write32(hw, B0_IMSK, 0); -@@ -3097,17 +3107,8 @@ static void sky2_restart(struct work_struct *work) +@@ -3097,17 +3109,8 @@ static void sky2_restart(struct work_struct *work) sky2_write32(hw, B0_IMSK, Y2_IS_BASE); napi_enable(&hw->napi); @@ -661952,7 +672332,7 @@ index 0a551d8..15140f9 100644 rtnl_unlock(); } -@@ -3186,7 +3187,8 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +@@ -3186,7 +3189,8 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } ecmd->advertising = sky2->advertising; @@ -661962,7 +672342,7 @@ index 0a551d8..15140f9 100644 ecmd->duplex = sky2->duplex; return 0; } -@@ -3198,6 +3200,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +@@ -3198,6 +3202,7 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) u32 supported = sky2_supported_modes(hw); if (ecmd->autoneg == AUTONEG_ENABLE) { @@ -661970,7 +672350,7 @@ index 0a551d8..15140f9 100644 ecmd->advertising = supported; sky2->duplex = -1; sky2->speed = -1; -@@ -3239,9 +3242,9 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +@@ -3239,9 +3244,9 @@ static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) sky2->speed = ecmd->speed; sky2->duplex = ecmd->duplex; @@ -661981,7 +672361,7 @@ index 0a551d8..15140f9 100644 sky2->advertising = ecmd->advertising; if (netif_running(dev)) { -@@ -3311,14 +3314,17 @@ static u32 sky2_get_rx_csum(struct net_device *dev) +@@ -3311,14 +3316,17 @@ static u32 sky2_get_rx_csum(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); @@ -662001,7 +672381,7 @@ index 0a551d8..15140f9 100644 sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); -@@ -3336,7 +3342,7 @@ static int sky2_nway_reset(struct net_device *dev) +@@ -3336,7 +3344,7 @@ static int sky2_nway_reset(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); @@ -662010,7 +672390,7 @@ index 0a551d8..15140f9 100644 return -EINVAL; sky2_phy_reinit(sky2); -@@ -3576,7 +3582,8 @@ static void sky2_get_pauseparam(struct net_device *dev, +@@ -3576,7 +3584,8 @@ static void sky2_get_pauseparam(struct net_device *dev, ecmd->tx_pause = ecmd->rx_pause = 1; } @@ -662020,7 +672400,7 @@ index 0a551d8..15140f9 100644 } static int sky2_set_pauseparam(struct net_device *dev, -@@ -3584,7 +3591,11 @@ static int sky2_set_pauseparam(struct net_device *dev, +@@ -3584,7 +3593,11 @@ static int sky2_set_pauseparam(struct net_device *dev, { struct sky2_port *sky2 = netdev_priv(dev); @@ -662033,7 +672413,7 @@ index 0a551d8..15140f9 100644 sky2->flow_mode = sky2_flow(ecmd->rx_pause, ecmd->tx_pause); if (netif_running(dev)) -@@ -3640,7 +3651,7 @@ static int sky2_set_coalesce(struct net_device *dev, +@@ -3640,7 +3653,7 @@ static int sky2_set_coalesce(struct net_device *dev, ecmd->rx_coalesce_usecs_irq > tmax) return -EINVAL; @@ -662042,7 +672422,7 @@ index 0a551d8..15140f9 100644 return -EINVAL; if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) return -EINVAL; -@@ -3684,7 +3695,7 @@ static void sky2_get_ringparam(struct net_device *dev, +@@ -3684,7 +3697,7 @@ static void sky2_get_ringparam(struct net_device *dev, ering->rx_max_pending = RX_MAX_PENDING; ering->rx_mini_max_pending = 0; ering->rx_jumbo_max_pending = 0; @@ -662051,7 +672431,7 @@ index 0a551d8..15140f9 100644 ering->rx_pending = sky2->rx_pending; ering->rx_mini_pending = 0; -@@ -3696,27 +3707,20 @@ static int sky2_set_ringparam(struct net_device *dev, +@@ -3696,27 +3709,20 @@ static int sky2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct sky2_port *sky2 = netdev_priv(dev); @@ -662084,7 +672464,7 @@ index 0a551d8..15140f9 100644 } static int sky2_get_regs_len(struct net_device *dev) -@@ -4084,8 +4088,8 @@ static int sky2_debug_show(struct seq_file *seq, void *v) +@@ -4084,8 +4090,8 @@ static int sky2_debug_show(struct seq_file *seq, void *v) /* Dump contents of tx ring */ sop = 1; @@ -662095,7 +672475,7 @@ index 0a551d8..15140f9 100644 const struct sky2_tx_le *le = sky2->tx_le + idx; u32 a = le32_to_cpu(le->addr); -@@ -4128,7 +4132,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) +@@ -4128,7 +4134,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n", sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)), @@ -662104,7 +672484,7 @@ index 0a551d8..15140f9 100644 sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); sky2_read32(hw, B0_Y2_SP_LISR); -@@ -4282,19 +4286,22 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, +@@ -4282,19 +4288,22 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->msg_enable = netif_msg_init(debug, default_msg); /* Auto speed and flow control */ @@ -662130,7 +672510,7 @@ index 0a551d8..15140f9 100644 hw->dev[port] = dev; -@@ -4543,16 +4550,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev, +@@ -4543,16 +4552,18 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (hw->ports > 1) { struct net_device *dev1; @@ -662155,7 +672535,7 @@ index 0a551d8..15140f9 100644 } setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw); -@@ -4602,7 +4611,6 @@ static void __devexit sky2_remove(struct pci_dev *pdev) +@@ -4602,7 +4613,6 @@ static void __devexit sky2_remove(struct pci_dev *pdev) sky2_power_aux(hw); @@ -662163,7 +672543,7 @@ index 0a551d8..15140f9 100644 sky2_write8(hw, B0_CTST, CS_RST_SET); sky2_read8(hw, B0_CTST); -@@ -4634,13 +4642,12 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) +@@ -4634,13 +4644,12 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) del_timer_sync(&hw->watchdog_timer); cancel_work_sync(&hw->restart_work); @@ -662179,7 +672559,7 @@ index 0a551d8..15140f9 100644 if (sky2->wol) sky2_wol_init(sky2); -@@ -4651,6 +4658,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) +@@ -4651,6 +4660,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) sky2_write32(hw, B0_IMSK, 0); napi_disable(&hw->napi); sky2_power_aux(hw); @@ -662187,7 +672567,7 @@ index 0a551d8..15140f9 100644 pci_save_state(pdev); pci_enable_wake(pdev, pci_choose_state(pdev, state), wol); -@@ -4687,25 +4695,18 @@ static int sky2_resume(struct pci_dev *pdev) +@@ -4687,25 +4697,18 @@ static int sky2_resume(struct pci_dev *pdev) sky2_write32(hw, B0_IMSK, Y2_IS_BASE); napi_enable(&hw->napi); @@ -662220,7 +672600,7 @@ index 0a551d8..15140f9 100644 dev_err(&pdev->dev, "resume failed (%d)\n", err); pci_disable_device(pdev); return err; -@@ -4720,6 +4721,7 @@ static void sky2_shutdown(struct pci_dev *pdev) +@@ -4720,6 +4723,7 @@ static void sky2_shutdown(struct pci_dev *pdev) if (!hw) return; @@ -662228,7 +672608,7 @@ index 0a551d8..15140f9 100644 del_timer_sync(&hw->watchdog_timer); for (i = 0; i < hw->ports; i++) { -@@ -4734,6 +4736,7 @@ static void sky2_shutdown(struct pci_dev *pdev) +@@ -4734,6 +4738,7 @@ static void sky2_shutdown(struct pci_dev *pdev) if (wol) sky2_power_aux(hw); @@ -663041,6 +673421,18 @@ index c6ec61e..dcefb60 100644 } static void qe_set_multicast(struct net_device *dev) +diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c +index f1e5e45..bc74db0 100644 +--- a/drivers/net/sunvnet.c ++++ b/drivers/net/sunvnet.c +@@ -1016,7 +1016,6 @@ static const struct net_device_ops vnet_ops = { + .ndo_open = vnet_open, + .ndo_stop = vnet_close, + .ndo_set_multicast_list = vnet_set_rx_mode, +- .ndo_change_mtu = eth_change_mtu, + .ndo_set_mac_address = vnet_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_tx_timeout = vnet_tx_timeout, diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index d737f6b..d1298e5 100644 --- a/drivers/net/tc35815.c @@ -668323,7 +678715,7 @@ index c2ca9f4..0f2ca59 100644 diff --git a/drivers/net/tun.c b/drivers/net/tun.c -index 42b6c63..d3ee199 100644 +index 42b6c63..4fdfa2a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -103,13 +103,10 @@ struct tun_struct { @@ -668512,8 +678904,12 @@ index 42b6c63..d3ee199 100644 err = tun_attach(tun, file); if (err < 0) return err; -@@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) +@@ -943,10 +946,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) + char *name; + unsigned long flags = 0; +- err = -EINVAL; +- if (!capable(CAP_NET_ADMIN)) return -EPERM; + err = security_tun_dev_create(); @@ -668522,7 +678918,16 @@ index 42b6c63..d3ee199 100644 /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { -@@ -986,9 +992,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) +@@ -958,7 +962,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) + flags |= TUN_TAP_DEV; + name = "tap%d"; + } else +- goto failed; ++ return -EINVAL; + + if (*ifr->ifr_name) + name = ifr->ifr_name; +@@ -986,9 +990,10 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) sk->sk_write_space = tun_sock_write_space; sk->sk_sndbuf = INT_MAX; @@ -668534,7 +678939,7 @@ index 42b6c63..d3ee199 100644 tun_net_init(dev); if (strchr(dev->name, '%')) { -@@ -997,7 +1004,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) +@@ -997,7 +1002,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) goto err_free_sk; } @@ -668542,7 +678947,7 @@ index 42b6c63..d3ee199 100644 err = register_netdevice(tun->dev); if (err < 0) goto err_free_sk; -@@ -1069,7 +1075,8 @@ static int set_offload(struct net_device *dev, unsigned long arg) +@@ -1069,7 +1073,8 @@ static int set_offload(struct net_device *dev, unsigned long arg) old_features = dev->features; /* Unset features, set them as we chew on the arg. */ features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST @@ -668552,7 +678957,7 @@ index 42b6c63..d3ee199 100644 if (arg & TUN_F_CSUM) { features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST; -@@ -1086,6 +1093,11 @@ static int set_offload(struct net_device *dev, unsigned long arg) +@@ -1086,6 +1091,11 @@ static int set_offload(struct net_device *dev, unsigned long arg) features |= NETIF_F_TSO6; arg &= ~(TUN_F_TSO4|TUN_F_TSO6); } @@ -668564,7 +678969,7 @@ index 42b6c63..d3ee199 100644 } /* This gives the user a way to test for new features in future by -@@ -1239,7 +1251,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, +@@ -1239,7 +1249,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, break; case TUNGETSNDBUF: @@ -668573,7 +678978,7 @@ index 42b6c63..d3ee199 100644 if (copy_to_user(argp, &sndbuf, sizeof(sndbuf))) ret = -EFAULT; break; -@@ -1250,7 +1262,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, +@@ -1250,7 +1260,7 @@ static long tun_chr_ioctl(struct file *file, unsigned int cmd, break; } @@ -668582,7 +678987,7 @@ index 42b6c63..d3ee199 100644 break; default: -@@ -1333,7 +1345,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) +@@ -1333,7 +1343,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) tun = tfile->tun; if (tun) @@ -668591,7 +678996,7 @@ index 42b6c63..d3ee199 100644 put_net(tfile->net); kfree(tfile); -@@ -1358,7 +1370,7 @@ static const struct file_operations tun_fops = { +@@ -1358,7 +1368,7 @@ static const struct file_operations tun_fops = { static struct miscdevice tun_miscdev = { .minor = TUN_MINOR, .name = "tun", @@ -669697,10 +680102,47 @@ index f8c6d7e..fa4e581 100644 /* registering our net device */ result = register_netdev(net); diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c -index 1f9ec29..e2a39b9 100644 +index 1f9ec29..e391ef9 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c -@@ -778,7 +778,7 @@ static u32 kaweth_get_link(struct net_device *dev) +@@ -263,6 +263,7 @@ static int kaweth_control(struct kaweth_device *kaweth, + int timeout) + { + struct usb_ctrlrequest *dr; ++ int retval; + + dbg("kaweth_control()"); + +@@ -278,18 +279,21 @@ static int kaweth_control(struct kaweth_device *kaweth, + return -ENOMEM; + } + +- dr->bRequestType= requesttype; ++ dr->bRequestType = requesttype; + dr->bRequest = request; + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(size); + +- return kaweth_internal_control_msg(kaweth->dev, +- pipe, +- dr, +- data, +- size, +- timeout); ++ retval = kaweth_internal_control_msg(kaweth->dev, ++ pipe, ++ dr, ++ data, ++ size, ++ timeout); ++ ++ kfree(dr); ++ return retval; + } + + /**************************************************************** +@@ -778,7 +782,7 @@ static u32 kaweth_get_link(struct net_device *dev) return kaweth->linkstate; } @@ -669709,7 +680151,7 @@ index 1f9ec29..e2a39b9 100644 .get_drvinfo = kaweth_get_drvinfo, .get_link = kaweth_get_link }; -@@ -803,7 +803,8 @@ static void kaweth_usb_transmit_complete(struct urb *urb) +@@ -803,7 +807,8 @@ static void kaweth_usb_transmit_complete(struct urb *urb) /**************************************************************** * kaweth_start_xmit ****************************************************************/ @@ -669719,7 +680161,7 @@ index 1f9ec29..e2a39b9 100644 { struct kaweth_device *kaweth = netdev_priv(net); __le16 *private_header; -@@ -829,7 +830,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) +@@ -829,7 +834,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net) kaweth->stats.tx_errors++; netif_start_queue(net); spin_unlock_irq(&kaweth->device_lock); @@ -669728,7 +680170,7 @@ index 1f9ec29..e2a39b9 100644 } } -@@ -864,7 +865,7 @@ skip: +@@ -864,7 +869,7 @@ skip: spin_unlock_irq(&kaweth->device_lock); @@ -669883,7 +680325,7 @@ index fcc6fa0..b091e20 100644 .get_settings = rtl8150_get_settings, .get_link = ethtool_op_get_link diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c -index fe04589..938fb35 100644 +index fe04589..c6c9222 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -220,11 +220,6 @@ static int smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev) @@ -669907,8 +680349,93 @@ index fe04589..938fb35 100644 .get_link = usbnet_get_link, .nway_reset = usbnet_nway_reset, .get_drvinfo = usbnet_get_drvinfo, +@@ -1232,7 +1227,7 @@ static const struct driver_info smsc95xx_info = { + .rx_fixup = smsc95xx_rx_fixup, + .tx_fixup = smsc95xx_tx_fixup, + .status = smsc95xx_status, +- .flags = FLAG_ETHER, ++ .flags = FLAG_ETHER | FLAG_SEND_ZLP, + }; + + static const struct usb_device_id products[] = { +@@ -1242,10 +1237,75 @@ static const struct usb_device_id products[] = { + .driver_info = (unsigned long) &smsc95xx_info, + }, + { ++ /* SMSC9505 USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9505), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9E00), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device */ ++ USB_DEVICE(0x0424, 0x9E01), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { + /* SMSC9512/9514 USB Hub & Ethernet Device */ + USB_DEVICE(0x0424, 0xec00), + .driver_info = (unsigned long) &smsc95xx_info, + }, ++ { ++ /* SMSC9500 USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9900), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505 USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9901), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9902), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9903), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9512/9514 USB Hub & Ethernet Device (SAL10) */ ++ USB_DEVICE(0x0424, 0x9904), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (HAL) */ ++ USB_DEVICE(0x0424, 0x9905), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9505A USB Ethernet Device (HAL) */ ++ USB_DEVICE(0x0424, 0x9906), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500 USB Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9907), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9500A USB Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9908), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, ++ { ++ /* SMSC9512/9514 USB Hub & Ethernet Device (Alternate ID) */ ++ USB_DEVICE(0x0424, 0x9909), ++ .driver_info = (unsigned long) &smsc95xx_info, ++ }, + { }, /* END */ + }; + MODULE_DEVICE_TABLE(usb, products); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c -index edfd9e1..24b36f7 100644 +index edfd9e1..ca5ca5a 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -233,6 +233,11 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) @@ -670059,6 +680586,15 @@ index edfd9e1..24b36f7 100644 // some devices want funky USB-level framing, for // win32 driver (usually) and/or hardware quirks +@@ -988,7 +1049,7 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) + * NOTE: strictly conforming cdc-ether devices should expect + * the ZLP here, but ignore the one-byte packet. + */ +- if ((length % dev->maxpacket) == 0) { ++ if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) { + urb->transfer_buffer_length++; + if (skb_tailroom(skb)) { + skb->data[skb->len] = 0; @@ -1019,7 +1080,6 @@ int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) if (netif_msg_tx_err (dev)) devdbg (dev, "drop, code %d", retval); @@ -677003,6 +687539,119 @@ index d84caf1..921a082 100644 bad_end: arlan_process_interrupt(dev); +diff --git a/drivers/net/wireless/arlan-proc.c b/drivers/net/wireless/arlan-proc.c +index 2ab1d59..a8b6896 100644 +--- a/drivers/net/wireless/arlan-proc.c ++++ b/drivers/net/wireless/arlan-proc.c +@@ -402,7 +402,7 @@ static int arlan_setup_card_by_book(struct net_device *dev) + + static char arlan_drive_info[ARLAN_STR_SIZE] = "A655\n\0"; + +-static int arlan_sysctl_info(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_info(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int i; +@@ -629,7 +629,7 @@ final: + *lenp = pos; + + if (!write) +- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ retv = proc_dostring(ctl, write, buffer, lenp, ppos); + else + { + *lenp = 0; +@@ -639,7 +639,7 @@ final: + } + + +-static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_info161719(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int i; +@@ -669,11 +669,11 @@ static int arlan_sysctl_info161719(ctl_table * ctl, int write, struct file *filp + + final: + *lenp = pos; +- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ retv = proc_dostring(ctl, write, buffer, lenp, ppos); + return retv; + } + +-static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int i; +@@ -698,11 +698,11 @@ static int arlan_sysctl_infotxRing(ctl_table * ctl, int write, struct file *filp + SARLBNpln(u_char, txBuffer, 0x800); + final: + *lenp = pos; +- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ retv = proc_dostring(ctl, write, buffer, lenp, ppos); + return retv; + } + +-static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int i; +@@ -726,11 +726,11 @@ static int arlan_sysctl_inforxRing(ctl_table * ctl, int write, struct file *filp + SARLBNpln(u_char, rxBuffer, 0x800); + final: + *lenp = pos; +- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ retv = proc_dostring(ctl, write, buffer, lenp, ppos); + return retv; + } + +-static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_info18(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int i; +@@ -756,7 +756,7 @@ static int arlan_sysctl_info18(ctl_table * ctl, int write, struct file *filp, + + final: + *lenp = pos; +- retv = proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ retv = proc_dostring(ctl, write, buffer, lenp, ppos); + return retv; + } + +@@ -766,7 +766,7 @@ final: + + static char conf_reset_result[200]; + +-static int arlan_configure(ctl_table * ctl, int write, struct file *filp, ++static int arlan_configure(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int pos = 0; +@@ -788,10 +788,10 @@ static int arlan_configure(ctl_table * ctl, int write, struct file *filp, + return -1; + + *lenp = pos; +- return proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ return proc_dostring(ctl, write, buffer, lenp, ppos); + } + +-static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp, ++static int arlan_sysctl_reset(ctl_table * ctl, int write, + void __user *buffer, size_t * lenp, loff_t *ppos) + { + int pos = 0; +@@ -811,7 +811,7 @@ static int arlan_sysctl_reset(ctl_table * ctl, int write, struct file *filp, + } else + return -1; + *lenp = pos + 3; +- return proc_dostring(ctl, write, filp, buffer, lenp, ppos); ++ return proc_dostring(ctl, write, buffer, lenp, ppos); + } + + diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 4efbdbe..8e1a55d 100644 --- a/drivers/net/wireless/at76c50x-usb.c @@ -781975,10 +792624,10 @@ index 8d88dae..baa051d 100644 .set_sg = xennet_set_sg, diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c new file mode 100644 -index 0000000..dc22782 +index 0000000..83a044d --- /dev/null +++ b/drivers/net/xilinx_emaclite.c -@@ -0,0 +1,1040 @@ +@@ -0,0 +1,1037 @@ +/* + * Xilinx EmacLite Linux driver for the Xilinx Ethernet MAC Lite device. + * @@ -782115,18 +792764,15 @@ index 0000000..dc22782 + } + + /* Enable the Rx interrupts for the first buffer */ -+ reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET); + out_be32(drvdata->base_addr + XEL_RSR_OFFSET, -+ reg_data | XEL_RSR_RECV_IE_MASK); ++ XEL_RSR_RECV_IE_MASK); + + /* Enable the Rx interrupts for the second Buffer if + * configured in HW */ + if (drvdata->rx_ping_pong != 0) { -+ reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + -+ XEL_RSR_OFFSET); + out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET + + XEL_RSR_OFFSET, -+ reg_data | XEL_RSR_RECV_IE_MASK); ++ XEL_RSR_RECV_IE_MASK); + } + + /* Enable the Global Interrupt Enable */ @@ -783487,6 +794133,64 @@ index 123d8fe..57a6d19 100644 iova_space_size>>20, iov_order + PAGE_SHIFT); +diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c +index 554e11f..8eefe56 100644 +--- a/drivers/parport/procfs.c ++++ b/drivers/parport/procfs.c +@@ -31,7 +31,7 @@ + #define PARPORT_MIN_SPINTIME_VALUE 1 + #define PARPORT_MAX_SPINTIME_VALUE 1000 + +-static int do_active_device(ctl_table *table, int write, struct file *filp, ++static int do_active_device(ctl_table *table, int write, + void __user *result, size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +@@ -68,7 +68,7 @@ static int do_active_device(ctl_table *table, int write, struct file *filp, + } + + #ifdef CONFIG_PARPORT_1284 +-static int do_autoprobe(ctl_table *table, int write, struct file *filp, ++static int do_autoprobe(ctl_table *table, int write, + void __user *result, size_t *lenp, loff_t *ppos) + { + struct parport_device_info *info = table->extra2; +@@ -111,7 +111,7 @@ static int do_autoprobe(ctl_table *table, int write, struct file *filp, + #endif /* IEEE1284.3 support. */ + + static int do_hardware_base_addr (ctl_table *table, int write, +- struct file *filp, void __user *result, ++ void __user *result, + size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +@@ -139,7 +139,7 @@ static int do_hardware_base_addr (ctl_table *table, int write, + } + + static int do_hardware_irq (ctl_table *table, int write, +- struct file *filp, void __user *result, ++ void __user *result, + size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +@@ -167,7 +167,7 @@ static int do_hardware_irq (ctl_table *table, int write, + } + + static int do_hardware_dma (ctl_table *table, int write, +- struct file *filp, void __user *result, ++ void __user *result, + size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; +@@ -195,7 +195,7 @@ static int do_hardware_dma (ctl_table *table, int write, + } + + static int do_hardware_modes (ctl_table *table, int write, +- struct file *filp, void __user *result, ++ void __user *result, + size_t *lenp, loff_t *ppos) + { + struct parport *port = (struct parport *)table->extra1; diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 1ebd6b4..4a7f11d 100644 --- a/drivers/pci/Makefile @@ -783502,7 +794206,7 @@ index 1ebd6b4..4a7f11d 100644 obj-$(CONFIG_PCIEPORTBUS) += pcie/ diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c -index 7b287cb..14bbaa1 100644 +index 7b287cb..22b02c6 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -33,9 +33,10 @@ @@ -783518,7 +794222,28 @@ index 7b287cb..14bbaa1 100644 /* No locks are needed as DMA remapping hardware unit * list is constructed at boot time and hotplug of -@@ -413,6 +414,12 @@ parse_dmar_table(void) +@@ -353,6 +354,7 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) + struct acpi_dmar_hardware_unit *drhd; + struct acpi_dmar_reserved_memory *rmrr; + struct acpi_dmar_atsr *atsr; ++ struct acpi_dmar_rhsa *rhsa; + + switch (header->type) { + case ACPI_DMAR_TYPE_HARDWARE_UNIT: +@@ -374,6 +376,12 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) + atsr = container_of(header, struct acpi_dmar_atsr, header); + printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags); + break; ++ case ACPI_DMAR_HARDWARE_AFFINITY: ++ rhsa = container_of(header, struct acpi_dmar_rhsa, header); ++ printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n", ++ (unsigned long long)rhsa->base_address, ++ rhsa->proximity_domain); ++ break; + } + } + +@@ -413,6 +421,12 @@ parse_dmar_table(void) */ dmar_table_detect(); @@ -783531,7 +794256,22 @@ index 7b287cb..14bbaa1 100644 dmar = (struct acpi_table_dmar *)dmar_tbl; if (!dmar) return -ENODEV; -@@ -570,9 +577,6 @@ int __init dmar_table_init(void) +@@ -452,9 +466,13 @@ parse_dmar_table(void) + ret = dmar_parse_one_atsr(entry_header); + #endif + break; ++ case ACPI_DMAR_HARDWARE_AFFINITY: ++ /* We don't do anything with RHSA (yet?) */ ++ break; + default: + printk(KERN_WARNING PREFIX +- "Unknown DMAR structure type\n"); ++ "Unknown DMAR structure type %d\n", ++ entry_header->type); + ret = 0; /* for forward compatibility */ + break; + } +@@ -570,9 +588,6 @@ int __init dmar_table_init(void) printk(KERN_INFO PREFIX "No ATSR found\n"); #endif @@ -783541,7 +794281,7 @@ index 7b287cb..14bbaa1 100644 return 0; } -@@ -632,20 +636,31 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) +@@ -632,20 +647,31 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG); iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG); @@ -783575,7 +794315,7 @@ index 7b287cb..14bbaa1 100644 } #endif iommu->agaw = agaw; -@@ -665,7 +680,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) +@@ -665,7 +691,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) } ver = readl(iommu->reg + DMAR_VER_REG); @@ -783584,7 +794324,7 @@ index 7b287cb..14bbaa1 100644 (unsigned long long)drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver), (unsigned long long)iommu->cap, -@@ -675,7 +690,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) +@@ -675,7 +701,10 @@ int alloc_iommu(struct dmar_drhd_unit *drhd) drhd->iommu = iommu; return 0; @@ -783596,7 +794336,7 @@ index 7b287cb..14bbaa1 100644 kfree(iommu); return -1; } -@@ -1212,7 +1230,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id) +@@ -1212,7 +1241,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id) source_id, guest_addr); fault_index++; @@ -783605,7 +794345,7 @@ index 7b287cb..14bbaa1 100644 fault_index = 0; spin_lock_irqsave(&iommu->register_lock, flag); } -@@ -1305,3 +1323,13 @@ int dmar_reenable_qi(struct intel_iommu *iommu) +@@ -1305,3 +1334,13 @@ int dmar_reenable_qi(struct intel_iommu *iommu) return 0; } @@ -784171,10 +794911,10 @@ index 0cb0f83..58d25a1 100644 } diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c -index 5befa7e..a9d926b 100644 +index 5befa7e..e7be66d 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c -@@ -398,23 +398,21 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, +@@ -398,23 +398,20 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, acpi_handle *phandle = (acpi_handle *)context; acpi_status status; struct acpi_device_info *info; @@ -784190,7 +794930,6 @@ index 5befa7e..a9d926b 100644 } - info = info_buffer.pointer; - info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0'; -+ info->hardware_id.string[sizeof(info->hardware_id.length) - 1] = '\0'; if (info->current_status && (info->valid & ACPI_VALID_HID) && - (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) || @@ -791381,7 +802120,7 @@ index db657bb..b39d2bb 100644 out4: ASUS_LED_UNREGISTER(pled); diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c -index 222ffb8..da3c08b 100644 +index 222ffb8..749e210 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -142,18 +142,28 @@ struct eeepc_hotk { @@ -791470,6 +802209,15 @@ index 222ffb8..da3c08b 100644 } else { pr_err("Hotkey device not present, aborting\n"); return -EINVAL; +@@ -642,7 +624,7 @@ static int notify_brn(void) + struct backlight_device *bd = eeepc_backlight_device; + if (bd) { + int old = bd->props.brightness; +- bd->props.brightness = read_brightness(bd); ++ backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY); + return old; + } + return -1; @@ -661,40 +643,48 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, return 0; } @@ -792237,10 +802985,71 @@ index dafaa4a..f9f68e0 100644 return AE_OK; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index e856008..f78d275 100644 +index e856008..3910f2f 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -1278,6 +1278,7 @@ static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id) +@@ -22,7 +22,7 @@ + */ + + #define TPACPI_VERSION "0.23" +-#define TPACPI_SYSFS_VERSION 0x020400 ++#define TPACPI_SYSFS_VERSION 0x020500 + + /* + * Changelog: +@@ -145,6 +145,51 @@ enum { + TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */ + }; + ++/* HKEY events */ ++enum tpacpi_hkey_event_t { ++ /* Hotkey-related */ ++ TP_HKEY_EV_HOTKEY_BASE = 0x1001, /* first hotkey (FN+F1) */ ++ TP_HKEY_EV_BRGHT_UP = 0x1010, /* Brightness up */ ++ TP_HKEY_EV_BRGHT_DOWN = 0x1011, /* Brightness down */ ++ TP_HKEY_EV_VOL_UP = 0x1015, /* Volume up or unmute */ ++ TP_HKEY_EV_VOL_DOWN = 0x1016, /* Volume down or unmute */ ++ TP_HKEY_EV_VOL_MUTE = 0x1017, /* Mixer output mute */ ++ ++ /* Reasons for waking up from S3/S4 */ ++ TP_HKEY_EV_WKUP_S3_UNDOCK = 0x2304, /* undock requested, S3 */ ++ TP_HKEY_EV_WKUP_S4_UNDOCK = 0x2404, /* undock requested, S4 */ ++ TP_HKEY_EV_WKUP_S3_BAYEJ = 0x2305, /* bay ejection req, S3 */ ++ TP_HKEY_EV_WKUP_S4_BAYEJ = 0x2405, /* bay ejection req, S4 */ ++ TP_HKEY_EV_WKUP_S3_BATLOW = 0x2313, /* battery empty, S3 */ ++ TP_HKEY_EV_WKUP_S4_BATLOW = 0x2413, /* battery empty, S4 */ ++ ++ /* Auto-sleep after eject request */ ++ TP_HKEY_EV_BAYEJ_ACK = 0x3003, /* bay ejection complete */ ++ TP_HKEY_EV_UNDOCK_ACK = 0x4003, /* undock complete */ ++ ++ /* Misc bay events */ ++ TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ ++ ++ /* User-interface events */ ++ TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ ++ TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */ ++ TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */ ++ TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */ ++ TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */ ++ TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ ++ TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ ++ ++ /* Thermal events */ ++ TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ ++ TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ ++ TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021, /* sensor too hot */ ++ TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ ++ TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ ++ ++ /* Misc */ ++ TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ ++}; ++ + /**************************************************************************** + * Main driver + */ +@@ -1278,6 +1323,7 @@ static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id) tp_rfk = tpacpi_rfkill_switches[id]; if (tp_rfk) { rfkill_unregister(tp_rfk->rfkill); @@ -792248,7 +803057,7 @@ index e856008..f78d275 100644 tpacpi_rfkill_switches[id] = NULL; kfree(tp_rfk); } -@@ -1601,6 +1602,196 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) +@@ -1601,6 +1647,196 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) #endif } @@ -792445,7 +803254,7 @@ index e856008..f78d275 100644 /**************************************************************************** **************************************************************************** * -@@ -1634,6 +1825,7 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) +@@ -1634,6 +1870,7 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) (thinkpad_id.nummodel_str) ? thinkpad_id.nummodel_str : "unknown"); @@ -792453,7 +803262,44 @@ index e856008..f78d275 100644 return 0; } -@@ -1731,16 +1923,42 @@ struct tp_nvram_state { +@@ -1656,6 +1893,27 @@ static struct ibm_struct thinkpad_acpi_driver_data = { + * Hotkey subdriver + */ + ++/* ++ * ThinkPad firmware event model ++ * ++ * The ThinkPad firmware has two main event interfaces: normal ACPI ++ * notifications (which follow the ACPI standard), and a private event ++ * interface. ++ * ++ * The private event interface also issues events for the hotkeys. As ++ * the driver gained features, the event handling code ended up being ++ * built around the hotkey subdriver. This will need to be refactored ++ * to a more formal event API eventually. ++ * ++ * Some "hotkeys" are actually supposed to be used as event reports, ++ * such as "brightness has changed", "volume has changed", depending on ++ * the ThinkPad model and how the firmware is operating. ++ * ++ * Unlike other classes, hotkey-class events have mask/unmask control on ++ * non-ancient firmware. However, how it behaves changes a lot with the ++ * firmware model and version. ++ */ ++ + enum { /* hot key scan codes (derived from ACPI DSDT) */ + TP_ACPI_HOTKEYSCAN_FNF1 = 0, + TP_ACPI_HOTKEYSCAN_FNF2, +@@ -1683,7 +1941,7 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ + TP_ACPI_HOTKEYSCAN_THINKPAD, + }; + +-enum { /* Keys available through NVRAM polling */ ++enum { /* Keys/events available through NVRAM polling */ + TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, + TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, + }; +@@ -1731,16 +1989,50 @@ struct tp_nvram_state { u8 volume_level; }; @@ -792466,8 +803312,11 @@ index e856008..f78d275 100644 static struct mutex hotkey_thread_mutex; + +/* -+ * Acquire mutex to write poller control variables. -+ * Increment hotkey_config_change when changing them. ++ * Acquire mutex to write poller control variables as an ++ * atomic block. ++ * ++ * Increment hotkey_config_change when changing them if you ++ * want the kthread to forget old state. + * + * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END + */ @@ -792478,6 +803327,11 @@ index e856008..f78d275 100644 + * hotkey poller control variables + * + * Must be atomic or readers will also need to acquire mutex ++ * ++ * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END ++ * should be used only when the changes need to be taken as ++ * a block, OR when one needs to force the kthread to forget ++ * old state. + */ +static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ +static unsigned int hotkey_poll_freq = 10; /* Hz */ @@ -792498,7 +803352,24 @@ index e856008..f78d275 100644 #endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ -@@ -1765,19 +1983,6 @@ static u16 *hotkey_keycode_map; +@@ -1754,10 +2046,12 @@ static enum { /* Reasons for waking up */ + + static int hotkey_autosleep_ack; + +-static u32 hotkey_orig_mask; +-static u32 hotkey_all_mask; +-static u32 hotkey_reserved_mask; +-static u32 hotkey_mask; ++static u32 hotkey_orig_mask; /* events the BIOS had enabled */ ++static u32 hotkey_all_mask; /* all events supported in fw */ ++static u32 hotkey_reserved_mask; /* events better left disabled */ ++static u32 hotkey_driver_mask; /* events needed by the driver */ ++static u32 hotkey_user_mask; /* events visible to userspace */ ++static u32 hotkey_acpi_mask; /* events enabled in firmware */ + + static unsigned int hotkey_report_mode; + +@@ -1765,18 +2059,8 @@ static u16 *hotkey_keycode_map; static struct attribute_set *hotkey_dev_attributes; @@ -792514,21 +803385,318 @@ index e856008..f78d275 100644 -#define HOTKEY_CONFIG_CRITICAL_START -#define HOTKEY_CONFIG_CRITICAL_END -#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ -- ++static void tpacpi_driver_event(const unsigned int hkey_event); ++static void hotkey_driver_event(const unsigned int scancode); + /* HKEY.MHKG() return bits */ #define TP_HOTKEY_TABLET_MASK (1 << 3) +@@ -1812,22 +2096,53 @@ static int hotkey_get_tablet_mode(int *status) + } -@@ -1822,7 +2027,9 @@ static int hotkey_mask_get(void) + /* ++ * Reads current event mask from firmware, and updates ++ * hotkey_acpi_mask accordingly. Also resets any bits ++ * from hotkey_user_mask that are unavailable to be ++ * delivered (shadow requirement of the userspace ABI). ++ * + * Call with hotkey_mutex held + */ + static int hotkey_mask_get(void) + { +- u32 m = 0; +- + if (tp_features.hotkey_mask) { ++ u32 m = 0; ++ if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) return -EIO; ++ ++ hotkey_acpi_mask = m; ++ } else { ++ /* no mask support doesn't mean no event support... */ ++ hotkey_acpi_mask = hotkey_all_mask; } -+ HOTKEY_CONFIG_CRITICAL_START - hotkey_mask = m | (hotkey_source_mask & hotkey_mask); -+ HOTKEY_CONFIG_CRITICAL_END +- hotkey_mask = m | (hotkey_source_mask & hotkey_mask); ++ ++ /* sync userspace-visible mask */ ++ hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask); return 0; } -@@ -2075,6 +2282,7 @@ static int hotkey_kthread(void *data) + ++void static hotkey_mask_warn_incomplete_mask(void) ++{ ++ /* log only what the user can fix... */ ++ const u32 wantedmask = hotkey_driver_mask & ++ ~(hotkey_acpi_mask | hotkey_source_mask) & ++ (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK); ++ ++ if (wantedmask) ++ printk(TPACPI_NOTICE ++ "required events 0x%08x not enabled!\n", ++ wantedmask); ++} ++ + /* ++ * Set the firmware mask when supported ++ * ++ * Also calls hotkey_mask_get to update hotkey_acpi_mask. ++ * ++ * NOTE: does not set bits in hotkey_user_mask, but may reset them. ++ * + * Call with hotkey_mutex held + */ + static int hotkey_mask_set(u32 mask) +@@ -1835,66 +2150,98 @@ static int hotkey_mask_set(u32 mask) + int i; + int rc = 0; + +- if (tp_features.hotkey_mask) { +- if (!tp_warned.hotkey_mask_ff && +- (mask == 0xffff || mask == 0xffffff || +- mask == 0xffffffff)) { +- tp_warned.hotkey_mask_ff = 1; +- printk(TPACPI_NOTICE +- "setting the hotkey mask to 0x%08x is likely " +- "not the best way to go about it\n", mask); +- printk(TPACPI_NOTICE +- "please consider using the driver defaults, " +- "and refer to up-to-date thinkpad-acpi " +- "documentation\n"); +- } ++ const u32 fwmask = mask & ~hotkey_source_mask; + +- HOTKEY_CONFIG_CRITICAL_START ++ if (tp_features.hotkey_mask) { + for (i = 0; i < 32; i++) { +- u32 m = 1 << i; +- /* enable in firmware mask only keys not in NVRAM +- * mode, but enable the key in the cached hotkey_mask +- * regardless of mode, or the key will end up +- * disabled by hotkey_mask_get() */ + if (!acpi_evalf(hkey_handle, + NULL, "MHKM", "vdd", i + 1, +- !!((mask & ~hotkey_source_mask) & m))) { ++ !!(mask & (1 << i)))) { + rc = -EIO; + break; +- } else { +- hotkey_mask = (hotkey_mask & ~m) | (mask & m); + } + } +- HOTKEY_CONFIG_CRITICAL_END ++ } + +- /* hotkey_mask_get must be called unconditionally below */ +- if (!hotkey_mask_get() && !rc && +- (hotkey_mask & ~hotkey_source_mask) != +- (mask & ~hotkey_source_mask)) { +- printk(TPACPI_NOTICE +- "requested hot key mask 0x%08x, but " +- "firmware forced it to 0x%08x\n", +- mask, hotkey_mask); +- } +- } else { +-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL +- HOTKEY_CONFIG_CRITICAL_START +- hotkey_mask = mask & hotkey_source_mask; +- HOTKEY_CONFIG_CRITICAL_END +- hotkey_mask_get(); +- if (hotkey_mask != mask) { +- printk(TPACPI_NOTICE +- "requested hot key mask 0x%08x, " +- "forced to 0x%08x (NVRAM poll mask is " +- "0x%08x): no firmware mask support\n", +- mask, hotkey_mask, hotkey_source_mask); +- } +-#else +- hotkey_mask_get(); +- rc = -ENXIO; +-#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ ++ /* ++ * We *must* make an inconditional call to hotkey_mask_get to ++ * refresh hotkey_acpi_mask and update hotkey_user_mask ++ * ++ * Take the opportunity to also log when we cannot _enable_ ++ * a given event. ++ */ ++ if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) { ++ printk(TPACPI_NOTICE ++ "asked for hotkey mask 0x%08x, but " ++ "firmware forced it to 0x%08x\n", ++ fwmask, hotkey_acpi_mask); + } + ++ hotkey_mask_warn_incomplete_mask(); ++ ++ return rc; ++} ++ ++/* ++ * Sets hotkey_user_mask and tries to set the firmware mask ++ * ++ * Call with hotkey_mutex held ++ */ ++static int hotkey_user_mask_set(const u32 mask) ++{ ++ int rc; ++ ++ /* Give people a chance to notice they are doing something that ++ * is bound to go boom on their users sooner or later */ ++ if (!tp_warned.hotkey_mask_ff && ++ (mask == 0xffff || mask == 0xffffff || ++ mask == 0xffffffff)) { ++ tp_warned.hotkey_mask_ff = 1; ++ printk(TPACPI_NOTICE ++ "setting the hotkey mask to 0x%08x is likely " ++ "not the best way to go about it\n", mask); ++ printk(TPACPI_NOTICE ++ "please consider using the driver defaults, " ++ "and refer to up-to-date thinkpad-acpi " ++ "documentation\n"); ++ } ++ ++ /* Try to enable what the user asked for, plus whatever we need. ++ * this syncs everything but won't enable bits in hotkey_user_mask */ ++ rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask); ++ ++ /* Enable the available bits in hotkey_user_mask */ ++ hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask); ++ ++ return rc; ++} ++ ++/* ++ * Sets the driver hotkey mask. ++ * ++ * Can be called even if the hotkey subdriver is inactive ++ */ ++static int tpacpi_hotkey_driver_mask_set(const u32 mask) ++{ ++ int rc; ++ ++ /* Do the right thing if hotkey_init has not been called yet */ ++ if (!tp_features.hotkey) { ++ hotkey_driver_mask = mask; ++ return 0; ++ } ++ ++ mutex_lock(&hotkey_mutex); ++ ++ HOTKEY_CONFIG_CRITICAL_START ++ hotkey_driver_mask = mask; ++ hotkey_source_mask |= (mask & ~hotkey_all_mask); ++ HOTKEY_CONFIG_CRITICAL_END ++ ++ rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & ++ ~hotkey_source_mask); ++ mutex_unlock(&hotkey_mutex); ++ + return rc; + } + +@@ -1930,11 +2277,10 @@ static void tpacpi_input_send_tabletsw(void) + } + } + +-static void tpacpi_input_send_key(unsigned int scancode) ++/* Do NOT call without validating scancode first */ ++static void tpacpi_input_send_key(const unsigned int scancode) + { +- unsigned int keycode; +- +- keycode = hotkey_keycode_map[scancode]; ++ const unsigned int keycode = hotkey_keycode_map[scancode]; + + if (keycode != KEY_RESERVED) { + mutex_lock(&tpacpi_inputdev_send_mutex); +@@ -1955,19 +2301,28 @@ static void tpacpi_input_send_key(unsigned int scancode) + } + } + ++/* Do NOT call without validating scancode first */ ++static void tpacpi_input_send_key_masked(const unsigned int scancode) ++{ ++ hotkey_driver_event(scancode); ++ if (hotkey_user_mask & (1 << scancode)) ++ tpacpi_input_send_key(scancode); ++} ++ + #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL + static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; + ++/* Do NOT call without validating scancode first */ + static void tpacpi_hotkey_send_key(unsigned int scancode) + { +- tpacpi_input_send_key(scancode); ++ tpacpi_input_send_key_masked(scancode); + if (hotkey_report_mode < 2) { + acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, +- 0x80, 0x1001 + scancode); ++ 0x80, TP_HKEY_EV_HOTKEY_BASE + scancode); + } + } + +-static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) ++static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m) + { + u8 d; + +@@ -2003,21 +2358,24 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) + } + } + ++static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, ++ struct tp_nvram_state *newn, ++ const u32 event_mask) ++{ ++ + #define TPACPI_COMPARE_KEY(__scancode, __member) \ + do { \ +- if ((mask & (1 << __scancode)) && \ ++ if ((event_mask & (1 << __scancode)) && \ + oldn->__member != newn->__member) \ +- tpacpi_hotkey_send_key(__scancode); \ ++ tpacpi_hotkey_send_key(__scancode); \ + } while (0) + + #define TPACPI_MAY_SEND_KEY(__scancode) \ +- do { if (mask & (1 << __scancode)) \ +- tpacpi_hotkey_send_key(__scancode); } while (0) ++ do { \ ++ if (event_mask & (1 << __scancode)) \ ++ tpacpi_hotkey_send_key(__scancode); \ ++ } while (0) + +-static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, +- struct tp_nvram_state *newn, +- u32 mask) +-{ + TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); + TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); + TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); +@@ -2063,18 +2421,26 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn, + } + } + } +-} + + #undef TPACPI_COMPARE_KEY + #undef TPACPI_MAY_SEND_KEY ++} + ++/* ++ * Polling driver ++ * ++ * We track all events in hotkey_source_mask all the time, since ++ * most of them are edge-based. We only issue those requested by ++ * hotkey_user_mask or hotkey_driver_mask, though. ++ */ + static int hotkey_kthread(void *data) + { + struct tp_nvram_state s[2]; +- u32 mask; ++ u32 poll_mask, event_mask; unsigned int si, so; unsigned long t; unsigned int change_detector, must_reset; @@ -792536,13 +803704,18 @@ index e856008..f78d275 100644 mutex_lock(&hotkey_thread_mutex); -@@ -2091,12 +2299,17 @@ static int hotkey_kthread(void *data) +@@ -2090,13 +2456,20 @@ static int hotkey_kthread(void *data) + /* Initial state for compares */ mutex_lock(&hotkey_thread_data_mutex); change_detector = hotkey_config_change; - mask = hotkey_source_mask & hotkey_mask; +- mask = hotkey_source_mask & hotkey_mask; ++ poll_mask = hotkey_source_mask; ++ event_mask = hotkey_source_mask & ++ (hotkey_driver_mask | hotkey_user_mask); + poll_freq = hotkey_poll_freq; mutex_unlock(&hotkey_thread_data_mutex); - hotkey_read_nvram(&s[so], mask); +- hotkey_read_nvram(&s[so], mask); ++ hotkey_read_nvram(&s[so], poll_mask); - while (!kthread_should_stop() && hotkey_poll_freq) { - if (t == 0) @@ -792557,15 +803730,29 @@ index e856008..f78d275 100644 t = msleep_interruptible(t); if (unlikely(kthread_should_stop())) break; -@@ -2112,6 +2325,7 @@ static int hotkey_kthread(void *data) +@@ -2111,14 +2484,17 @@ static int hotkey_kthread(void *data) + t = 0; change_detector = hotkey_config_change; } - mask = hotkey_source_mask & hotkey_mask; +- mask = hotkey_source_mask & hotkey_mask; ++ poll_mask = hotkey_source_mask; ++ event_mask = hotkey_source_mask & ++ (hotkey_driver_mask | hotkey_user_mask); + poll_freq = hotkey_poll_freq; mutex_unlock(&hotkey_thread_data_mutex); - if (likely(mask)) { -@@ -2131,6 +2345,7 @@ exit: +- if (likely(mask)) { +- hotkey_read_nvram(&s[si], mask); ++ if (likely(poll_mask)) { ++ hotkey_read_nvram(&s[si], poll_mask); + if (likely(si != so)) { + hotkey_compare_and_issue_event(&s[so], &s[si], +- mask); ++ event_mask); + } + } + +@@ -2131,6 +2507,7 @@ exit: return 0; } @@ -792573,7 +803760,7 @@ index e856008..f78d275 100644 static void hotkey_poll_stop_sync(void) { if (tpacpi_hotkey_task) { -@@ -2147,10 +2362,11 @@ static void hotkey_poll_stop_sync(void) +@@ -2147,11 +2524,14 @@ static void hotkey_poll_stop_sync(void) } /* call with hotkey_mutex held */ @@ -792582,25 +803769,32 @@ index e856008..f78d275 100644 { - if ((hotkey_source_mask & hotkey_mask) != 0 && - hotkey_poll_freq > 0 && -+ u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask; +- (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { ++ const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; ++ const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; + -+ if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 && - (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { ++ if (hotkey_poll_freq > 0 && ++ (poll_driver_mask || ++ (poll_user_mask && tpacpi_inputdev->users > 0))) { if (!tpacpi_hotkey_task) { tpacpi_hotkey_task = kthread_run(hotkey_kthread, -@@ -2164,26 +2380,37 @@ static void hotkey_poll_setup(int may_warn) + NULL, TPACPI_NVRAM_KTHREAD_NAME); +@@ -2164,26 +2544,36 @@ static void hotkey_poll_setup(int may_warn) } } else { hotkey_poll_stop_sync(); - if (may_warn && - hotkey_source_mask != 0 && hotkey_poll_freq == 0) { -+ if (may_warn && hotkeys_to_poll != 0 && ++ if (may_warn && (poll_driver_mask || poll_user_mask) && + hotkey_poll_freq == 0) { printk(TPACPI_NOTICE - "hot keys 0x%08x require polling, " - "which is currently disabled\n", +- "hot keys 0x%08x require polling, " +- "which is currently disabled\n", - hotkey_source_mask); -+ hotkeys_to_poll); ++ "hot keys 0x%08x and/or events 0x%08x " ++ "require polling, which is currently " ++ "disabled\n", ++ poll_user_mask, poll_driver_mask); } } } @@ -792619,9 +803813,7 @@ index e856008..f78d275 100644 + if (!freq) + hotkey_poll_stop_sync(); + -+ HOTKEY_CONFIG_CRITICAL_START + hotkey_poll_freq = freq; -+ HOTKEY_CONFIG_CRITICAL_END +} + #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ @@ -792631,7 +803823,7 @@ index e856008..f78d275 100644 { } -@@ -2201,7 +2428,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) +@@ -2201,7 +2591,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) case TPACPI_LIFE_EXITING: return -EBUSY; case TPACPI_LIFE_RUNNING: @@ -792640,17 +803832,41 @@ index e856008..f78d275 100644 return 0; } -@@ -2214,7 +2441,7 @@ static void hotkey_inputdev_close(struct input_dev *dev) +@@ -2213,8 +2603,9 @@ static int hotkey_inputdev_open(struct input_dev *dev) + static void hotkey_inputdev_close(struct input_dev *dev) { /* disable hotkey polling when possible */ - if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) +- if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) - hotkey_poll_setup_safe(0); ++ if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && ++ !(hotkey_source_mask & hotkey_driver_mask)) + hotkey_poll_setup_safe(false); } /* sysfs hotkey enable ------------------------------------------------- */ -@@ -2288,7 +2515,7 @@ static ssize_t hotkey_mask_store(struct device *dev, - res = hotkey_mask_set(t); +@@ -2261,15 +2652,7 @@ static ssize_t hotkey_mask_show(struct device *dev, + struct device_attribute *attr, + char *buf) + { +- int res; +- +- if (mutex_lock_killable(&hotkey_mutex)) +- return -ERESTARTSYS; +- res = hotkey_mask_get(); +- mutex_unlock(&hotkey_mutex); +- +- return (res)? +- res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask); ++ return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask); + } + + static ssize_t hotkey_mask_store(struct device *dev, +@@ -2285,10 +2668,10 @@ static ssize_t hotkey_mask_store(struct device *dev, + if (mutex_lock_killable(&hotkey_mutex)) + return -ERESTARTSYS; + +- res = hotkey_mask_set(t); ++ res = hotkey_user_mask_set(t); #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL - hotkey_poll_setup(1); @@ -792658,7 +803874,7 @@ index e856008..f78d275 100644 #endif mutex_unlock(&hotkey_mutex); -@@ -2318,6 +2545,8 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, +@@ -2318,6 +2701,8 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -792667,17 +803883,47 @@ index e856008..f78d275 100644 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); } -@@ -2377,7 +2606,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev, +@@ -2365,6 +2750,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev, + const char *buf, size_t count) + { + unsigned long t; ++ u32 r_ev; ++ int rc; + + if (parse_strtoul(buf, 0xffffffffUL, &t) || + ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) +@@ -2377,13 +2764,28 @@ static ssize_t hotkey_source_mask_store(struct device *dev, hotkey_source_mask = t; HOTKEY_CONFIG_CRITICAL_END - hotkey_poll_setup(1); ++ rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) & ++ ~hotkey_source_mask); + hotkey_poll_setup(true); -+ hotkey_mask_set(hotkey_mask); ++ ++ /* check if events needed by the driver got disabled */ ++ r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask) ++ & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK; mutex_unlock(&hotkey_mutex); -@@ -2410,9 +2640,9 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, ++ if (rc < 0) ++ printk(TPACPI_ERR "hotkey_source_mask: failed to update the" ++ "firmware event mask!\n"); ++ ++ if (r_ev) ++ printk(TPACPI_NOTICE "hotkey_source_mask: " ++ "some important events were disabled: " ++ "0x%04x\n", r_ev); ++ + tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); + +- return count; ++ return (rc < 0) ? rc : count; + } + + static struct device_attribute dev_attr_hotkey_source_mask = +@@ -2410,9 +2812,9 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, if (mutex_lock_killable(&hotkey_mutex)) return -ERESTARTSYS; @@ -792689,7 +803935,63 @@ index e856008..f78d275 100644 mutex_unlock(&hotkey_mutex); tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); -@@ -2603,7 +2833,9 @@ static void tpacpi_send_radiosw_update(void) +@@ -2501,9 +2903,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_reason = + + static void hotkey_wakeup_reason_notify_change(void) + { +- if (tp_features.hotkey_mask) +- sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, +- "wakeup_reason"); ++ sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, ++ "wakeup_reason"); + } + + /* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ +@@ -2520,9 +2921,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete = + + static void hotkey_wakeup_hotunplug_complete_notify_change(void) + { +- if (tp_features.hotkey_mask) +- sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, +- "wakeup_hotunplug_complete"); ++ sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, ++ "wakeup_hotunplug_complete"); + } + + /* --------------------------------------------------------------------- */ +@@ -2530,27 +2930,19 @@ static void hotkey_wakeup_hotunplug_complete_notify_change(void) + static struct attribute *hotkey_attributes[] __initdata = { + &dev_attr_hotkey_enable.attr, + &dev_attr_hotkey_bios_enabled.attr, ++ &dev_attr_hotkey_bios_mask.attr, + &dev_attr_hotkey_report_mode.attr, +-#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL ++ &dev_attr_hotkey_wakeup_reason.attr, ++ &dev_attr_hotkey_wakeup_hotunplug_complete.attr, + &dev_attr_hotkey_mask.attr, + &dev_attr_hotkey_all_mask.attr, + &dev_attr_hotkey_recommended_mask.attr, ++#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL + &dev_attr_hotkey_source_mask.attr, + &dev_attr_hotkey_poll_freq.attr, + #endif + }; + +-static struct attribute *hotkey_mask_attributes[] __initdata = { +- &dev_attr_hotkey_bios_mask.attr, +-#ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL +- &dev_attr_hotkey_mask.attr, +- &dev_attr_hotkey_all_mask.attr, +- &dev_attr_hotkey_recommended_mask.attr, +-#endif +- &dev_attr_hotkey_wakeup_reason.attr, +- &dev_attr_hotkey_wakeup_hotunplug_complete.attr, +-}; +- + /* + * Sync both the hw and sw blocking state of all switches + */ +@@ -2603,7 +2995,9 @@ static void tpacpi_send_radiosw_update(void) static void hotkey_exit(void) { #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL @@ -792699,23 +804001,84 @@ index e856008..f78d275 100644 #endif if (hotkey_dev_attributes) -@@ -2623,6 +2855,15 @@ static void hotkey_exit(void) - } - } +@@ -2611,18 +3005,56 @@ static void hotkey_exit(void) + kfree(hotkey_keycode_map); + +- if (tp_features.hotkey) { +- dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, +- "restoring original hot key mask\n"); +- /* no short-circuit boolean operator below! */ +- if ((hotkey_mask_set(hotkey_orig_mask) | +- hotkey_status_set(false)) != 0) +- printk(TPACPI_ERR +- "failed to restore hot key mask " +- "to BIOS defaults\n"); ++ dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, ++ "restoring original HKEY status and mask\n"); ++ /* yes, there is a bitwise or below, we want the ++ * functions to be called even if one of them fail */ ++ if (((tp_features.hotkey_mask && ++ hotkey_mask_set(hotkey_orig_mask)) | ++ hotkey_status_set(false)) != 0) ++ printk(TPACPI_ERR ++ "failed to restore hot key mask " ++ "to BIOS defaults\n"); ++} ++ +static void __init hotkey_unmap(const unsigned int scancode) +{ + if (hotkey_keycode_map[scancode] != KEY_RESERVED) { + clear_bit(hotkey_keycode_map[scancode], + tpacpi_inputdev->keybit); + hotkey_keycode_map[scancode] = KEY_RESERVED; -+ } -+} + } + } + ++/* ++ * HKEY quirks: ++ * TPACPI_HK_Q_INIMASK: Supports FN+F3,FN+F4,FN+F12 ++ */ ++ ++#define TPACPI_HK_Q_INIMASK 0x0001 ++ ++static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { ++ TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK), /* 600E */ ++ TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK), /* 600E */ ++ TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK), /* 770, 770E, 770ED */ ++ TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK), /* A20m */ ++ TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK), /* A20p */ ++ TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK), /* A21e, A22e */ ++ TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK), /* A21e */ ++ TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK), /* A21m, A22m */ ++ TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK), /* A21p, A22p */ ++ TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK), /* A22e */ ++ TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK), /* A22m */ ++ TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK), /* A30/p (0) */ ++ TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK), /* R30 */ ++ TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK), /* R31 */ ++ TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK), /* T20 */ ++ TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK), /* T21 */ ++ TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK), /* T22 */ ++ TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK), /* X20, X21 */ ++ TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ ++}; + static int __init hotkey_init(struct ibm_init_struct *iibm) { /* Requirements for changing the default keymaps: -@@ -2701,11 +2942,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) +@@ -2665,9 +3097,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + KEY_UNKNOWN, /* 0x0D: FN+INSERT */ + KEY_UNKNOWN, /* 0x0E: FN+DELETE */ + +- /* brightness: firmware always reacts to them, unless +- * X.org did some tricks in the radeon BIOS scratch +- * registers of *some* models */ ++ /* brightness: firmware always reacts to them */ + KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ + KEY_RESERVED, /* 0x10: FN+END (brightness down) */ + +@@ -2701,11 +3131,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) KEY_UNKNOWN, /* 0x0D: FN+INSERT */ KEY_UNKNOWN, /* 0x0E: FN+DELETE */ @@ -792732,18 +804095,116 @@ index e856008..f78d275 100644 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ -@@ -2831,19 +3072,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) - goto err_exit; +@@ -2742,6 +3172,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + int status; + int hkeyv; + ++ unsigned long quirks; ++ + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "initializing hotkey subdriver\n"); + +@@ -2767,9 +3199,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + if (!tp_features.hotkey) + return 1; + ++ quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable, ++ ARRAY_SIZE(tpacpi_hotkey_qtable)); ++ + tpacpi_disable_brightness_delay(); + +- hotkey_dev_attributes = create_attr_set(13, NULL); ++ /* MUST have enough space for all attributes to be added to ++ * hotkey_dev_attributes */ ++ hotkey_dev_attributes = create_attr_set( ++ ARRAY_SIZE(hotkey_attributes) + 2, ++ NULL); + if (!hotkey_dev_attributes) + return -ENOMEM; + res = add_many_to_attr_set(hotkey_dev_attributes, +@@ -2778,7 +3217,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + if (res) + goto err_exit; + +- /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, ++ /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p, + A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking + for HKEY interface version 0x100 */ + if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { +@@ -2792,10 +3231,22 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + * MHKV 0x100 in A31, R40, R40e, + * T4x, X31, and later + */ +- tp_features.hotkey_mask = 1; + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "firmware HKEY interface version: 0x%x\n", + hkeyv); ++ ++ /* Paranoia check AND init hotkey_all_mask */ ++ if (!acpi_evalf(hkey_handle, &hotkey_all_mask, ++ "MHKA", "qd")) { ++ printk(TPACPI_ERR ++ "missing MHKA handler, " ++ "please report this to %s\n", ++ TPACPI_MAIL); ++ /* Fallback: pre-init for FN+F3,F4,F12 */ ++ hotkey_all_mask = 0x080cU; ++ } else { ++ tp_features.hotkey_mask = 1; ++ } + } } +@@ -2803,47 +3254,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + "hotkey masks are %s\n", + str_supported(tp_features.hotkey_mask)); + +- if (tp_features.hotkey_mask) { +- if (!acpi_evalf(hkey_handle, &hotkey_all_mask, +- "MHKA", "qd")) { +- printk(TPACPI_ERR +- "missing MHKA handler, " +- "please report this to %s\n", +- TPACPI_MAIL); +- /* FN+F12, FN+F4, FN+F3 */ +- hotkey_all_mask = 0x080cU; +- } +- } ++ /* Init hotkey_all_mask if not initialized yet */ ++ if (!tp_features.hotkey_mask && !hotkey_all_mask && ++ (quirks & TPACPI_HK_Q_INIMASK)) ++ hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ + +- /* hotkey_source_mask *must* be zero for +- * the first hotkey_mask_get */ ++ /* Init hotkey_acpi_mask and hotkey_orig_mask */ + if (tp_features.hotkey_mask) { ++ /* hotkey_source_mask *must* be zero for ++ * the first hotkey_mask_get to return hotkey_orig_mask */ + res = hotkey_mask_get(); + if (res) + goto err_exit; + +- hotkey_orig_mask = hotkey_mask; +- res = add_many_to_attr_set( +- hotkey_dev_attributes, +- hotkey_mask_attributes, +- ARRAY_SIZE(hotkey_mask_attributes)); +- if (res) +- goto err_exit; +- } +- -#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL - if (tp_features.hotkey_mask) { - hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK - & ~hotkey_all_mask; -- } else { ++ hotkey_orig_mask = hotkey_acpi_mask; + } else { - hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; -- } -- ++ hotkey_orig_mask = hotkey_all_mask; ++ hotkey_acpi_mask = hotkey_all_mask; + } + - vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, - "hotkey source mask 0x%08x, polling freq %d\n", - hotkey_source_mask, hotkey_poll_freq); @@ -792752,7 +804213,7 @@ index e856008..f78d275 100644 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES if (dbg_wlswemul) { tp_features.hotkey_wlsw = 1; -@@ -2944,17 +3172,31 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) +@@ -2944,17 +3373,26 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) "Disabling thinkpad-acpi brightness events " "by default...\n"); @@ -792773,14 +804234,9 @@ index e856008..f78d275 100644 } +#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL -+ if (tp_features.hotkey_mask) { -+ hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK -+ & ~hotkey_all_mask -+ & ~hotkey_reserved_mask; -+ } else { -+ hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK -+ & ~hotkey_reserved_mask; -+ } ++ hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK ++ & ~hotkey_all_mask ++ & ~hotkey_reserved_mask; + + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "hotkey source mask 0x%08x, polling freq %u\n", @@ -792790,7 +804246,29 @@ index e856008..f78d275 100644 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, "enabling firmware HKEY event interface...\n"); res = hotkey_status_set(true); -@@ -2978,7 +3220,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) +@@ -2962,13 +3400,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) + hotkey_exit(); + return res; + } +- res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) +- & ~hotkey_reserved_mask) +- | hotkey_orig_mask); ++ res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask) ++ | hotkey_driver_mask) ++ & ~hotkey_source_mask); + if (res < 0 && res != -ENXIO) { + hotkey_exit(); + return res; + } ++ hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask) ++ & ~hotkey_reserved_mask; ++ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, ++ "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n", ++ hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask); + + dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, + "legacy ibm/hotkey event reporting over procfs %s\n", +@@ -2978,7 +3421,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) tpacpi_inputdev->open = &hotkey_inputdev_open; tpacpi_inputdev->close = &hotkey_inputdev_close; @@ -792799,7 +804277,150 @@ index e856008..f78d275 100644 tpacpi_send_radiosw_update(); tpacpi_input_send_tabletsw(); -@@ -3266,7 +3508,7 @@ static void hotkey_resume(void) +@@ -3003,7 +3446,7 @@ static bool hotkey_notify_hotkey(const u32 hkey, + if (scancode > 0 && scancode < 0x21) { + scancode--; + if (!(hotkey_source_mask & (1 << scancode))) { +- tpacpi_input_send_key(scancode); ++ tpacpi_input_send_key_masked(scancode); + *send_acpi_ev = false; + } else { + *ignore_acpi_ev = true; +@@ -3022,20 +3465,20 @@ static bool hotkey_notify_wakeup(const u32 hkey, + *ignore_acpi_ev = false; + + switch (hkey) { +- case 0x2304: /* suspend, undock */ +- case 0x2404: /* hibernation, undock */ ++ case TP_HKEY_EV_WKUP_S3_UNDOCK: /* suspend, undock */ ++ case TP_HKEY_EV_WKUP_S4_UNDOCK: /* hibernation, undock */ + hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; + *ignore_acpi_ev = true; + break; + +- case 0x2305: /* suspend, bay eject */ +- case 0x2405: /* hibernation, bay eject */ ++ case TP_HKEY_EV_WKUP_S3_BAYEJ: /* suspend, bay eject */ ++ case TP_HKEY_EV_WKUP_S4_BAYEJ: /* hibernation, bay eject */ + hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; + *ignore_acpi_ev = true; + break; + +- case 0x2313: /* Battery on critical low level (S3) */ +- case 0x2413: /* Battery on critical low level (S4) */ ++ case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */ ++ case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */ + printk(TPACPI_ALERT + "EMERGENCY WAKEUP: battery almost empty\n"); + /* how to auto-heal: */ +@@ -3065,21 +3508,21 @@ static bool hotkey_notify_usrevent(const u32 hkey, + *ignore_acpi_ev = false; + + switch (hkey) { +- case 0x5010: /* Lenovo new BIOS: brightness changed */ +- case 0x500b: /* X61t: tablet pen inserted into bay */ +- case 0x500c: /* X61t: tablet pen removed from bay */ ++ case TP_HKEY_EV_PEN_INSERTED: /* X61t: tablet pen inserted into bay */ ++ case TP_HKEY_EV_PEN_REMOVED: /* X61t: tablet pen removed from bay */ + return true; + +- case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ +- case 0x500a: /* X41t-X61t: swivel down (normal mode) */ ++ case TP_HKEY_EV_TABLET_TABLET: /* X41t-X61t: tablet mode */ ++ case TP_HKEY_EV_TABLET_NOTEBOOK: /* X41t-X61t: normal mode */ + tpacpi_input_send_tabletsw(); + hotkey_tablet_mode_notify_change(); + *send_acpi_ev = false; + return true; + +- case 0x5001: +- case 0x5002: +- /* LID switch events. Do not propagate */ ++ case TP_HKEY_EV_LID_CLOSE: /* Lid closed */ ++ case TP_HKEY_EV_LID_OPEN: /* Lid opened */ ++ case TP_HKEY_EV_BRGHT_CHANGED: /* brightness changed */ ++ /* do not propagate these events */ + *ignore_acpi_ev = true; + return true; + +@@ -3097,30 +3540,30 @@ static bool hotkey_notify_thermal(const u32 hkey, + *ignore_acpi_ev = false; + + switch (hkey) { +- case 0x6011: ++ case TP_HKEY_EV_ALARM_BAT_HOT: + printk(TPACPI_CRIT + "THERMAL ALARM: battery is too hot!\n"); + /* recommended action: warn user through gui */ + return true; +- case 0x6012: ++ case TP_HKEY_EV_ALARM_BAT_XHOT: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: battery is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + return true; +- case 0x6021: ++ case TP_HKEY_EV_ALARM_SENSOR_HOT: + printk(TPACPI_CRIT + "THERMAL ALARM: " + "a sensor reports something is too hot!\n"); + /* recommended action: warn user through gui, that */ + /* some internal component is too hot */ + return true; +- case 0x6022: ++ case TP_HKEY_EV_ALARM_SENSOR_XHOT: + printk(TPACPI_ALERT + "THERMAL EMERGENCY: " + "a sensor reports something is extremely hot!\n"); + /* recommended action: immediate sleep/hibernate */ + return true; +- case 0x6030: ++ case TP_HKEY_EV_THM_TABLE_CHANGED: + printk(TPACPI_INFO + "EC reports that Thermal Table has changed\n"); + /* recommended action: do nothing, we don't have +@@ -3178,7 +3621,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) + break; + case 3: + /* 0x3000-0x3FFF: bay-related wakeups */ +- if (hkey == 0x3003) { ++ if (hkey == TP_HKEY_EV_BAYEJ_ACK) { + hotkey_autosleep_ack = 1; + printk(TPACPI_INFO + "bay ejected\n"); +@@ -3190,7 +3633,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) + break; + case 4: + /* 0x4000-0x4FFF: dock-related wakeups */ +- if (hkey == 0x4003) { ++ if (hkey == TP_HKEY_EV_UNDOCK_ACK) { + hotkey_autosleep_ack = 1; + printk(TPACPI_INFO + "undocked\n"); +@@ -3212,7 +3655,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) + break; + case 7: + /* 0x7000-0x7FFF: misc */ +- if (tp_features.hotkey_wlsw && hkey == 0x7000) { ++ if (tp_features.hotkey_wlsw && ++ hkey == TP_HKEY_EV_RFKILL_CHANGED) { + tpacpi_send_radiosw_update(); + send_acpi_ev = 0; + known_ev = true; +@@ -3258,15 +3702,17 @@ static void hotkey_resume(void) + { + tpacpi_disable_brightness_delay(); + +- if (hotkey_mask_get()) ++ if (hotkey_status_set(true) < 0 || ++ hotkey_mask_set(hotkey_acpi_mask) < 0) + printk(TPACPI_ERR +- "error while trying to read hot key mask " +- "from firmware\n"); ++ "error while attempting to reset the event " ++ "firmware interface\n"); ++ + tpacpi_send_radiosw_update(); hotkey_tablet_mode_notify_change(); hotkey_wakeup_reason_notify_change(); hotkey_wakeup_hotunplug_complete_notify_change(); @@ -792808,7 +804429,27 @@ index e856008..f78d275 100644 } /* procfs -------------------------------------------------------------- */ -@@ -3338,7 +3580,8 @@ static int hotkey_write(char *buf) +@@ -3290,8 +3736,8 @@ static int hotkey_read(char *p) + return res; + + len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); +- if (tp_features.hotkey_mask) { +- len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); ++ if (hotkey_all_mask) { ++ len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask); + len += sprintf(p + len, + "commands:\tenable, disable, reset, \n"); + } else { +@@ -3328,7 +3774,7 @@ static int hotkey_write(char *buf) + if (mutex_lock_killable(&hotkey_mutex)) + return -ERESTARTSYS; + +- mask = hotkey_mask; ++ mask = hotkey_user_mask; + + res = 0; + while ((cmd = next_cmd(&buf))) { +@@ -3338,7 +3784,8 @@ static int hotkey_write(char *buf) hotkey_enabledisable_warn(0); res = -EPERM; } else if (strlencmp(cmd, "reset") == 0) { @@ -792818,7 +804459,23 @@ index e856008..f78d275 100644 } else if (sscanf(cmd, "0x%x", &mask) == 1) { /* mask set */ } else if (sscanf(cmd, "%x", &mask) == 1) { -@@ -5655,16 +5898,16 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { +@@ -3349,12 +3796,11 @@ static int hotkey_write(char *buf) + } + } + +- if (!res) ++ if (!res) { + tpacpi_disclose_usertask("procfs hotkey", + "set mask to 0x%08x\n", mask); +- +- if (!res && mask != hotkey_mask) +- res = hotkey_mask_set(mask); ++ res = hotkey_user_mask_set(mask); ++ } + + errexit: + mutex_unlock(&hotkey_mutex); +@@ -5655,16 +6101,16 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { /* Models with ATI GPUs known to require ECNVRAM mode */ TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ @@ -792839,7 +804496,41 @@ index e856008..f78d275 100644 /* Models with Intel GMA900 */ TPACPI_Q_IBM('7', '0', TPACPI_BRGHT_Q_NOEC), /* T43, R52 */ -@@ -7524,9 +7767,11 @@ static int __init probe_for_thinkpad(void) +@@ -5767,8 +6213,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm) + TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, + &ibm_backlight_data); + if (IS_ERR(ibm_backlight_device)) { ++ int rc = PTR_ERR(ibm_backlight_device); ++ ibm_backlight_device = NULL; + printk(TPACPI_ERR "Could not register backlight device\n"); +- return PTR_ERR(ibm_backlight_device); ++ return rc; + } + vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, + "brightness is supported\n"); +@@ -7256,6 +7704,21 @@ static struct ibm_struct fan_driver_data = { + **************************************************************************** + ****************************************************************************/ + ++/* ++ * HKEY event callout for other subdrivers go here ++ * (yes, it is ugly, but it is quick, safe, and gets the job done ++ */ ++static void tpacpi_driver_event(const unsigned int hkey_event) ++{ ++} ++ ++ ++ ++static void hotkey_driver_event(const unsigned int scancode) ++{ ++ tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode); ++} ++ + /* sysfs name ---------------------------------------------------------- */ + static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, + struct device_attribute *attr, +@@ -7524,9 +7987,11 @@ static int __init probe_for_thinkpad(void) /* * Non-ancient models have better DMI tagging, but very old models @@ -792853,7 +804544,7 @@ index e856008..f78d275 100644 /* ec is required because many other handles are relative to it */ TPACPI_ACPIHANDLE_INIT(ec); -@@ -7537,13 +7782,6 @@ static int __init probe_for_thinkpad(void) +@@ -7537,13 +8002,6 @@ static int __init probe_for_thinkpad(void) return -ENODEV; } @@ -802304,6 +813995,28 @@ index e01b955..cdb7050 100644 MODULE_AUTHOR("Mark Jackson "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:rtc-ds1390"); +diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c +index 0b6b773..539676e 100644 +--- a/drivers/rtc/rtc-ds1511.c ++++ b/drivers/rtc/rtc-ds1511.c +@@ -2,7 +2,7 @@ + * An rtc driver for the Dallas DS1511 + * + * Copyright (C) 2006 Atsushi Nemoto +- * Copyright (C) 2007 Andrew Sharp ++ * Copyright (C) 2007 Andrew Sharp + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -636,7 +636,7 @@ ds1511_rtc_exit(void) + module_init(ds1511_rtc_init); + module_exit(ds1511_rtc_exit); + +-MODULE_AUTHOR("Andrew Sharp "); ++MODULE_AUTHOR("Andrew Sharp "); + MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); + MODULE_LICENSE("GPL"); + MODULE_VERSION(DRV_VERSION); diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index c51589e..a774ca3 100644 --- a/drivers/rtc/rtc-ds3234.c @@ -806409,10 +818122,18 @@ index 31b902e..77571b6 100644 pr_info("%s unloaded.\n", ur_banner); } diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c -index 1bbae43..c431198 100644 +index 1bbae43..82daa3c 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c -@@ -275,7 +275,7 @@ struct zcore_header { +@@ -14,7 +14,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -275,7 +274,7 @@ struct zcore_header { u32 num_pages; u32 pad1; u64 tod; @@ -807189,7 +818910,7 @@ index 9763eee..68d6b0b 100644 int (*fn_unknown)(struct subchannel_id, void *), void *data); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c -index d593bc7..f780bdd 100644 +index d593bc7..2ee093e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -131,6 +131,10 @@ static void io_subchannel_shutdown(struct subchannel *); @@ -807554,7 +819275,16 @@ index d593bc7..f780bdd 100644 CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, priv->dev_id.devno); ccw_device_schedule_sch_unregister(cdev); -@@ -1688,10 +1700,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) +@@ -1597,7 +1609,7 @@ int ccw_purge_blacklisted(void) + return 0; + } + +-static void device_set_disconnected(struct ccw_device *cdev) ++void ccw_device_set_disconnected(struct ccw_device *cdev) + { + if (!cdev) + return; +@@ -1688,16 +1700,12 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) spin_unlock_irqrestore(sch->lock, flags); css_sch_device_unregister(sch); spin_lock_irqsave(sch->lock, flags); @@ -807565,6 +819295,13 @@ index d593bc7..f780bdd 100644 break; case REPROBE: ccw_device_trigger_reprobe(cdev); + break; + case DISC: +- device_set_disconnected(cdev); ++ ccw_device_set_disconnected(cdev); + break; + default: + break; @@ -1712,7 +1720,6 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow) #ifdef CONFIG_CCW_CONSOLE @@ -807623,7 +819360,7 @@ index d593bc7..f780bdd 100644 } } diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h -index e397510..ed39a2c 100644 +index e397510..246c648 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h @@ -74,6 +74,7 @@ dev_fsm_final_state(struct ccw_device *cdev) @@ -807634,43 +819371,80 @@ index e397510..ed39a2c 100644 void io_subchannel_recog_done(struct ccw_device *cdev); void io_subchannel_init_config(struct subchannel *sch); +@@ -124,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *); + void ccw_device_trigger_reprobe(struct ccw_device *); + void ccw_device_kill_io(struct ccw_device *); + int ccw_device_notify(struct ccw_device *, int); ++void ccw_device_set_disconnected(struct ccw_device *cdev); + void ccw_device_set_notoper(struct ccw_device *cdev); + + /* qdio needs this. */ diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c -index 3db88c5..e728ce4 100644 +index 3db88c5..3b0f408 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c -@@ -394,6 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state) +@@ -387,12 +387,35 @@ ccw_device_done(struct ccw_device *cdev, int state) + + cdev->private->state = state; + +- if (state == DEV_STATE_BOXED) { ++ switch (state) { ++ case DEV_STATE_BOXED: + CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", + cdev->private->dev_id.devno, sch->schid.sch_no); + if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) ccw_device_schedule_sch_unregister(cdev); cdev->private->flags.donotify = 0; - } -+ if (state == DEV_STATE_NOT_OPER) { ++ break; ++ case DEV_STATE_NOT_OPER: + CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", + cdev->private->dev_id.devno, sch->schid.sch_no); + if (!ccw_device_notify(cdev, CIO_GONE)) + ccw_device_schedule_sch_unregister(cdev); ++ else ++ ccw_device_set_disconnected(cdev); + cdev->private->flags.donotify = 0; -+ } ++ break; ++ case DEV_STATE_DISCONNECTED: ++ CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel " ++ "%04x\n", cdev->private->dev_id.devno, ++ sch->schid.sch_no); ++ if (!ccw_device_notify(cdev, CIO_NO_PATH)) ++ ccw_device_schedule_sch_unregister(cdev); ++ else ++ ccw_device_set_disconnected(cdev); ++ cdev->private->flags.donotify = 0; ++ break; ++ default: ++ break; + } if (cdev->private->flags.donotify) { - cdev->private->flags.donotify = 0; -@@ -731,6 +738,17 @@ static void ccw_device_generic_notoper(struct ccw_device *cdev, - } - - /* +@@ -723,10 +746,20 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) + static void ccw_device_generic_notoper(struct ccw_device *cdev, + enum dev_event dev_event) + { +- struct subchannel *sch; ++ if (!ccw_device_notify(cdev, CIO_GONE)) ++ ccw_device_schedule_sch_unregister(cdev); ++ else ++ ccw_device_set_disconnected(cdev); ++} ++ ++/* + * Handle path verification event in offline state. + */ +static void ccw_device_offline_verify(struct ccw_device *cdev, + enum dev_event dev_event) +{ + struct subchannel *sch = to_subchannel(cdev->dev.parent); -+ -+ css_schedule_eval(sch->schid); -+} -+ -+/* - * Handle path verification event. - */ - static void -@@ -887,6 +905,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) + +- ccw_device_set_notoper(cdev); +- sch = to_subchannel(cdev->dev.parent); + css_schedule_eval(sch->schid); + } + +@@ -887,6 +920,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event) } call_handler: cdev->private->state = DEV_STATE_ONLINE; @@ -807679,7 +819453,7 @@ index 3db88c5..e728ce4 100644 /* Call the handler. */ if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify) /* Start delayed path verification. */ -@@ -1149,7 +1169,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { +@@ -1149,7 +1184,7 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq, [DEV_EVENT_TIMEOUT] = ccw_device_nop, @@ -815414,7 +827188,7 @@ index 6d46516..869a30b 100644 }; diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig -index 9c23122..9cce88b 100644 +index 9c23122..e11cca4 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -366,6 +366,7 @@ config ISCSI_TCP @@ -815438,11 +827212,36 @@ index 9c23122..9cce88b 100644 config SCSI_SRP tristate "SCSI RDMA Protocol helper library" depends on SCSI && PCI +@@ -1821,6 +1828,16 @@ config SCSI_SRP + To compile this driver as a module, choose M here: the + module will be called libsrp. + ++config SCSI_BFA_FC ++ tristate "Brocade BFA Fibre Channel Support" ++ depends on PCI && SCSI ++ select SCSI_FC_ATTRS ++ help ++ This bfa driver supports all Brocade PCIe FC/FCOE host adapters. ++ ++ To compile this driver as a module, choose M here. The module will ++ be called bfa. ++ + endif # SCSI_LOWLEVEL + + source "drivers/scsi/pcmcia/Kconfig" diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile -index 25429ea..c6788bf 100644 +index 25429ea..3ad61db 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile -@@ -130,6 +130,8 @@ obj-$(CONFIG_SCSI_MVSAS) += mvsas/ +@@ -86,6 +86,7 @@ obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o + obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ + obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ + obj-$(CONFIG_SCSI_LPFC) += lpfc/ ++obj-$(CONFIG_SCSI_BFA_FC) += bfa/ + obj-$(CONFIG_SCSI_PAS16) += pas16.o + obj-$(CONFIG_SCSI_T128) += t128.o + obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o +@@ -130,6 +131,8 @@ obj-$(CONFIG_SCSI_MVSAS) += mvsas/ obj-$(CONFIG_PS3_ROM) += ps3rom.o obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/ obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/ @@ -822646,6 +834445,50347 @@ index 0000000..00e816e + unsigned short issue_reset, + unsigned short savecfg_flag); +#endif +diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile +new file mode 100644 +index 0000000..1d60094 +--- /dev/null ++++ b/drivers/scsi/bfa/Makefile +@@ -0,0 +1,15 @@ ++obj-$(CONFIG_SCSI_BFA_FC) := bfa.o ++ ++bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o ++ ++bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o ++bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o ++bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o ++bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o ++bfa-y += bfa_csdebug.o bfa_sm.o plog.o ++ ++bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o ++bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o ++bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o ++ ++ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna +diff --git a/drivers/scsi/bfa/bfa_callback_priv.h b/drivers/scsi/bfa/bfa_callback_priv.h +new file mode 100644 +index 0000000..1e3265c +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_callback_priv.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_CALLBACK_PRIV_H__ ++#define __BFA_CALLBACK_PRIV_H__ ++ ++#include ++ ++typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); ++ ++/** ++ * Generic BFA callback element. ++ */ ++struct bfa_cb_qe_s { ++ struct list_head qe; ++ bfa_cb_cbfn_t cbfn; ++ bfa_boolean_t once; ++ u32 rsvd; ++ void *cbarg; ++}; ++ ++#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \ ++ (__hcb_qe)->cbfn = (__cbfn); \ ++ (__hcb_qe)->cbarg = (__cbarg); \ ++ list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \ ++} while (0) ++ ++#define bfa_cb_dequeue(__hcb_qe) list_del(&(__hcb_qe)->qe) ++ ++#define bfa_cb_queue_once(__bfa, __hcb_qe, __cbfn, __cbarg) do { \ ++ (__hcb_qe)->cbfn = (__cbfn); \ ++ (__hcb_qe)->cbarg = (__cbarg); \ ++ if (!(__hcb_qe)->once) { \ ++ list_add_tail((__hcb_qe), &(__bfa)->comp_q); \ ++ (__hcb_qe)->once = BFA_TRUE; \ ++ } \ ++} while (0) ++ ++#define bfa_cb_queue_done(__hcb_qe) do { \ ++ (__hcb_qe)->once = BFA_FALSE; \ ++} while (0) ++ ++#endif /* __BFA_CALLBACK_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h +new file mode 100644 +index 0000000..0050c83 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h +@@ -0,0 +1,205 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_cb_ioim_macros.h BFA IOIM driver interface macros. ++ */ ++ ++#ifndef __BFA_HCB_IOIM_MACROS_H__ ++#define __BFA_HCB_IOIM_MACROS_H__ ++ ++#include ++/* ++ * #include ++ * ++ * #include #include #include ++ * #include ++ */ ++#include "bfad_im_compat.h" ++ ++/* ++ * task attribute values in FCP-2 FCP_CMND IU ++ */ ++#define SIMPLE_Q 0 ++#define HEAD_OF_Q 1 ++#define ORDERED_Q 2 ++#define ACA_Q 4 ++#define UNTAGGED 5 ++ ++static inline lun_t ++bfad_int_to_lun(u32 luno) ++{ ++ union { ++ u16 scsi_lun[4]; ++ lun_t bfa_lun; ++ } lun; ++ ++ lun.bfa_lun = 0; ++ lun.scsi_lun[0] = bfa_os_htons(luno); ++ ++ return (lun.bfa_lun); ++} ++ ++/** ++ * Get LUN for the I/O request ++ */ ++#define bfa_cb_ioim_get_lun(__dio) \ ++ bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun) ++ ++/** ++ * Get CDB for the I/O request ++ */ ++static inline u8 * ++bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ ++ return ((u8 *) cmnd->cmnd); ++} ++ ++/** ++ * Get I/O direction (read/write) for the I/O request ++ */ ++static inline enum fcp_iodir ++bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ enum dma_data_direction dmadir; ++ ++ dmadir = cmnd->sc_data_direction; ++ if (dmadir == DMA_TO_DEVICE) ++ return FCP_IODIR_WRITE; ++ else if (dmadir == DMA_FROM_DEVICE) ++ return FCP_IODIR_READ; ++ else ++ return FCP_IODIR_NONE; ++} ++ ++/** ++ * Get IO size in bytes for the I/O request ++ */ ++static inline u32 ++bfa_cb_ioim_get_size(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ ++ return (scsi_bufflen(cmnd)); ++} ++ ++/** ++ * Get timeout for the I/O request ++ */ ++static inline u8 ++bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ /* ++ * TBD: need a timeout for scsi passthru ++ */ ++ if (cmnd->device->host == NULL) ++ return 4; ++ ++ return 0; ++} ++ ++/** ++ * Get SG element for the I/O request given the SG element index ++ */ ++static inline union bfi_addr_u ++bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ struct scatterlist *sge; ++ u64 addr; ++ ++ sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid; ++ addr = (u64) sg_dma_address(sge); ++ ++ return (*(union bfi_addr_u *) &addr); ++} ++ ++static inline u32 ++bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ struct scatterlist *sge; ++ u32 len; ++ ++ sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid; ++ len = sg_dma_len(sge); ++ ++ return len; ++} ++ ++/** ++ * Get Command Reference Number for the I/O request. 0 if none. ++ */ ++static inline u8 ++bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio) ++{ ++ return 0; ++} ++ ++/** ++ * Get SAM-3 priority for the I/O request. 0 is default. ++ */ ++static inline u8 ++bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio) ++{ ++ return 0; ++} ++ ++/** ++ * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0). ++ */ ++static inline u8 ++bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ u8 task_attr = UNTAGGED; ++ ++ if (cmnd->device->tagged_supported) { ++ switch (cmnd->tag) { ++ case HEAD_OF_QUEUE_TAG: ++ task_attr = HEAD_OF_Q; ++ break; ++ case ORDERED_QUEUE_TAG: ++ task_attr = ORDERED_Q; ++ break; ++ default: ++ task_attr = SIMPLE_Q; ++ break; ++ } ++ } ++ ++ return task_attr; ++} ++ ++/** ++ * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16). ++ */ ++static inline u8 ++bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ ++ return (cmnd->cmd_len); ++} ++ ++ ++ ++#endif /* __BFA_HCB_IOIM_MACROS_H__ */ +diff --git a/drivers/scsi/bfa/bfa_cee.c b/drivers/scsi/bfa/bfa_cee.c +new file mode 100644 +index 0000000..7a959c3 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_cee.c +@@ -0,0 +1,492 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(CNA, CEE); ++ ++#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) ++#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc) ++ ++static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg); ++static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s ++ *dcbcx_stats); ++static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s ++ *lldp_stats); ++static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats); ++static void bfa_cee_format_cee_cfg(void *buffer); ++static void bfa_cee_format_cee_stats(void *buffer); ++ ++static void ++bfa_cee_format_cee_stats(void *buffer) ++{ ++ struct bfa_cee_stats_s *cee_stats = buffer; ++ bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats); ++ bfa_cee_format_lldp_stats(&cee_stats->lldp_stats); ++ bfa_cee_format_cfg_stats(&cee_stats->cfg_stats); ++} ++ ++static void ++bfa_cee_format_cee_cfg(void *buffer) ++{ ++ struct bfa_cee_attr_s *cee_cfg = buffer; ++ bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote); ++} ++ ++static void ++bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats) ++{ ++ dcbcx_stats->subtlvs_unrecognized = ++ bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized); ++ dcbcx_stats->negotiation_failed = ++ bfa_os_ntohl(dcbcx_stats->negotiation_failed); ++ dcbcx_stats->remote_cfg_changed = ++ bfa_os_ntohl(dcbcx_stats->remote_cfg_changed); ++ dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received); ++ dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid); ++ dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno); ++ dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno); ++ dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno); ++ dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno); ++} ++ ++static void ++bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats) ++{ ++ lldp_stats->frames_transmitted = ++ bfa_os_ntohl(lldp_stats->frames_transmitted); ++ lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out); ++ lldp_stats->frames_discarded = ++ bfa_os_ntohl(lldp_stats->frames_discarded); ++ lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error); ++ lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd); ++ lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded); ++ lldp_stats->tlvs_unrecognized = ++ bfa_os_ntohl(lldp_stats->tlvs_unrecognized); ++} ++ ++static void ++bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats) ++{ ++ cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down); ++ cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up); ++ cfg_stats->cee_hw_cfg_changed = ++ bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed); ++ cfg_stats->recvd_invalid_cfg = ++ bfa_os_ntohl(cfg_stats->recvd_invalid_cfg); ++} ++ ++static void ++bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg) ++{ ++ lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval); ++ lldp_cfg->enabled_system_cap = ++ bfa_os_ntohs(lldp_cfg->enabled_system_cap); ++} ++ ++/** ++ * bfa_cee_attr_meminfo() ++ * ++ * ++ * @param[in] void ++ * ++ * @return Size of DMA region ++ */ ++static u32 ++bfa_cee_attr_meminfo(void) ++{ ++ return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ); ++} ++ ++/** ++ * bfa_cee_stats_meminfo() ++ * ++ * ++ * @param[in] void ++ * ++ * @return Size of DMA region ++ */ ++static u32 ++bfa_cee_stats_meminfo(void) ++{ ++ return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ); ++} ++ ++/** ++ * bfa_cee_get_attr_isr() ++ * ++ * ++ * @param[in] cee - Pointer to the CEE module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status) ++{ ++ cee->get_attr_status = status; ++ bfa_trc(cee, 0); ++ if (status == BFA_STATUS_OK) { ++ bfa_trc(cee, 0); ++ /* ++ * The requested data has been copied to the DMA area, *process ++ * it. ++ */ ++ memcpy(cee->attr, cee->attr_dma.kva, ++ sizeof(struct bfa_cee_attr_s)); ++ bfa_cee_format_cee_cfg(cee->attr); ++ } ++ cee->get_attr_pending = BFA_FALSE; ++ if (cee->cbfn.get_attr_cbfn) { ++ bfa_trc(cee, 0); ++ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); ++ } ++ bfa_trc(cee, 0); ++} ++ ++/** ++ * bfa_cee_get_attr_isr() ++ * ++ * ++ * @param[in] cee - Pointer to the CEE module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) ++{ ++ cee->get_stats_status = status; ++ bfa_trc(cee, 0); ++ if (status == BFA_STATUS_OK) { ++ bfa_trc(cee, 0); ++ /* ++ * The requested data has been copied to the DMA area, process ++ * it. ++ */ ++ memcpy(cee->stats, cee->stats_dma.kva, ++ sizeof(struct bfa_cee_stats_s)); ++ bfa_cee_format_cee_stats(cee->stats); ++ } ++ cee->get_stats_pending = BFA_FALSE; ++ bfa_trc(cee, 0); ++ if (cee->cbfn.get_stats_cbfn) { ++ bfa_trc(cee, 0); ++ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); ++ } ++ bfa_trc(cee, 0); ++} ++ ++/** ++ * bfa_cee_get_attr_isr() ++ * ++ * ++ * @param[in] cee - Pointer to the CEE module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status) ++{ ++ cee->reset_stats_status = status; ++ cee->reset_stats_pending = BFA_FALSE; ++ if (cee->cbfn.reset_stats_cbfn) ++ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); ++} ++ ++/** ++ * bfa_cee_meminfo() ++ * ++ * ++ * @param[in] void ++ * ++ * @return Size of DMA region ++ */ ++u32 ++bfa_cee_meminfo(void) ++{ ++ return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo()); ++} ++ ++/** ++ * bfa_cee_mem_claim() ++ * ++ * ++ * @param[in] cee CEE module pointer ++ * dma_kva Kernel Virtual Address of CEE DMA Memory ++ * dma_pa Physical Address of CEE DMA Memory ++ * ++ * @return void ++ */ ++void ++bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa) ++{ ++ cee->attr_dma.kva = dma_kva; ++ cee->attr_dma.pa = dma_pa; ++ cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo(); ++ cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo(); ++ cee->attr = (struct bfa_cee_attr_s *)dma_kva; ++ cee->stats = ++ (struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo()); ++} ++ ++/** ++ * bfa_cee_get_attr() ++ * ++ * Send the request to the f/w to fetch CEE attributes. ++ * ++ * @param[in] Pointer to the CEE module data structure. ++ * ++ * @return Status ++ */ ++ ++bfa_status_t ++bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr, ++ bfa_cee_get_attr_cbfn_t cbfn, void *cbarg) ++{ ++ struct bfi_cee_get_req_s *cmd; ++ ++ bfa_assert((cee != NULL) && (cee->ioc != NULL)); ++ bfa_trc(cee, 0); ++ if (!bfa_ioc_is_operational(cee->ioc)) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ if (cee->get_attr_pending == BFA_TRUE) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_DEVBUSY; ++ } ++ cee->get_attr_pending = BFA_TRUE; ++ cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg; ++ cee->attr = attr; ++ cee->cbfn.get_attr_cbfn = cbfn; ++ cee->cbfn.get_attr_cbarg = cbarg; ++ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ, ++ bfa_ioc_portid(cee->ioc)); ++ bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa); ++ bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb); ++ bfa_trc(cee, 0); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_cee_get_stats() ++ * ++ * Send the request to the f/w to fetch CEE statistics. ++ * ++ * @param[in] Pointer to the CEE module data structure. ++ * ++ * @return Status ++ */ ++ ++bfa_status_t ++bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats, ++ bfa_cee_get_stats_cbfn_t cbfn, void *cbarg) ++{ ++ struct bfi_cee_get_req_s *cmd; ++ ++ bfa_assert((cee != NULL) && (cee->ioc != NULL)); ++ ++ if (!bfa_ioc_is_operational(cee->ioc)) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ if (cee->get_stats_pending == BFA_TRUE) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_DEVBUSY; ++ } ++ cee->get_stats_pending = BFA_TRUE; ++ cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg; ++ cee->stats = stats; ++ cee->cbfn.get_stats_cbfn = cbfn; ++ cee->cbfn.get_stats_cbarg = cbarg; ++ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ, ++ bfa_ioc_portid(cee->ioc)); ++ bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa); ++ bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb); ++ bfa_trc(cee, 0); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_cee_reset_stats() ++ * ++ * ++ * @param[in] Pointer to the CEE module data structure. ++ * ++ * @return Status ++ */ ++ ++bfa_status_t ++bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn, ++ void *cbarg) ++{ ++ struct bfi_cee_reset_stats_s *cmd; ++ ++ bfa_assert((cee != NULL) && (cee->ioc != NULL)); ++ if (!bfa_ioc_is_operational(cee->ioc)) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ if (cee->reset_stats_pending == BFA_TRUE) { ++ bfa_trc(cee, 0); ++ return BFA_STATUS_DEVBUSY; ++ } ++ cee->reset_stats_pending = BFA_TRUE; ++ cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg; ++ cee->cbfn.reset_stats_cbfn = cbfn; ++ cee->cbfn.reset_stats_cbarg = cbarg; ++ bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS, ++ bfa_ioc_portid(cee->ioc)); ++ bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb); ++ bfa_trc(cee, 0); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_cee_isrs() ++ * ++ * ++ * @param[in] Pointer to the CEE module data structure. ++ * ++ * @return void ++ */ ++ ++void ++bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m) ++{ ++ union bfi_cee_i2h_msg_u *msg; ++ struct bfi_cee_get_rsp_s *get_rsp; ++ struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg; ++ msg = (union bfi_cee_i2h_msg_u *)m; ++ get_rsp = (struct bfi_cee_get_rsp_s *)m; ++ bfa_trc(cee, msg->mh.msg_id); ++ switch (msg->mh.msg_id) { ++ case BFI_CEE_I2H_GET_CFG_RSP: ++ bfa_trc(cee, get_rsp->cmd_status); ++ bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); ++ break; ++ case BFI_CEE_I2H_GET_STATS_RSP: ++ bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); ++ break; ++ case BFI_CEE_I2H_RESET_STATS_RSP: ++ bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); ++ break; ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * bfa_cee_hbfail() ++ * ++ * ++ * @param[in] Pointer to the CEE module data structure. ++ * ++ * @return void ++ */ ++ ++void ++bfa_cee_hbfail(void *arg) ++{ ++ struct bfa_cee_s *cee; ++ cee = (struct bfa_cee_s *)arg; ++ ++ if (cee->get_attr_pending == BFA_TRUE) { ++ cee->get_attr_status = BFA_STATUS_FAILED; ++ cee->get_attr_pending = BFA_FALSE; ++ if (cee->cbfn.get_attr_cbfn) { ++ cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, ++ BFA_STATUS_FAILED); ++ } ++ } ++ if (cee->get_stats_pending == BFA_TRUE) { ++ cee->get_stats_status = BFA_STATUS_FAILED; ++ cee->get_stats_pending = BFA_FALSE; ++ if (cee->cbfn.get_stats_cbfn) { ++ cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, ++ BFA_STATUS_FAILED); ++ } ++ } ++ if (cee->reset_stats_pending == BFA_TRUE) { ++ cee->reset_stats_status = BFA_STATUS_FAILED; ++ cee->reset_stats_pending = BFA_FALSE; ++ if (cee->cbfn.reset_stats_cbfn) { ++ cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, ++ BFA_STATUS_FAILED); ++ } ++ } ++} ++ ++/** ++ * bfa_cee_attach() ++ * ++ * ++ * @param[in] cee - Pointer to the CEE module data structure ++ * ioc - Pointer to the ioc module data structure ++ * dev - Pointer to the device driver module data structure ++ * The device driver specific mbox ISR functions have ++ * this pointer as one of the parameters. ++ * trcmod - ++ * logmod - ++ * ++ * @return void ++ */ ++void ++bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev, ++ struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod) ++{ ++ bfa_assert(cee != NULL); ++ cee->dev = dev; ++ cee->trcmod = trcmod; ++ cee->logmod = logmod; ++ cee->ioc = ioc; ++ ++ bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); ++ bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee); ++ bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail); ++ bfa_trc(cee, 0); ++} ++ ++/** ++ * bfa_cee_detach() ++ * ++ * ++ * @param[in] cee - Pointer to the CEE module data structure ++ * ++ * @return void ++ */ ++void ++bfa_cee_detach(struct bfa_cee_s *cee) ++{ ++ /* ++ * For now, just check if there is some ioctl pending and mark that as ++ * failed? ++ */ ++ /* bfa_cee_hbfail(cee); */ ++} +diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c +new file mode 100644 +index 0000000..44e2d11 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_core.c +@@ -0,0 +1,402 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define DEF_CFG_NUM_FABRICS 1 ++#define DEF_CFG_NUM_LPORTS 256 ++#define DEF_CFG_NUM_CQS 4 ++#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX) ++#define DEF_CFG_NUM_TSKIM_REQS 128 ++#define DEF_CFG_NUM_FCXP_REQS 64 ++#define DEF_CFG_NUM_UF_BUFS 64 ++#define DEF_CFG_NUM_RPORTS 1024 ++#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS) ++#define DEF_CFG_NUM_TINS 256 ++ ++#define DEF_CFG_NUM_SGPGS 2048 ++#define DEF_CFG_NUM_REQQ_ELEMS 256 ++#define DEF_CFG_NUM_RSPQ_ELEMS 64 ++#define DEF_CFG_NUM_SBOOT_TGTS 16 ++#define DEF_CFG_NUM_SBOOT_LUNS 16 ++ ++/** ++ * Use this function query the memory requirement of the BFA library. ++ * This function needs to be called before bfa_attach() to get the ++ * memory required of the BFA layer for a given driver configuration. ++ * ++ * This call will fail, if the cap is out of range compared to pre-defined ++ * values within the BFA library ++ * ++ * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate ++ * its configuration in this structure. ++ * The default values for struct bfa_iocfc_cfg_s can be ++ * fetched using bfa_cfg_get_default() API. ++ * ++ * If cap's boundary check fails, the library will use ++ * the default bfa_cap_t values (and log a warning msg). ++ * ++ * @param[out] meminfo - pointer to bfa_meminfo_t. This content ++ * indicates the memory type (see bfa_mem_type_t) and ++ * amount of memory required. ++ * ++ * Driver should allocate the memory, populate the ++ * starting address for each block and provide the same ++ * structure as input parameter to bfa_attach() call. ++ * ++ * @return void ++ * ++ * Special Considerations: @note ++ */ ++void ++bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo) ++{ ++ int i; ++ u32 km_len = 0, dm_len = 0; ++ ++ bfa_assert((cfg != NULL) && (meminfo != NULL)); ++ ++ bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s)); ++ meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type = ++ BFA_MEM_TYPE_KVA; ++ meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type = ++ BFA_MEM_TYPE_DMA; ++ ++ bfa_iocfc_meminfo(cfg, &km_len, &dm_len); ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->meminfo(cfg, &km_len, &dm_len); ++ ++ ++ meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len; ++ meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len; ++} ++ ++/** ++ * Use this function to do attach the driver instance with the BFA ++ * library. This function will not trigger any HW initialization ++ * process (which will be done in bfa_init() call) ++ * ++ * This call will fail, if the cap is out of range compared to ++ * pre-defined values within the BFA library ++ * ++ * @param[out] bfa Pointer to bfa_t. ++ * @param[in] bfad Opaque handle back to the driver's IOC structure ++ * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure ++ * that was used in bfa_cfg_get_meminfo(). ++ * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should ++ * use the bfa_cfg_get_meminfo() call to ++ * find the memory blocks required, allocate the ++ * required memory and provide the starting addresses. ++ * @param[in] pcidev pointer to struct bfa_pcidev_s ++ * ++ * @return ++ * void ++ * ++ * Special Considerations: ++ * ++ * @note ++ * ++ */ ++void ++bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ int i; ++ struct bfa_mem_elem_s *melem; ++ ++ bfa->fcs = BFA_FALSE; ++ ++ bfa_assert((cfg != NULL) && (meminfo != NULL)); ++ ++ /** ++ * initialize all memory pointers for iterative allocation ++ */ ++ for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { ++ melem = meminfo->meminfo + i; ++ melem->kva_curp = melem->kva; ++ melem->dma_curp = melem->dma; ++ } ++ ++ bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev); ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev); ++ ++} ++ ++/** ++ * Use this function to delete a BFA IOC. IOC should be stopped (by ++ * calling bfa_stop()) before this function call. ++ * ++ * @param[in] bfa - pointer to bfa_t. ++ * ++ * @return ++ * void ++ * ++ * Special Considerations: ++ * ++ * @note ++ */ ++void ++bfa_detach(struct bfa_s *bfa) ++{ ++ int i; ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->detach(bfa); ++ ++ bfa_iocfc_detach(bfa); ++} ++ ++ ++void ++bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod) ++{ ++ bfa->trcmod = trcmod; ++} ++ ++ ++void ++bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod) ++{ ++ bfa->logm = logmod; ++} ++ ++ ++void ++bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen) ++{ ++ bfa->aen = aen; ++} ++ ++void ++bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog) ++{ ++ bfa->plog = plog; ++} ++ ++/** ++ * Initialize IOC. ++ * ++ * This function will return immediately, when the IOC initialization is ++ * completed, the bfa_cb_init() will be called. ++ * ++ * @param[in] bfa instance ++ * ++ * @return void ++ * ++ * Special Considerations: ++ * ++ * @note ++ * When this function returns, the driver should register the interrupt service ++ * routine(s) and enable the device interrupts. If this is not done, ++ * bfa_cb_init() will never get called ++ */ ++void ++bfa_init(struct bfa_s *bfa) ++{ ++ bfa_iocfc_init(bfa); ++} ++ ++/** ++ * Use this function initiate the IOC configuration setup. This function ++ * will return immediately. ++ * ++ * @param[in] bfa instance ++ * ++ * @return None ++ */ ++void ++bfa_start(struct bfa_s *bfa) ++{ ++ bfa_iocfc_start(bfa); ++} ++ ++/** ++ * Use this function quiese the IOC. This function will return immediately, ++ * when the IOC is actually stopped, the bfa_cb_stop() will be called. ++ * ++ * @param[in] bfa - pointer to bfa_t. ++ * ++ * @return None ++ * ++ * Special Considerations: ++ * bfa_cb_stop() could be called before or after bfa_stop() returns. ++ * ++ * @note ++ * In case of any failure, we could handle it automatically by doing a ++ * reset and then succeed the bfa_stop() call. ++ */ ++void ++bfa_stop(struct bfa_s *bfa) ++{ ++ bfa_iocfc_stop(bfa); ++} ++ ++void ++bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q) ++{ ++ INIT_LIST_HEAD(comp_q); ++ list_splice_tail_init(&bfa->comp_q, comp_q); ++} ++ ++void ++bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) ++{ ++ struct list_head *qe; ++ struct list_head *qen; ++ struct bfa_cb_qe_s *hcb_qe; ++ ++ list_for_each_safe(qe, qen, comp_q) { ++ hcb_qe = (struct bfa_cb_qe_s *) qe; ++ hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); ++ } ++} ++ ++void ++bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q) ++{ ++ struct list_head *qe; ++ struct bfa_cb_qe_s *hcb_qe; ++ ++ while (!list_empty(comp_q)) { ++ bfa_q_deq(comp_q, &qe); ++ hcb_qe = (struct bfa_cb_qe_s *) qe; ++ hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE); ++ } ++} ++ ++void ++bfa_attach_fcs(struct bfa_s *bfa) ++{ ++ bfa->fcs = BFA_TRUE; ++} ++ ++/** ++ * Periodic timer heart beat from driver ++ */ ++void ++bfa_timer_tick(struct bfa_s *bfa) ++{ ++ bfa_timer_beat(&bfa->timer_mod); ++} ++ ++#ifndef BFA_BIOS_BUILD ++/** ++ * Return the list of PCI vendor/device id lists supported by this ++ * BFA instance. ++ */ ++void ++bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids) ++{ ++ static struct bfa_pciid_s __pciids[] = { ++ {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P}, ++ {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P}, ++ {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT}, ++ }; ++ ++ *npciids = sizeof(__pciids) / sizeof(__pciids[0]); ++ *pciids = __pciids; ++} ++ ++/** ++ * Use this function query the default struct bfa_iocfc_cfg_s value (compiled ++ * into BFA layer). The OS driver can then turn back and overwrite entries that ++ * have been configured by the user. ++ * ++ * @param[in] cfg - pointer to bfa_ioc_cfg_t ++ * ++ * @return ++ * void ++ * ++ * Special Considerations: ++ * note ++ */ ++void ++bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg) ++{ ++ cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS; ++ cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS; ++ cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS; ++ cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS; ++ cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS; ++ cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS; ++ cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS; ++ cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS; ++ ++ cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS; ++ cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS; ++ cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS; ++ cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS; ++ cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS; ++ cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF; ++ cfg->drvcfg.ioc_recover = BFA_FALSE; ++ cfg->drvcfg.delay_comp = BFA_FALSE; ++ ++} ++ ++void ++bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg) ++{ ++ bfa_cfg_get_default(cfg); ++ cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; ++ cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; ++ cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN; ++ cfg->fwcfg.num_uf_bufs = BFA_UF_MIN; ++ cfg->fwcfg.num_rports = BFA_RPORT_MIN; ++ ++ cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; ++ cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN; ++ cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN; ++ cfg->drvcfg.min_cfg = BFA_TRUE; ++} ++ ++void ++bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr) ++{ ++ bfa_ioc_get_attr(&bfa->ioc, ioc_attr); ++} ++ ++/** ++ * Retrieve firmware trace information on IOC failure. ++ */ ++bfa_status_t ++bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen) ++{ ++ return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen); ++} ++ ++/** ++ * Fetch firmware trace data. ++ * ++ * @param[in] bfa BFA instance ++ * @param[out] trcdata Firmware trace buffer ++ * @param[in,out] trclen Firmware trace buffer len ++ * ++ * @retval BFA_STATUS_OK Firmware trace is fetched. ++ * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress. ++ */ ++bfa_status_t ++bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen) ++{ ++ return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen); ++} ++#endif +diff --git a/drivers/scsi/bfa/bfa_csdebug.c b/drivers/scsi/bfa/bfa_csdebug.c +new file mode 100644 +index 0000000..1b71d34 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_csdebug.c +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ * cs_debug_api ++ */ ++ ++ ++void ++bfa_panic(int line, char *file, char *panicstr) ++{ ++ bfa_log(NULL, BFA_LOG_HAL_ASSERT, file, line, panicstr); ++ bfa_os_panic(); ++} ++ ++void ++bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event) ++{ ++ bfa_log(logm, BFA_LOG_HAL_SM_ASSERT, file, line, event); ++ bfa_os_panic(); ++} ++ ++int ++bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe) ++{ ++ struct list_head *tqe; ++ ++ tqe = bfa_q_next(q); ++ while (tqe != q) { ++ if (tqe == qe) ++ return (1); ++ tqe = bfa_q_next(tqe); ++ if (tqe == NULL) ++ break; ++ } ++ return (0); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c +new file mode 100644 +index 0000000..401babe +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcpim.c +@@ -0,0 +1,175 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++BFA_TRC_FILE(HAL, FCPIM); ++BFA_MODULE(fcpim); ++ ++/** ++ * hal_fcpim_mod BFA FCP Initiator Mode module ++ */ ++ ++/** ++ * Compute and return memory needed by FCP(im) module. ++ */ ++static void ++bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len) ++{ ++ bfa_itnim_meminfo(cfg, km_len, dm_len); ++ ++ /** ++ * IO memory ++ */ ++ if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN) ++ cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; ++ else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX) ++ cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX; ++ ++ *km_len += cfg->fwcfg.num_ioim_reqs * ++ (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s)); ++ ++ *dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN; ++ ++ /** ++ * task management command memory ++ */ ++ if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN) ++ cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; ++ *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s); ++} ++ ++ ++static void ++bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ bfa_trc(bfa, cfg->drvcfg.path_tov); ++ bfa_trc(bfa, cfg->fwcfg.num_rports); ++ bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs); ++ bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs); ++ ++ fcpim->bfa = bfa; ++ fcpim->num_itnims = cfg->fwcfg.num_rports; ++ fcpim->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs; ++ fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs; ++ fcpim->path_tov = cfg->drvcfg.path_tov; ++ fcpim->delay_comp = cfg->drvcfg.delay_comp; ++ ++ bfa_itnim_attach(fcpim, meminfo); ++ bfa_tskim_attach(fcpim, meminfo); ++ bfa_ioim_attach(fcpim, meminfo); ++} ++ ++static void ++bfa_fcpim_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcpim_detach(struct bfa_s *bfa) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ bfa_ioim_detach(fcpim); ++ bfa_tskim_detach(fcpim); ++} ++ ++static void ++bfa_fcpim_start(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcpim_stop(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcpim_iocdisable(struct bfa_s *bfa) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfa_itnim_s *itnim; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &fcpim->itnim_q) { ++ itnim = (struct bfa_itnim_s *) qe; ++ bfa_itnim_iocdisable(itnim); ++ } ++} ++ ++void ++bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ fcpim->path_tov = path_tov * 1000; ++ if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX) ++ fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX; ++} ++ ++u16 ++bfa_fcpim_path_tov_get(struct bfa_s *bfa) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ return (fcpim->path_tov / 1000); ++} ++ ++bfa_status_t ++bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_fcpim_stats_s *modstats) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ *modstats = fcpim->stats; ++ ++ return BFA_STATUS_OK; ++} ++ ++bfa_status_t ++bfa_fcpim_clr_modstats(struct bfa_s *bfa) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ memset(&fcpim->stats, 0, sizeof(struct bfa_fcpim_stats_s)); ++ ++ return BFA_STATUS_OK; ++} ++ ++void ++bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX); ++ ++ fcpim->q_depth = q_depth; ++} ++ ++u16 ++bfa_fcpim_qdepth_get(struct bfa_s *bfa) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ ++ return (fcpim->q_depth); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h +new file mode 100644 +index 0000000..153206c +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcpim_priv.h +@@ -0,0 +1,188 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCPIM_PRIV_H__ ++#define __BFA_FCPIM_PRIV_H__ ++ ++#include ++#include ++#include ++#include "bfa_sgpg_priv.h" ++ ++#define BFA_ITNIM_MIN 32 ++#define BFA_ITNIM_MAX 1024 ++ ++#define BFA_IOIM_MIN 8 ++#define BFA_IOIM_MAX 2000 ++ ++#define BFA_TSKIM_MIN 4 ++#define BFA_TSKIM_MAX 512 ++#define BFA_FCPIM_PATHTOV_DEF (30 * 1000) /* in millisecs */ ++#define BFA_FCPIM_PATHTOV_MAX (90 * 1000) /* in millisecs */ ++ ++#define bfa_fcpim_stats(__fcpim, __stats) \ ++ (__fcpim)->stats.__stats ++ ++ ++struct bfa_fcpim_mod_s { ++ struct bfa_s *bfa; ++ struct bfa_itnim_s *itnim_arr; ++ struct bfa_ioim_s *ioim_arr; ++ struct bfa_ioim_sp_s *ioim_sp_arr; ++ struct bfa_tskim_s *tskim_arr; ++ struct bfa_dma_s snsbase; ++ int num_itnims; ++ int num_ioim_reqs; ++ int num_tskim_reqs; ++ u32 path_tov; ++ u16 q_depth; ++ u16 rsvd; ++ struct list_head itnim_q; /* queue of active itnim */ ++ struct list_head ioim_free_q; /* free IO resources */ ++ struct list_head ioim_resfree_q; /* IOs waiting for f/w */ ++ struct list_head ioim_comp_q; /* IO global comp Q */ ++ struct list_head tskim_free_q; ++ u32 ios_active; /* current active IOs */ ++ u32 delay_comp; ++ struct bfa_fcpim_stats_s stats; ++}; ++ ++struct bfa_ioim_s; ++struct bfa_tskim_s; ++ ++/** ++ * BFA IO (initiator mode) ++ */ ++struct bfa_ioim_s { ++ struct list_head qe; /* queue elememt */ ++ bfa_sm_t sm; /* BFA ioim state machine */ ++ struct bfa_s *bfa; /* BFA module */ ++ struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */ ++ struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */ ++ struct bfad_ioim_s *dio; /* driver IO handle */ ++ u16 iotag; /* FWI IO tag */ ++ u16 abort_tag; /* unqiue abort request tag */ ++ u16 nsges; /* number of SG elements */ ++ u16 nsgpgs; /* number of SG pages */ ++ struct bfa_sgpg_s *sgpg; /* first SG page */ ++ struct list_head sgpg_q; /* allocated SG pages */ ++ struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */ ++ bfa_cb_cbfn_t io_cbfn; /* IO completion handler */ ++ struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */ ++}; ++ ++struct bfa_ioim_sp_s { ++ struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */ ++ u8 *snsinfo; /* sense info for this IO */ ++ struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */ ++ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ ++ bfa_boolean_t abort_explicit; /* aborted by OS */ ++ struct bfa_tskim_s *tskim; /* Relevant TM cmd */ ++}; ++ ++/** ++ * BFA Task management command (initiator mode) ++ */ ++struct bfa_tskim_s { ++ struct list_head qe; ++ bfa_sm_t sm; ++ struct bfa_s *bfa; /* BFA module */ ++ struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */ ++ struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */ ++ struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */ ++ bfa_boolean_t notify; /* notify itnim on TM comp */ ++ lun_t lun; /* lun if applicable */ ++ enum fcp_tm_cmnd tm_cmnd; /* task management command */ ++ u16 tsk_tag; /* FWI IO tag */ ++ u8 tsecs; /* timeout in seconds */ ++ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ ++ struct list_head io_q; /* queue of affected IOs */ ++ struct bfa_wc_s wc; /* waiting counter */ ++ struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */ ++ enum bfi_tskim_status tsk_status; /* TM status */ ++}; ++ ++/** ++ * BFA i-t-n (initiator mode) ++ */ ++struct bfa_itnim_s { ++ struct list_head qe; /* queue element */ ++ bfa_sm_t sm; /* i-t-n im BFA state machine */ ++ struct bfa_s *bfa; /* bfa instance */ ++ struct bfa_rport_s *rport; /* bfa rport */ ++ void *ditn; /* driver i-t-n structure */ ++ struct bfi_mhdr_s mhdr; /* pre-built mhdr */ ++ u8 msg_no; /* itnim/rport firmware handle */ ++ u8 reqq; /* CQ for requests */ ++ struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */ ++ struct list_head pending_q; /* queue of pending IO requests*/ ++ struct list_head io_q; /* queue of active IO requests */ ++ struct list_head io_cleanup_q; /* IO being cleaned up */ ++ struct list_head tsk_q; /* queue of active TM commands */ ++ struct list_head delay_comp_q;/* queue of failed inflight cmds */ ++ bfa_boolean_t seq_rec; /* SQER supported */ ++ bfa_boolean_t is_online; /* itnim is ONLINE for IO */ ++ bfa_boolean_t iotov_active; /* IO TOV timer is active */ ++ struct bfa_wc_s wc; /* waiting counter */ ++ struct bfa_timer_s timer; /* pending IO TOV */ ++ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ ++ struct bfa_fcpim_mod_s *fcpim; /* fcpim module */ ++ struct bfa_itnim_hal_stats_s stats; ++}; ++ ++#define bfa_itnim_is_online(_itnim) (_itnim)->is_online ++#define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod) ++#define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \ ++ (&fcpim->ioim_arr[_iotag]) ++#define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \ ++ (&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)]) ++ ++/* ++ * function prototypes ++ */ ++void bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, ++ struct bfa_meminfo_s *minfo); ++void bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim); ++void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++void bfa_ioim_good_comp_isr(struct bfa_s *bfa, ++ struct bfi_msg_s *msg); ++void bfa_ioim_cleanup(struct bfa_ioim_s *ioim); ++void bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, ++ struct bfa_tskim_s *tskim); ++void bfa_ioim_iocdisable(struct bfa_ioim_s *ioim); ++void bfa_ioim_tov(struct bfa_ioim_s *ioim); ++ ++void bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, ++ struct bfa_meminfo_s *minfo); ++void bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim); ++void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++void bfa_tskim_iodone(struct bfa_tskim_s *tskim); ++void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim); ++void bfa_tskim_cleanup(struct bfa_tskim_s *tskim); ++ ++void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len); ++void bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, ++ struct bfa_meminfo_s *minfo); ++void bfa_itnim_detach(struct bfa_fcpim_mod_s *fcpim); ++void bfa_itnim_iocdisable(struct bfa_itnim_s *itnim); ++void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++void bfa_itnim_iodone(struct bfa_itnim_s *itnim); ++void bfa_itnim_tskdone(struct bfa_itnim_s *itnim); ++bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim); ++ ++#endif /* __BFA_FCPIM_PRIV_H__ */ ++ +diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c +new file mode 100644 +index 0000000..9924359 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcport.c +@@ -0,0 +1,1671 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, PPORT); ++BFA_MODULE(pport); ++ ++#define bfa_pport_callback(__pport, __event) do { \ ++ if ((__pport)->bfa->fcs) { \ ++ (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \ ++ } else { \ ++ (__pport)->hcb_event = (__event); \ ++ bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \ ++ __bfa_cb_port_event, (__pport)); \ ++ } \ ++} while (0) ++ ++/* ++ * The port is considered disabled if corresponding physical port or IOC are ++ * disabled explicitly ++ */ ++#define BFA_PORT_IS_DISABLED(bfa) \ ++ ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \ ++ (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE)) ++ ++/* ++ * forward declarations ++ */ ++static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port); ++static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port); ++static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport); ++static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport); ++static void bfa_pport_set_wwns(struct bfa_pport_s *port); ++static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); ++static void bfa_port_stats_timeout(void *cbarg); ++static void bfa_port_stats_clr_timeout(void *cbarg); ++ ++/** ++ * bfa_pport_private ++ */ ++ ++/** ++ * BFA port state machine events ++ */ ++enum bfa_pport_sm_event { ++ BFA_PPORT_SM_START = 1, /* start port state machine */ ++ BFA_PPORT_SM_STOP = 2, /* stop port state machine */ ++ BFA_PPORT_SM_ENABLE = 3, /* enable port */ ++ BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */ ++ BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */ ++ BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */ ++ BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */ ++ BFA_PPORT_SM_QRESUME = 8, /* CQ space available */ ++ BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ ++}; ++ ++static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_enabling(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_linkup(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_disabling(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_disabled(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_stopped(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event); ++ ++static struct bfa_sm_table_s hal_pport_sm_table[] = { ++ {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, ++ {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, ++ {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING}, ++ {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN}, ++ {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP}, ++ {BFA_SM(bfa_pport_sm_disabling_qwait), ++ BFA_PPORT_ST_DISABLING_QWAIT}, ++ {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING}, ++ {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED}, ++ {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED}, ++ {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN}, ++ {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN}, ++}; ++ ++static void ++bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = pport->bfa->logm; ++ wwn_t pwwn = pport->pwwn; ++ char pwwn_ptr[BFA_STRING_32]; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ wwn2str(pwwn_ptr, pwwn); ++ switch (event) { ++ case BFA_PORT_AEN_ONLINE: ++ bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr); ++ break; ++ case BFA_PORT_AEN_OFFLINE: ++ bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr); ++ break; ++ case BFA_PORT_AEN_ENABLE: ++ bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr); ++ break; ++ case BFA_PORT_AEN_DISABLE: ++ bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr); ++ break; ++ case BFA_PORT_AEN_DISCONNECT: ++ bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr); ++ break; ++ case BFA_PORT_AEN_QOS_NEG: ++ bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr); ++ break; ++ default: ++ break; ++ } ++ ++ bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr); ++ aen_data.port.ioc_type = ioc_attr.ioc_type; ++ aen_data.port.pwwn = pwwn; ++} ++ ++static void ++bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_START: ++ /** ++ * Start event after IOC is configured and BFA is started. ++ */ ++ if (bfa_pport_send_enable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ /** ++ * Port is persistently configured to be in enabled state. Do ++ * not change state. Port enabling is done when START event is ++ * received. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ /** ++ * If a port is persistently configured to be disabled, the ++ * first event will a port disable request. ++ */ ++ bfa_sm_set_state(pport, bfa_pport_sm_disabled); ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_QRESUME: ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ bfa_pport_send_enable(pport); ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_reqq_wcancel(&pport->reqq_wait); ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ /** ++ * Already enable is in progress. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ /** ++ * Just send disable request to firmware when room becomes ++ * available in request queue. ++ */ ++ bfa_sm_set_state(pport, bfa_pport_sm_disabled); ++ bfa_reqq_wcancel(&pport->reqq_wait); ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); ++ break; ++ ++ case BFA_PPORT_SM_LINKUP: ++ case BFA_PPORT_SM_LINKDOWN: ++ /** ++ * Possible to get link events when doing back-to-back ++ * enable/disables. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_reqq_wcancel(&pport->reqq_wait); ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_FWRSP: ++ case BFA_PPORT_SM_LINKDOWN: ++ bfa_sm_set_state(pport, bfa_pport_sm_linkdown); ++ break; ++ ++ case BFA_PPORT_SM_LINKUP: ++ bfa_pport_update_linkinfo(pport); ++ bfa_sm_set_state(pport, bfa_pport_sm_linkup); ++ ++ bfa_assert(pport->event_cbfn); ++ bfa_pport_callback(pport, BFA_PPORT_LINKUP); ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ /** ++ * Already being enabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ if (bfa_pport_send_disable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); ++ ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_LINKUP: ++ bfa_pport_update_linkinfo(pport); ++ bfa_sm_set_state(pport, bfa_pport_sm_linkup); ++ bfa_assert(pport->event_cbfn); ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup"); ++ bfa_pport_callback(pport, BFA_PPORT_LINKUP); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE); ++ /** ++ * If QoS is enabled and it is not online, ++ * Send a separate event. ++ */ ++ if ((pport->cfg.qos_enabled) ++ && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE)) ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG); ++ ++ break; ++ ++ case BFA_PPORT_SM_LINKDOWN: ++ /** ++ * Possible to get link down event. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ /** ++ * Already enabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ if (bfa_pport_send_disable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); ++ ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_ENABLE: ++ /** ++ * Already enabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ if (bfa_pport_send_disable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait); ++ ++ bfa_pport_reset_linkinfo(pport); ++ bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE); ++ break; ++ ++ case BFA_PPORT_SM_LINKDOWN: ++ bfa_sm_set_state(pport, bfa_pport_sm_linkdown); ++ bfa_pport_reset_linkinfo(pport); ++ bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); ++ if (BFA_PORT_IS_DISABLED(pport->bfa)) { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); ++ } else { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); ++ } ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ bfa_pport_reset_linkinfo(pport); ++ if (BFA_PORT_IS_DISABLED(pport->bfa)) { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); ++ } else { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); ++ } ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ bfa_pport_reset_linkinfo(pport); ++ bfa_pport_callback(pport, BFA_PPORT_LINKDOWN); ++ if (BFA_PORT_IS_DISABLED(pport->bfa)) { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE); ++ } else { ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT); ++ } ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport, ++ enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_QRESUME: ++ bfa_sm_set_state(pport, bfa_pport_sm_disabling); ++ bfa_pport_send_disable(pport); ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ bfa_reqq_wcancel(&pport->reqq_wait); ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ /** ++ * Already being disabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_LINKUP: ++ case BFA_PPORT_SM_LINKDOWN: ++ /** ++ * Possible to get link events when doing back-to-back ++ * enable/disables. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocfail); ++ bfa_reqq_wcancel(&pport->reqq_wait); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_FWRSP: ++ bfa_sm_set_state(pport, bfa_pport_sm_disabled); ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ /** ++ * Already being disabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ if (bfa_pport_send_enable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); ++ ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ break; ++ ++ case BFA_PPORT_SM_LINKUP: ++ case BFA_PPORT_SM_LINKDOWN: ++ /** ++ * Possible to get link events when doing back-to-back ++ * enable/disables. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocfail); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_START: ++ /** ++ * Ignore start event for a port that is disabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_STOP: ++ bfa_sm_set_state(pport, bfa_pport_sm_stopped); ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ if (bfa_pport_send_enable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); ++ ++ bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL, ++ BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); ++ bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE); ++ break; ++ ++ case BFA_PPORT_SM_DISABLE: ++ /** ++ * Already disabled. ++ */ ++ break; ++ ++ case BFA_PPORT_SM_HWFAIL: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocfail); ++ break; ++ ++ default: ++ bfa_sm_fault(pport->bfa, event); ++ } ++} ++ ++static void ++bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_START: ++ if (bfa_pport_send_enable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); ++ break; ++ ++ default: ++ /** ++ * Ignore all other events. ++ */ ++ ; ++ } ++} ++ ++/** ++ * Port is enabled. IOC is down/failed. ++ */ ++static void ++bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_START: ++ if (bfa_pport_send_enable(pport)) ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling); ++ else ++ bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait); ++ break; ++ ++ default: ++ /** ++ * Ignore all events. ++ */ ++ ; ++ } ++} ++ ++/** ++ * Port is disabled. IOC is down/failed. ++ */ ++static void ++bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event) ++{ ++ bfa_trc(pport->bfa, event); ++ ++ switch (event) { ++ case BFA_PPORT_SM_START: ++ bfa_sm_set_state(pport, bfa_pport_sm_disabled); ++ break; ++ ++ case BFA_PPORT_SM_ENABLE: ++ bfa_sm_set_state(pport, bfa_pport_sm_iocdown); ++ break; ++ ++ default: ++ /** ++ * Ignore all events. ++ */ ++ ; ++ } ++} ++ ++ ++ ++/** ++ * bfa_pport_private ++ */ ++ ++static void ++__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_pport_s *pport = cbarg; ++ ++ if (complete) ++ pport->event_cbfn(pport->event_cbarg, pport->hcb_event); ++} ++ ++#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ ++ BFA_CACHELINE_SZ)) ++ ++static void ++bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, ++ u32 *dm_len) ++{ ++ *dm_len += PPORT_STATS_DMA_SZ; ++} ++ ++static void ++bfa_pport_qresume(void *cbarg) ++{ ++ struct bfa_pport_s *port = cbarg; ++ ++ bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME); ++} ++ ++static void ++bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo) ++{ ++ u8 *dm_kva; ++ u64 dm_pa; ++ ++ dm_kva = bfa_meminfo_dma_virt(meminfo); ++ dm_pa = bfa_meminfo_dma_phys(meminfo); ++ ++ pport->stats_kva = dm_kva; ++ pport->stats_pa = dm_pa; ++ pport->stats = (union bfa_pport_stats_u *)dm_kva; ++ ++ dm_kva += PPORT_STATS_DMA_SZ; ++ dm_pa += PPORT_STATS_DMA_SZ; ++ ++ bfa_meminfo_dma_virt(meminfo) = dm_kva; ++ bfa_meminfo_dma_phys(meminfo) = dm_pa; ++} ++ ++/** ++ * Memory initialization. ++ */ ++static void ++bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ struct bfa_pport_cfg_s *port_cfg = &pport->cfg; ++ ++ bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); ++ pport->bfa = bfa; ++ ++ bfa_pport_mem_claim(pport, meminfo); ++ ++ bfa_sm_set_state(pport, bfa_pport_sm_uninit); ++ ++ /** ++ * initialize and set default configuration ++ */ ++ port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P; ++ port_cfg->speed = BFA_PPORT_SPEED_AUTO; ++ port_cfg->trunked = BFA_FALSE; ++ port_cfg->maxfrsize = 0; ++ ++ port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS; ++ ++ bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport); ++} ++ ++static void ++bfa_pport_initdone(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ /** ++ * Initialize port attributes from IOC hardware data. ++ */ ++ bfa_pport_set_wwns(pport); ++ if (pport->cfg.maxfrsize == 0) ++ pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc); ++ pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc); ++ pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc); ++ ++ bfa_assert(pport->cfg.maxfrsize); ++ bfa_assert(pport->cfg.rx_bbcredit); ++ bfa_assert(pport->speed_sup); ++} ++ ++static void ++bfa_pport_detach(struct bfa_s *bfa) ++{ ++} ++ ++/** ++ * Called when IOC is ready. ++ */ ++static void ++bfa_pport_start(struct bfa_s *bfa) ++{ ++ bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START); ++} ++ ++/** ++ * Called before IOC is stopped. ++ */ ++static void ++bfa_pport_stop(struct bfa_s *bfa) ++{ ++ bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP); ++} ++ ++/** ++ * Called when IOC failure is detected. ++ */ ++static void ++bfa_pport_iocdisable(struct bfa_s *bfa) ++{ ++ bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL); ++} ++ ++static void ++bfa_pport_update_linkinfo(struct bfa_pport_s *pport) ++{ ++ struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event; ++ ++ pport->speed = pevent->link_state.speed; ++ pport->topology = pevent->link_state.topology; ++ ++ if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP) ++ pport->myalpa = pevent->link_state.tl.loop_info.myalpa; ++ ++ /* ++ * QoS Details ++ */ ++ bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr); ++ bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr); ++ ++ bfa_trc(pport->bfa, pport->speed); ++ bfa_trc(pport->bfa, pport->topology); ++} ++ ++static void ++bfa_pport_reset_linkinfo(struct bfa_pport_s *pport) ++{ ++ pport->speed = BFA_PPORT_SPEED_UNKNOWN; ++ pport->topology = BFA_PPORT_TOPOLOGY_NONE; ++} ++ ++/** ++ * Send port enable message to firmware. ++ */ ++static bfa_boolean_t ++bfa_pport_send_enable(struct bfa_pport_s *port) ++{ ++ struct bfi_pport_enable_req_s *m; ++ ++ /** ++ * Increment message tag before queue check, so that responses to old ++ * requests are discarded. ++ */ ++ port->msgtag++; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ if (!m) { ++ bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ, ++ bfa_lpuid(port->bfa)); ++ m->nwwn = port->nwwn; ++ m->pwwn = port->pwwn; ++ m->port_cfg = port->cfg; ++ m->msgtag = port->msgtag; ++ m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize); ++ bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa); ++ bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo); ++ bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi); ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++ return BFA_TRUE; ++} ++ ++/** ++ * Send port disable message to firmware. ++ */ ++static bfa_boolean_t ++bfa_pport_send_disable(struct bfa_pport_s *port) ++{ ++ bfi_pport_disable_req_t *m; ++ ++ /** ++ * Increment message tag before queue check, so that responses to old ++ * requests are discarded. ++ */ ++ port->msgtag++; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ if (!m) { ++ bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ, ++ bfa_lpuid(port->bfa)); ++ m->msgtag = port->msgtag; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++ ++ return BFA_TRUE; ++} ++ ++static void ++bfa_pport_set_wwns(struct bfa_pport_s *port) ++{ ++ port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc); ++ port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc); ++ ++ bfa_trc(port->bfa, port->pwwn); ++ bfa_trc(port->bfa, port->nwwn); ++} ++ ++static void ++bfa_port_send_txcredit(void *port_cbarg) ++{ ++ ++ struct bfa_pport_s *port = port_cbarg; ++ struct bfi_pport_set_svc_params_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ if (!m) { ++ bfa_trc(port->bfa, port->cfg.tx_bbcredit); ++ return; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ, ++ bfa_lpuid(port->bfa)); ++ m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit); ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++} ++ ++ ++ ++/** ++ * bfa_pport_public ++ */ ++ ++/** ++ * Firmware message handler. ++ */ ++void ++bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ union bfi_pport_i2h_msg_u i2hmsg; ++ ++ i2hmsg.msg = msg; ++ pport->event_arg.i2hmsg = i2hmsg; ++ ++ switch (msg->mhdr.msg_id) { ++ case BFI_PPORT_I2H_ENABLE_RSP: ++ if (pport->msgtag == i2hmsg.enable_rsp->msgtag) ++ bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); ++ break; ++ ++ case BFI_PPORT_I2H_DISABLE_RSP: ++ if (pport->msgtag == i2hmsg.enable_rsp->msgtag) ++ bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP); ++ break; ++ ++ case BFI_PPORT_I2H_EVENT: ++ switch (i2hmsg.event->link_state.linkstate) { ++ case BFA_PPORT_LINKUP: ++ bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP); ++ break; ++ case BFA_PPORT_LINKDOWN: ++ bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN); ++ break; ++ case BFA_PPORT_TRUNK_LINKDOWN: ++ /** todo: event notification */ ++ break; ++ } ++ break; ++ ++ case BFI_PPORT_I2H_GET_STATS_RSP: ++ case BFI_PPORT_I2H_GET_QOS_STATS_RSP: ++ /* ++ * check for timer pop before processing the rsp ++ */ ++ if (pport->stats_busy == BFA_FALSE ++ || pport->stats_status == BFA_STATUS_ETIMER) ++ break; ++ ++ bfa_timer_stop(&pport->timer); ++ pport->stats_status = i2hmsg.getstats_rsp->status; ++ bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats, ++ pport); ++ break; ++ case BFI_PPORT_I2H_CLEAR_STATS_RSP: ++ case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP: ++ /* ++ * check for timer pop before processing the rsp ++ */ ++ if (pport->stats_busy == BFA_FALSE ++ || pport->stats_status == BFA_STATUS_ETIMER) ++ break; ++ ++ bfa_timer_stop(&pport->timer); ++ pport->stats_status = BFA_STATUS_OK; ++ bfa_cb_queue(pport->bfa, &pport->hcb_qe, ++ __bfa_cb_port_stats_clr, pport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_pport_api ++ */ ++ ++/** ++ * Registered callback for port events. ++ */ ++void ++bfa_pport_event_register(struct bfa_s *bfa, ++ void (*cbfn) (void *cbarg, bfa_pport_event_t event), ++ void *cbarg) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ pport->event_cbfn = cbfn; ++ pport->event_cbarg = cbarg; ++} ++ ++bfa_status_t ++bfa_pport_enable(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ if (pport->diag_busy) ++ return (BFA_STATUS_DIAG_BUSY); ++ else if (bfa_sm_cmp_state ++ (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait)) ++ return (BFA_STATUS_DEVBUSY); ++ ++ bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE); ++ return BFA_STATUS_OK; ++} ++ ++bfa_status_t ++bfa_pport_disable(struct bfa_s *bfa) ++{ ++ bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Configure port speed. ++ */ ++bfa_status_t ++bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, speed); ++ ++ if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) { ++ bfa_trc(bfa, pport->speed_sup); ++ return BFA_STATUS_UNSUPP_SPEED; ++ } ++ ++ pport->cfg.speed = speed; ++ ++ return (BFA_STATUS_OK); ++} ++ ++/** ++ * Get current speed. ++ */ ++enum bfa_pport_speed ++bfa_pport_get_speed(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->speed; ++} ++ ++/** ++ * Configure port topology. ++ */ ++bfa_status_t ++bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, topology); ++ bfa_trc(bfa, pport->cfg.topology); ++ ++ switch (topology) { ++ case BFA_PPORT_TOPOLOGY_P2P: ++ case BFA_PPORT_TOPOLOGY_LOOP: ++ case BFA_PPORT_TOPOLOGY_AUTO: ++ break; ++ ++ default: ++ return BFA_STATUS_EINVAL; ++ } ++ ++ pport->cfg.topology = topology; ++ return (BFA_STATUS_OK); ++} ++ ++/** ++ * Get current topology. ++ */ ++enum bfa_pport_topology ++bfa_pport_get_topology(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->topology; ++} ++ ++bfa_status_t ++bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, alpa); ++ bfa_trc(bfa, pport->cfg.cfg_hardalpa); ++ bfa_trc(bfa, pport->cfg.hardalpa); ++ ++ pport->cfg.cfg_hardalpa = BFA_TRUE; ++ pport->cfg.hardalpa = alpa; ++ ++ return (BFA_STATUS_OK); ++} ++ ++bfa_status_t ++bfa_pport_clr_hardalpa(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, pport->cfg.cfg_hardalpa); ++ bfa_trc(bfa, pport->cfg.hardalpa); ++ ++ pport->cfg.cfg_hardalpa = BFA_FALSE; ++ return (BFA_STATUS_OK); ++} ++ ++bfa_boolean_t ++bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ *alpa = port->cfg.hardalpa; ++ return port->cfg.cfg_hardalpa; ++} ++ ++u8 ++bfa_pport_get_myalpa(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->myalpa; ++} ++ ++bfa_status_t ++bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, maxfrsize); ++ bfa_trc(bfa, pport->cfg.maxfrsize); ++ ++ /* ++ * with in range ++ */ ++ if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ)) ++ return (BFA_STATUS_INVLD_DFSZ); ++ ++ /* ++ * power of 2, if not the max frame size of 2112 ++ */ ++ if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1))) ++ return (BFA_STATUS_INVLD_DFSZ); ++ ++ pport->cfg.maxfrsize = maxfrsize; ++ return (BFA_STATUS_OK); ++} ++ ++u16 ++bfa_pport_get_maxfrsize(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->cfg.maxfrsize; ++} ++ ++u32 ++bfa_pport_mypid(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->mypid; ++} ++ ++u8 ++bfa_pport_get_rx_bbcredit(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return port->cfg.rx_bbcredit; ++} ++ ++void ++bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ port->cfg.tx_bbcredit = (u8) tx_bbcredit; ++ bfa_port_send_txcredit(port); ++} ++ ++/** ++ * Get port attributes. ++ */ ++ ++wwn_t ++bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ if (node) ++ return pport->nwwn; ++ else ++ return pport->pwwn; ++} ++ ++void ++bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); ++ ++ attr->nwwn = pport->nwwn; ++ attr->pwwn = pport->pwwn; ++ ++ bfa_os_memcpy(&attr->pport_cfg, &pport->cfg, ++ sizeof(struct bfa_pport_cfg_s)); ++ /* ++ * speed attributes ++ */ ++ attr->pport_cfg.speed = pport->cfg.speed; ++ attr->speed_supported = pport->speed_sup; ++ attr->speed = pport->speed; ++ attr->cos_supported = FC_CLASS_3; ++ ++ /* ++ * topology attributes ++ */ ++ attr->pport_cfg.topology = pport->cfg.topology; ++ attr->topology = pport->topology; ++ ++ /* ++ * beacon attributes ++ */ ++ attr->beacon = pport->beacon; ++ attr->link_e2e_beacon = pport->link_e2e_beacon; ++ attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog); ++ ++ attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); ++ attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); ++ attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm); ++ if (bfa_ioc_is_disabled(&pport->bfa->ioc)) ++ attr->port_state = BFA_PPORT_ST_IOCDIS; ++ else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc)) ++ attr->port_state = BFA_PPORT_ST_FWMISMATCH; ++} ++ ++static void ++bfa_port_stats_query(void *cbarg) ++{ ++ struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; ++ bfi_pport_get_stats_req_t *msg; ++ ++ msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ ++ if (!msg) { ++ port->stats_qfull = BFA_TRUE; ++ bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query, ++ port); ++ bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); ++ return; ++ } ++ port->stats_qfull = BFA_FALSE; ++ ++ bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t)); ++ bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ, ++ bfa_lpuid(port->bfa)); ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++ ++ return; ++} ++ ++static void ++bfa_port_stats_clear(void *cbarg) ++{ ++ struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; ++ bfi_pport_clear_stats_req_t *msg; ++ ++ msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ ++ if (!msg) { ++ port->stats_qfull = BFA_TRUE; ++ bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear, ++ port); ++ bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); ++ return; ++ } ++ port->stats_qfull = BFA_FALSE; ++ ++ bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t)); ++ bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ, ++ bfa_lpuid(port->bfa)); ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++ return; ++} ++ ++static void ++bfa_port_qos_stats_clear(void *cbarg) ++{ ++ struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; ++ bfi_pport_clear_qos_stats_req_t *msg; ++ ++ msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT); ++ ++ if (!msg) { ++ port->stats_qfull = BFA_TRUE; ++ bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear, ++ port); ++ bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait); ++ return; ++ } ++ port->stats_qfull = BFA_FALSE; ++ ++ bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t)); ++ bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ, ++ bfa_lpuid(port->bfa)); ++ bfa_reqq_produce(port->bfa, BFA_REQQ_PORT); ++ return; ++} ++ ++static void ++bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s) ++{ ++ u32 *dip = (u32 *) d; ++ u32 *sip = (u32 *) s; ++ int i; ++ ++ /* ++ * Do 64 bit fields swap first ++ */ ++ for (i = 0; ++ i < ++ ((sizeof(union bfa_pport_stats_u) - ++ sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) { ++#ifdef __BIGENDIAN ++ dip[i] = bfa_os_ntohl(sip[i]); ++ dip[i + 1] = bfa_os_ntohl(sip[i + 1]); ++#else ++ dip[i] = bfa_os_ntohl(sip[i + 1]); ++ dip[i + 1] = bfa_os_ntohl(sip[i]); ++#endif ++ } ++ ++ /* ++ * Now swap the 32 bit fields ++ */ ++ for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i) ++ dip[i] = bfa_os_ntohl(sip[i]); ++} ++ ++static void ++__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_pport_s *port = cbarg; ++ ++ if (complete) { ++ port->stats_cbfn(port->stats_cbarg, port->stats_status); ++ } else { ++ port->stats_busy = BFA_FALSE; ++ port->stats_status = BFA_STATUS_OK; ++ } ++} ++ ++static void ++bfa_port_stats_clr_timeout(void *cbarg) ++{ ++ struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; ++ ++ bfa_trc(port->bfa, port->stats_qfull); ++ ++ if (port->stats_qfull) { ++ bfa_reqq_wcancel(&port->stats_reqq_wait); ++ port->stats_qfull = BFA_FALSE; ++ } ++ ++ port->stats_status = BFA_STATUS_ETIMER; ++ bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port); ++} ++ ++static void ++__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_pport_s *port = cbarg; ++ ++ if (complete) { ++ if (port->stats_status == BFA_STATUS_OK) ++ bfa_pport_stats_swap(port->stats_ret, port->stats); ++ port->stats_cbfn(port->stats_cbarg, port->stats_status); ++ } else { ++ port->stats_busy = BFA_FALSE; ++ port->stats_status = BFA_STATUS_OK; ++ } ++} ++ ++static void ++bfa_port_stats_timeout(void *cbarg) ++{ ++ struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg; ++ ++ bfa_trc(port->bfa, port->stats_qfull); ++ ++ if (port->stats_qfull) { ++ bfa_reqq_wcancel(&port->stats_reqq_wait); ++ port->stats_qfull = BFA_FALSE; ++ } ++ ++ port->stats_status = BFA_STATUS_ETIMER; ++ bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port); ++} ++ ++#define BFA_PORT_STATS_TOV 1000 ++ ++/** ++ * Fetch port attributes. ++ */ ++bfa_status_t ++bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, ++ bfa_cb_pport_t cbfn, void *cbarg) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ if (port->stats_busy) { ++ bfa_trc(bfa, port->stats_busy); ++ return (BFA_STATUS_DEVBUSY); ++ } ++ ++ port->stats_busy = BFA_TRUE; ++ port->stats_ret = stats; ++ port->stats_cbfn = cbfn; ++ port->stats_cbarg = cbarg; ++ ++ bfa_port_stats_query(port); ++ ++ bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port, ++ BFA_PORT_STATS_TOV); ++ return (BFA_STATUS_OK); ++} ++ ++bfa_status_t ++bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ if (port->stats_busy) { ++ bfa_trc(bfa, port->stats_busy); ++ return (BFA_STATUS_DEVBUSY); ++ } ++ ++ port->stats_busy = BFA_TRUE; ++ port->stats_cbfn = cbfn; ++ port->stats_cbarg = cbarg; ++ ++ bfa_port_stats_clear(port); ++ ++ bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, ++ BFA_PORT_STATS_TOV); ++ return (BFA_STATUS_OK); ++} ++ ++bfa_status_t ++bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, bitmap); ++ bfa_trc(bfa, pport->cfg.trunked); ++ bfa_trc(bfa, pport->cfg.trunk_ports); ++ ++ if (!bitmap || (bitmap & (bitmap - 1))) ++ return BFA_STATUS_EINVAL; ++ ++ pport->cfg.trunked = BFA_TRUE; ++ pport->cfg.trunk_ports = bitmap; ++ ++ return BFA_STATUS_OK; ++} ++ ++void ++bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ qos_attr->state = bfa_os_ntohl(pport->qos_attr.state); ++ qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr); ++} ++ ++void ++bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, ++ struct bfa_qos_vc_attr_s *qos_vc_attr) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; ++ u32 i = 0; ++ ++ qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); ++ qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit); ++ qos_vc_attr->elp_opmode_flags = ++ bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags); ++ ++ /* ++ * Individual VC info ++ */ ++ while (i < qos_vc_attr->total_vc_count) { ++ qos_vc_attr->vc_info[i].vc_credit = ++ bfa_vc_attr->vc_info[i].vc_credit; ++ qos_vc_attr->vc_info[i].borrow_credit = ++ bfa_vc_attr->vc_info[i].borrow_credit; ++ qos_vc_attr->vc_info[i].priority = ++ bfa_vc_attr->vc_info[i].priority; ++ ++i; ++ } ++} ++ ++/** ++ * Fetch QoS Stats. ++ */ ++bfa_status_t ++bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats, ++ bfa_cb_pport_t cbfn, void *cbarg) ++{ ++ /* ++ * QoS stats is embedded in port stats ++ */ ++ return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg)); ++} ++ ++bfa_status_t ++bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ if (port->stats_busy) { ++ bfa_trc(bfa, port->stats_busy); ++ return (BFA_STATUS_DEVBUSY); ++ } ++ ++ port->stats_busy = BFA_TRUE; ++ port->stats_cbfn = cbfn; ++ port->stats_cbarg = cbarg; ++ ++ bfa_port_qos_stats_clear(port); ++ ++ bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port, ++ BFA_PORT_STATS_TOV); ++ return (BFA_STATUS_OK); ++} ++ ++/** ++ * Fetch port attributes. ++ */ ++bfa_status_t ++bfa_pport_trunk_disable(struct bfa_s *bfa) ++{ ++ return (BFA_STATUS_OK); ++} ++ ++bfa_boolean_t ++bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ *bitmap = port->cfg.trunk_ports; ++ return port->cfg.trunked; ++} ++ ++bfa_boolean_t ++bfa_pport_is_disabled(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *port = BFA_PORT_MOD(bfa); ++ ++ return (bfa_sm_to_state(hal_pport_sm_table, port->sm) == ++ BFA_PPORT_ST_DISABLED); ++ ++} ++ ++bfa_boolean_t ++bfa_pport_is_ratelim(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE); ++ ++} ++ ++void ++bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, on_off); ++ bfa_trc(bfa, pport->cfg.qos_enabled); ++ ++ pport->cfg.qos_enabled = on_off; ++} ++ ++void ++bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, on_off); ++ bfa_trc(bfa, pport->cfg.ratelimit); ++ ++ pport->cfg.ratelimit = on_off; ++ if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN) ++ pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS; ++} ++ ++/** ++ * Configure default minimum ratelim speed ++ */ ++bfa_status_t ++bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, speed); ++ ++ /* ++ * Auto and speeds greater than the supported speed, are invalid ++ */ ++ if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) { ++ bfa_trc(bfa, pport->speed_sup); ++ return BFA_STATUS_UNSUPP_SPEED; ++ } ++ ++ pport->cfg.trl_def_speed = speed; ++ ++ return (BFA_STATUS_OK); ++} ++ ++/** ++ * Get default minimum ratelim speed ++ */ ++enum bfa_pport_speed ++bfa_pport_get_ratelim_speed(struct bfa_s *bfa) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, pport->cfg.trl_def_speed); ++ return (pport->cfg.trl_def_speed); ++ ++} ++ ++void ++bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, status); ++ bfa_trc(bfa, pport->diag_busy); ++ ++ pport->diag_busy = status; ++} ++ ++void ++bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, ++ bfa_boolean_t link_e2e_beacon) ++{ ++ struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); ++ ++ bfa_trc(bfa, beacon); ++ bfa_trc(bfa, link_e2e_beacon); ++ bfa_trc(bfa, pport->beacon); ++ bfa_trc(bfa, pport->link_e2e_beacon); ++ ++ pport->beacon = beacon; ++ pport->link_e2e_beacon = link_e2e_beacon; ++} ++ ++bfa_boolean_t ++bfa_pport_is_linkup(struct bfa_s *bfa) ++{ ++ return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c +new file mode 100644 +index 0000000..7cb39a3 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcs.c +@@ -0,0 +1,182 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs.c BFA FCS main ++ */ ++ ++#include ++#include "fcs_port.h" ++#include "fcs_uf.h" ++#include "fcs_vport.h" ++#include "fcs_rport.h" ++#include "fcs_fabric.h" ++#include "fcs_fcpim.h" ++#include "fcs_fcptm.h" ++#include "fcbuild.h" ++#include "fcs.h" ++#include "bfad_drv.h" ++#include ++ ++/** ++ * FCS sub-modules ++ */ ++struct bfa_fcs_mod_s { ++ void (*modinit) (struct bfa_fcs_s *fcs); ++ void (*modexit) (struct bfa_fcs_s *fcs); ++}; ++ ++#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit } ++ ++static struct bfa_fcs_mod_s fcs_modules[] = { ++ BFA_FCS_MODULE(bfa_fcs_pport), ++ BFA_FCS_MODULE(bfa_fcs_uf), ++ BFA_FCS_MODULE(bfa_fcs_fabric), ++ BFA_FCS_MODULE(bfa_fcs_vport), ++ BFA_FCS_MODULE(bfa_fcs_rport), ++ BFA_FCS_MODULE(bfa_fcs_fcpim), ++}; ++ ++/** ++ * fcs_api BFA FCS API ++ */ ++ ++static void ++bfa_fcs_exit_comp(void *fcs_cbarg) ++{ ++ struct bfa_fcs_s *fcs = fcs_cbarg; ++ struct bfad_s *bfad = fcs->bfad; ++ ++ complete(&bfad->comp); ++} ++ ++ ++ ++/** ++ * fcs_api BFA FCS API ++ */ ++ ++/** ++ * FCS instance initialization. ++ * ++ * param[in] fcs FCS instance ++ * param[in] bfa BFA instance ++ * param[in] bfad BFA driver instance ++ * ++ * return None ++ */ ++void ++bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, ++ bfa_boolean_t min_cfg) ++{ ++ int i; ++ struct bfa_fcs_mod_s *mod; ++ ++ fcs->bfa = bfa; ++ fcs->bfad = bfad; ++ fcs->min_cfg = min_cfg; ++ ++ bfa_attach_fcs(bfa); ++ fcbuild_init(); ++ ++ for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) { ++ mod = &fcs_modules[i]; ++ mod->modinit(fcs); ++ } ++} ++ ++/** ++ * Start FCS operations. ++ */ ++void ++bfa_fcs_start(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_fabric_modstart(fcs); ++} ++ ++/** ++ * FCS driver details initialization. ++ * ++ * param[in] fcs FCS instance ++ * param[in] driver_info Driver Details ++ * ++ * return None ++ */ ++void ++bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, ++ struct bfa_fcs_driver_info_s *driver_info) ++{ ++ ++ fcs->driver_info = *driver_info; ++ ++ bfa_fcs_fabric_psymb_init(&fcs->fabric); ++} ++ ++/** ++ * FCS instance cleanup and exit. ++ * ++ * param[in] fcs FCS instance ++ * return None ++ */ ++void ++bfa_fcs_exit(struct bfa_fcs_s *fcs) ++{ ++ struct bfa_fcs_mod_s *mod; ++ int nmods, i; ++ ++ bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs); ++ ++ nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]); ++ ++ for (i = 0; i < nmods; i++) { ++ bfa_wc_up(&fcs->wc); ++ ++ mod = &fcs_modules[i]; ++ mod->modexit(fcs); ++ } ++ ++ bfa_wc_wait(&fcs->wc); ++} ++ ++ ++void ++bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod) ++{ ++ fcs->trcmod = trcmod; ++} ++ ++ ++void ++bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod) ++{ ++ fcs->logm = logmod; ++} ++ ++ ++void ++bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen) ++{ ++ fcs->aen = aen; ++} ++ ++void ++bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs) ++{ ++ bfa_wc_down(&fcs->wc); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c +new file mode 100644 +index 0000000..8975ed0 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcs_lport.c +@@ -0,0 +1,940 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_port.c BFA FCS port ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fcs.h" ++#include "fcs_lport.h" ++#include "fcs_vport.h" ++#include "fcs_rport.h" ++#include "fcs_fcxp.h" ++#include "fcs_trcmod.h" ++#include "lport_priv.h" ++#include ++ ++BFA_TRC_FILE(FCS, PORT); ++ ++/** ++ * Forward declarations ++ */ ++ ++static void bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port, ++ enum bfa_lport_aen_event event); ++static void bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs, u8 reason_code, ++ u8 reason_code_expl); ++static void bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs, ++ struct fc_logi_s *plogi); ++static void bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_deleted(struct bfa_fcs_port_s *port); ++static void bfa_fcs_port_echo(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs, ++ struct fc_echo_s *echo, u16 len); ++static void bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs, ++ struct fc_rnid_cmd_s *rnid, u16 len); ++static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port, ++ struct fc_rnid_general_topology_data_s *gen_topo_data); ++ ++static struct { ++ void (*init) (struct bfa_fcs_port_s *port); ++ void (*online) (struct bfa_fcs_port_s *port); ++ void (*offline) (struct bfa_fcs_port_s *port); ++} __port_action[] = { ++ { ++ bfa_fcs_port_unknown_init, bfa_fcs_port_unknown_online, ++ bfa_fcs_port_unknown_offline}, { ++ bfa_fcs_port_fab_init, bfa_fcs_port_fab_online, ++ bfa_fcs_port_fab_offline}, { ++ bfa_fcs_port_loop_init, bfa_fcs_port_loop_online, ++ bfa_fcs_port_loop_offline}, { ++bfa_fcs_port_n2n_init, bfa_fcs_port_n2n_online, ++ bfa_fcs_port_n2n_offline},}; ++ ++/** ++ * fcs_port_sm FCS logical port state machine ++ */ ++ ++enum bfa_fcs_port_event { ++ BFA_FCS_PORT_SM_CREATE = 1, ++ BFA_FCS_PORT_SM_ONLINE = 2, ++ BFA_FCS_PORT_SM_OFFLINE = 3, ++ BFA_FCS_PORT_SM_DELETE = 4, ++ BFA_FCS_PORT_SM_DELRPORT = 5, ++}; ++ ++static void bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event); ++static void bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event); ++static void bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event); ++static void bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event); ++static void bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event); ++ ++static void ++bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event) ++{ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_PORT_SM_CREATE: ++ bfa_sm_set_state(port, bfa_fcs_port_sm_init); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event) ++{ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_PORT_SM_ONLINE: ++ bfa_sm_set_state(port, bfa_fcs_port_sm_online); ++ bfa_fcs_port_online_actions(port); ++ break; ++ ++ case BFA_FCS_PORT_SM_DELETE: ++ bfa_sm_set_state(port, bfa_fcs_port_sm_uninit); ++ bfa_fcs_port_deleted(port); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe, *qen; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_PORT_SM_OFFLINE: ++ bfa_sm_set_state(port, bfa_fcs_port_sm_offline); ++ bfa_fcs_port_offline_actions(port); ++ break; ++ ++ case BFA_FCS_PORT_SM_DELETE: ++ ++ __port_action[port->fabric->fab_type].offline(port); ++ ++ if (port->num_rports == 0) { ++ bfa_sm_set_state(port, bfa_fcs_port_sm_uninit); ++ bfa_fcs_port_deleted(port); ++ } else { ++ bfa_sm_set_state(port, bfa_fcs_port_sm_deleting); ++ list_for_each_safe(qe, qen, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ bfa_fcs_rport_delete(rport); ++ } ++ } ++ break; ++ ++ case BFA_FCS_PORT_SM_DELRPORT: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe, *qen; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_PORT_SM_ONLINE: ++ bfa_sm_set_state(port, bfa_fcs_port_sm_online); ++ bfa_fcs_port_online_actions(port); ++ break; ++ ++ case BFA_FCS_PORT_SM_DELETE: ++ if (port->num_rports == 0) { ++ bfa_sm_set_state(port, bfa_fcs_port_sm_uninit); ++ bfa_fcs_port_deleted(port); ++ } else { ++ bfa_sm_set_state(port, bfa_fcs_port_sm_deleting); ++ list_for_each_safe(qe, qen, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ bfa_fcs_rport_delete(rport); ++ } ++ } ++ break; ++ ++ case BFA_FCS_PORT_SM_DELRPORT: ++ case BFA_FCS_PORT_SM_OFFLINE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port, ++ enum bfa_fcs_port_event event) ++{ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_PORT_SM_DELRPORT: ++ if (port->num_rports == 0) { ++ bfa_sm_set_state(port, bfa_fcs_port_sm_uninit); ++ bfa_fcs_port_deleted(port); ++ } ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * fcs_port_pvt ++ */ ++ ++/** ++ * Send AEN notification ++ */ ++static void ++bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port, ++ enum bfa_lport_aen_event event) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = port->fcs->logm; ++ enum bfa_port_role role = port->port_cfg.roles; ++ wwn_t lpwwn = bfa_fcs_port_get_pwwn(port); ++ char lpwwn_ptr[BFA_STRING_32]; ++ char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] = ++ { "Initiator", "Target", "IPFC" }; ++ ++ wwn2str(lpwwn_ptr, lpwwn); ++ ++ bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); ++ ++ switch (event) { ++ case BFA_LPORT_AEN_ONLINE: ++ bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_OFFLINE: ++ bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_NEW: ++ bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_DELETE: ++ bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_DISCONNECT: ++ bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ default: ++ break; ++ } ++ ++ aen_data.lport.vf_id = port->fabric->vf_id; ++ aen_data.lport.roles = role; ++ aen_data.lport.ppwwn = ++ bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs)); ++ aen_data.lport.lpwwn = lpwwn; ++} ++ ++/* ++ * Send a LS reject ++ */ ++static void ++bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs, ++ u8 reason_code, u8 reason_code_expl) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_rport_s *bfa_rport = NULL; ++ int len; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id, ++ reason_code, reason_code_expl); ++ ++ bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, ++ FC_MAX_PDUSZ, 0); ++} ++ ++/** ++ * Process incoming plogi from a remote port. ++ */ ++static void ++bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs, ++ struct fc_logi_s *plogi) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ ++ /* ++ * If min cfg mode is enabled, drop any incoming PLOGIs ++ */ ++ if (__fcs_min_cfg(port->fcs)) { ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ return; ++ } ++ ++ if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) { ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ /* ++ * send a LS reject ++ */ ++ bfa_fcs_port_send_ls_rjt(port, rx_fchs, ++ FC_LS_RJT_RSN_PROTOCOL_ERROR, ++ FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS); ++ return; ++ } ++ ++ /** ++* Direct Attach P2P mode : verify address assigned by the r-port. ++ */ ++ if ((!bfa_fcs_fabric_is_switched(port->fabric)) ++ && ++ (memcmp ++ ((void *)&bfa_fcs_port_get_pwwn(port), (void *)&plogi->port_name, ++ sizeof(wwn_t)) < 0)) { ++ if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) { ++ /* ++ * Address assigned to us cannot be a WKA ++ */ ++ bfa_fcs_port_send_ls_rjt(port, rx_fchs, ++ FC_LS_RJT_RSN_PROTOCOL_ERROR, ++ FC_LS_RJT_EXP_INVALID_NPORT_ID); ++ return; ++ } ++ port->pid = rx_fchs->d_id; ++ } ++ ++ /** ++ * First, check if we know the device by pwwn. ++ */ ++ rport = bfa_fcs_port_get_rport_by_pwwn(port, plogi->port_name); ++ if (rport) { ++ /** ++ * Direct Attach P2P mode: handle address assigned by the rport. ++ */ ++ if ((!bfa_fcs_fabric_is_switched(port->fabric)) ++ && ++ (memcmp ++ ((void *)&bfa_fcs_port_get_pwwn(port), ++ (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) { ++ port->pid = rx_fchs->d_id; ++ rport->pid = rx_fchs->s_id; ++ } ++ bfa_fcs_rport_plogi(rport, rx_fchs, plogi); ++ return; ++ } ++ ++ /** ++ * Next, lookup rport by PID. ++ */ ++ rport = bfa_fcs_port_get_rport_by_pid(port, rx_fchs->s_id); ++ if (!rport) { ++ /** ++ * Inbound PLOGI from a new device. ++ */ ++ bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); ++ return; ++ } ++ ++ /** ++ * Rport is known only by PID. ++ */ ++ if (rport->pwwn) { ++ /** ++ * This is a different device with the same pid. Old device ++ * disappeared. Send implicit LOGO to old device. ++ */ ++ bfa_assert(rport->pwwn != plogi->port_name); ++ bfa_fcs_rport_logo_imp(rport); ++ ++ /** ++ * Inbound PLOGI from a new device (with old PID). ++ */ ++ bfa_fcs_rport_plogi_create(port, rx_fchs, plogi); ++ return; ++ } ++ ++ /** ++ * PLOGI crossing each other. ++ */ ++ bfa_assert(rport->pwwn == WWN_NULL); ++ bfa_fcs_rport_plogi(rport, rx_fchs, plogi); ++} ++ ++/* ++ * Process incoming ECHO. ++ * Since it does not require a login, it is processed here. ++ */ ++static void ++bfa_fcs_port_echo(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs, ++ struct fc_echo_s *echo, u16 rx_len) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_rport_s *bfa_rport = NULL; ++ int len, pyld_len; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ bfa_trc(port->fcs, rx_len); ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id); ++ ++ /* ++ * Copy the payload (if any) from the echo frame ++ */ ++ pyld_len = rx_len - sizeof(struct fchs_s); ++ bfa_trc(port->fcs, pyld_len); ++ ++ if (pyld_len > len) ++ memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) + ++ sizeof(struct fc_echo_s), (echo + 1), ++ (pyld_len - sizeof(struct fc_echo_s))); ++ ++ bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL, ++ FC_MAX_PDUSZ, 0); ++} ++ ++/* ++ * Process incoming RNID. ++ * Since it does not require a login, it is processed here. ++ */ ++static void ++bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs, ++ struct fc_rnid_cmd_s *rnid, u16 rx_len) ++{ ++ struct fc_rnid_common_id_data_s common_id_data; ++ struct fc_rnid_general_topology_data_s gen_topo_data; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_rport_s *bfa_rport = NULL; ++ u16 len; ++ u32 data_format; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ bfa_trc(port->fcs, rx_len); ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ /* ++ * Check Node Indentification Data Format ++ * We only support General Topology Discovery Format. ++ * For any other requested Data Formats, we return Common Node Id Data ++ * only, as per FC-LS. ++ */ ++ bfa_trc(port->fcs, rnid->node_id_data_format); ++ if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { ++ data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY; ++ /* ++ * Get General topology data for this port ++ */ ++ bfa_fs_port_get_gen_topo_data(port, &gen_topo_data); ++ } else { ++ data_format = RNID_NODEID_DATA_FORMAT_COMMON; ++ } ++ ++ /* ++ * Copy the Node Id Info ++ */ ++ common_id_data.port_name = bfa_fcs_port_get_pwwn(port); ++ common_id_data.node_name = bfa_fcs_port_get_nwwn(port); ++ ++ len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id, ++ data_format, &common_id_data, &gen_topo_data); ++ ++ bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, ++ FC_MAX_PDUSZ, 0); ++ ++ return; ++} ++ ++/* ++ * Fill out General Topolpgy Discovery Data for RNID ELS. ++ */ ++static void ++bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port, ++ struct fc_rnid_general_topology_data_s *gen_topo_data) ++{ ++ ++ bfa_os_memset(gen_topo_data, 0, ++ sizeof(struct fc_rnid_general_topology_data_s)); ++ ++ gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST); ++ gen_topo_data->phy_port_num = 0; /* @todo */ ++ gen_topo_data->num_attached_nodes = bfa_os_htonl(1); ++} ++ ++static void ++bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port) ++{ ++ bfa_trc(port->fcs, port->fabric->oper_type); ++ ++ __port_action[port->fabric->fab_type].init(port); ++ __port_action[port->fabric->fab_type].online(port); ++ ++ bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_ONLINE); ++ bfa_fcb_port_online(port->fcs->bfad, port->port_cfg.roles, ++ port->fabric->vf_drv, (port->vport == NULL) ? ++ NULL : port->vport->vport_drv); ++} ++ ++static void ++bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port) ++{ ++ struct list_head *qe, *qen; ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, port->fabric->oper_type); ++ ++ __port_action[port->fabric->fab_type].offline(port); ++ ++ if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) { ++ bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT); ++ } else { ++ bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE); ++ } ++ bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles, ++ port->fabric->vf_drv, ++ (port->vport == NULL) ? NULL : port->vport->vport_drv); ++ ++ list_for_each_safe(qe, qen, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ bfa_fcs_rport_offline(rport); ++ } ++} ++ ++static void ++bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port) ++{ ++ bfa_assert(0); ++} ++ ++static void ++bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port) ++{ ++ bfa_assert(0); ++} ++ ++static void ++bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port) ++{ ++ bfa_assert(0); ++} ++ ++static void ++bfa_fcs_port_deleted(struct bfa_fcs_port_s *port) ++{ ++ bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DELETE); ++ ++ /* ++ * Base port will be deleted by the OS driver ++ */ ++ if (port->vport) { ++ bfa_fcb_port_delete(port->fcs->bfad, port->port_cfg.roles, ++ port->fabric->vf_drv, ++ port->vport ? port->vport->vport_drv : NULL); ++ bfa_fcs_vport_delete_comp(port->vport); ++ } else { ++ bfa_fcs_fabric_port_delete_comp(port->fabric); ++ } ++} ++ ++ ++ ++/** ++ * fcs_lport_api BFA FCS port API ++ */ ++/** ++ * Module initialization ++ */ ++void ++bfa_fcs_port_modinit(struct bfa_fcs_s *fcs) ++{ ++ ++} ++ ++/** ++ * Module cleanup ++ */ ++void ++bfa_fcs_port_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} ++ ++/** ++ * Unsolicited frame receive handling. ++ */ ++void ++bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs, ++ u16 len) ++{ ++ u32 pid = fchs->s_id; ++ struct bfa_fcs_rport_s *rport = NULL; ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ bfa_stats(lport, uf_recvs); ++ ++ if (!bfa_fcs_port_is_online(lport)) { ++ bfa_stats(lport, uf_recv_drops); ++ return; ++ } ++ ++ /** ++ * First, handle ELSs that donot require a login. ++ */ ++ /* ++ * Handle PLOGI first ++ */ ++ if ((fchs->type == FC_TYPE_ELS) && ++ (els_cmd->els_code == FC_ELS_PLOGI)) { ++ bfa_fcs_port_plogi(lport, fchs, (struct fc_logi_s *) els_cmd); ++ return; ++ } ++ ++ /* ++ * Handle ECHO separately. ++ */ ++ if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) { ++ bfa_fcs_port_echo(lport, fchs, ++ (struct fc_echo_s *) els_cmd, len); ++ return; ++ } ++ ++ /* ++ * Handle RNID separately. ++ */ ++ if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) { ++ bfa_fcs_port_rnid(lport, fchs, ++ (struct fc_rnid_cmd_s *) els_cmd, len); ++ return; ++ } ++ ++ /** ++ * look for a matching remote port ID ++ */ ++ rport = bfa_fcs_port_get_rport_by_pid(lport, pid); ++ if (rport) { ++ bfa_trc(rport->fcs, fchs->s_id); ++ bfa_trc(rport->fcs, fchs->d_id); ++ bfa_trc(rport->fcs, fchs->type); ++ ++ bfa_fcs_rport_uf_recv(rport, fchs, len); ++ return; ++ } ++ ++ /** ++ * Only handles ELS frames for now. ++ */ ++ if (fchs->type != FC_TYPE_ELS) { ++ bfa_trc(lport->fcs, fchs->type); ++ bfa_assert(0); ++ return; ++ } ++ ++ bfa_trc(lport->fcs, els_cmd->els_code); ++ if (els_cmd->els_code == FC_ELS_RSCN) { ++ bfa_fcs_port_scn_process_rscn(lport, fchs, len); ++ return; ++ } ++ ++ if (els_cmd->els_code == FC_ELS_LOGO) { ++ /** ++ * @todo Handle LOGO frames received. ++ */ ++ bfa_trc(lport->fcs, els_cmd->els_code); ++ return; ++ } ++ ++ if (els_cmd->els_code == FC_ELS_PRLI) { ++ /** ++ * @todo Handle PRLI frames received. ++ */ ++ bfa_trc(lport->fcs, els_cmd->els_code); ++ return; ++ } ++ ++ /** ++ * Unhandled ELS frames. Send a LS_RJT. ++ */ ++ bfa_fcs_port_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP, ++ FC_LS_RJT_EXP_NO_ADDL_INFO); ++ ++} ++ ++/** ++ * PID based Lookup for a R-Port in the Port R-Port Queue ++ */ ++struct bfa_fcs_rport_s * ++bfa_fcs_port_get_rport_by_pid(struct bfa_fcs_port_s *port, u32 pid) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe; ++ ++ list_for_each(qe, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if (rport->pid == pid) ++ return rport; ++ } ++ ++ bfa_trc(port->fcs, pid); ++ return NULL; ++} ++ ++/** ++ * PWWN based Lookup for a R-Port in the Port R-Port Queue ++ */ ++struct bfa_fcs_rport_s * ++bfa_fcs_port_get_rport_by_pwwn(struct bfa_fcs_port_s *port, wwn_t pwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe; ++ ++ list_for_each(qe, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if (wwn_is_equal(rport->pwwn, pwwn)) ++ return rport; ++ } ++ ++ bfa_trc(port->fcs, pwwn); ++ return (NULL); ++} ++ ++/** ++ * NWWN based Lookup for a R-Port in the Port R-Port Queue ++ */ ++struct bfa_fcs_rport_s * ++bfa_fcs_port_get_rport_by_nwwn(struct bfa_fcs_port_s *port, wwn_t nwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe; ++ ++ list_for_each(qe, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if (wwn_is_equal(rport->nwwn, nwwn)) ++ return rport; ++ } ++ ++ bfa_trc(port->fcs, nwwn); ++ return (NULL); ++} ++ ++/** ++ * Called by rport module when new rports are discovered. ++ */ ++void ++bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port, ++ struct bfa_fcs_rport_s *rport) ++{ ++ list_add_tail(&rport->qe, &port->rport_q); ++ port->num_rports++; ++} ++ ++/** ++ * Called by rport module to when rports are deleted. ++ */ ++void ++bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port, ++ struct bfa_fcs_rport_s *rport) ++{ ++ bfa_assert(bfa_q_is_on_q(&port->rport_q, rport)); ++ list_del(&rport->qe); ++ port->num_rports--; ++ ++ bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT); ++} ++ ++/** ++ * Called by fabric for base port when fabric login is complete. ++ * Called by vport for virtual ports when FDISC is complete. ++ */ ++void ++bfa_fcs_port_online(struct bfa_fcs_port_s *port) ++{ ++ bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE); ++} ++ ++/** ++ * Called by fabric for base port when fabric goes offline. ++ * Called by vport for virtual ports when virtual port becomes offline. ++ */ ++void ++bfa_fcs_port_offline(struct bfa_fcs_port_s *port) ++{ ++ bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE); ++} ++ ++/** ++ * Called by fabric to delete base lport and associated resources. ++ * ++ * Called by vport to delete lport and associated resources. Should call ++ * bfa_fcs_vport_delete_comp() for vports on completion. ++ */ ++void ++bfa_fcs_port_delete(struct bfa_fcs_port_s *port) ++{ ++ bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE); ++} ++ ++/** ++ * Called by fabric in private loop topology to process LIP event. ++ */ ++void ++bfa_fcs_port_lip(struct bfa_fcs_port_s *port) ++{ ++} ++ ++/** ++ * Return TRUE if port is online, else return FALSE ++ */ ++bfa_boolean_t ++bfa_fcs_port_is_online(struct bfa_fcs_port_s *port) ++{ ++ return (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online)); ++} ++ ++/** ++ * Logical port initialization of base or virtual port. ++ * Called by fabric for base port or by vport for virtual ports. ++ */ ++void ++bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, ++ u16 vf_id, struct bfa_port_cfg_s *port_cfg, ++ struct bfa_fcs_vport_s *vport) ++{ ++ lport->fcs = fcs; ++ lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id); ++ bfa_os_assign(lport->port_cfg, *port_cfg); ++ lport->vport = vport; ++ lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) : ++ bfa_lps_get_tag(lport->fabric->lps); ++ ++ INIT_LIST_HEAD(&lport->rport_q); ++ lport->num_rports = 0; ++ ++ lport->bfad_port = ++ bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles, ++ lport->fabric->vf_drv, ++ vport ? vport->vport_drv : NULL); ++ bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW); ++ ++ bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit); ++ bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE); ++} ++ ++ ++ ++/** ++ * fcs_lport_api ++ */ ++ ++void ++bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, ++ struct bfa_port_attr_s *port_attr) ++{ ++ if (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online)) ++ port_attr->pid = port->pid; ++ else ++ port_attr->pid = 0; ++ ++ port_attr->port_cfg = port->port_cfg; ++ ++ if (port->fabric) { ++ port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric); ++ port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric); ++ port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port); ++ memcpy(port_attr->fabric_ip_addr, ++ bfa_fcs_port_get_fabric_ipaddr(port), ++ BFA_FCS_FABRIC_IPADDR_SZ); ++ ++ if (port->vport != NULL) ++ port_attr->port_type = BFA_PPORT_TYPE_VPORT; ++ ++ } else { ++ port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN; ++ port_attr->state = BFA_PORT_UNINIT; ++ } ++ ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c +new file mode 100644 +index 0000000..9c4b24e +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcs_port.c +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_pport.c BFA FCS PPORT ( physical port) ++ */ ++ ++#include ++#include ++#include ++#include "fcs_trcmod.h" ++#include "fcs.h" ++#include "fcs_fabric.h" ++#include "fcs_port.h" ++ ++BFA_TRC_FILE(FCS, PPORT); ++ ++static void ++bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event) ++{ ++ struct bfa_fcs_s *fcs = cbarg; ++ ++ bfa_trc(fcs, event); ++ ++ switch (event) { ++ case BFA_PPORT_LINKUP: ++ bfa_fcs_fabric_link_up(&fcs->fabric); ++ break; ++ ++ case BFA_PPORT_LINKDOWN: ++ bfa_fcs_fabric_link_down(&fcs->fabric); ++ break; ++ ++ case BFA_PPORT_TRUNK_LINKDOWN: ++ bfa_assert(0); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++void ++bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs) ++{ ++ bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler, ++ fcs); ++} ++ ++void ++bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} +diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c +new file mode 100644 +index 0000000..ad01db6 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcs_uf.c +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_uf.c BFA FCS UF ( Unsolicited Frames) ++ */ ++ ++#include ++#include ++#include ++#include "fcs.h" ++#include "fcs_trcmod.h" ++#include "fcs_fabric.h" ++#include "fcs_uf.h" ++ ++BFA_TRC_FILE(FCS, UF); ++ ++/** ++ * BFA callback for unsolicited frame receive handler. ++ * ++ * @param[in] cbarg callback arg for receive handler ++ * @param[in] uf unsolicited frame descriptor ++ * ++ * @return None ++ */ ++static void ++bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf) ++{ ++ struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg; ++ struct fchs_s *fchs = bfa_uf_get_frmbuf(uf); ++ u16 len = bfa_uf_get_frmlen(uf); ++ struct fc_vft_s *vft; ++ struct bfa_fcs_fabric_s *fabric; ++ ++ /** ++ * check for VFT header ++ */ ++ if (fchs->routing == FC_RTG_EXT_HDR && ++ fchs->cat_info == FC_CAT_VFT_HDR) { ++ bfa_stats(fcs, uf.tagged); ++ vft = bfa_uf_get_frmbuf(uf); ++ if (fcs->port_vfid == vft->vf_id) ++ fabric = &fcs->fabric; ++ else ++ fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id); ++ ++ /** ++ * drop frame if vfid is unknown ++ */ ++ if (!fabric) { ++ bfa_assert(0); ++ bfa_stats(fcs, uf.vfid_unknown); ++ bfa_uf_free(uf); ++ return; ++ } ++ ++ /** ++ * skip vft header ++ */ ++ fchs = (struct fchs_s *) (vft + 1); ++ len -= sizeof(struct fc_vft_s); ++ ++ bfa_trc(fcs, vft->vf_id); ++ } else { ++ bfa_stats(fcs, uf.untagged); ++ fabric = &fcs->fabric; ++ } ++ ++ bfa_trc(fcs, ((u32 *) fchs)[0]); ++ bfa_trc(fcs, ((u32 *) fchs)[1]); ++ bfa_trc(fcs, ((u32 *) fchs)[2]); ++ bfa_trc(fcs, ((u32 *) fchs)[3]); ++ bfa_trc(fcs, ((u32 *) fchs)[4]); ++ bfa_trc(fcs, ((u32 *) fchs)[5]); ++ bfa_trc(fcs, len); ++ ++ bfa_fcs_fabric_uf_recv(fabric, fchs, len); ++ bfa_uf_free(uf); ++} ++ ++void ++bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs) ++{ ++ bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs); ++} ++ ++void ++bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} +diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c +new file mode 100644 +index 0000000..4754a0e +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcxp.c +@@ -0,0 +1,782 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, FCXP); ++BFA_MODULE(fcxp); ++ ++/** ++ * forward declarations ++ */ ++static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete); ++static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, ++ struct bfi_fcxp_send_rsp_s *fcxp_rsp); ++static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, ++ struct bfa_fcxp_s *fcxp, struct fchs_s *fchs); ++static void bfa_fcxp_qresume(void *cbarg); ++static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, ++ struct bfi_fcxp_send_req_s *send_req); ++ ++/** ++ * fcxp_pvt BFA FCXP private functions ++ */ ++ ++static void ++claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi) ++{ ++ u8 *dm_kva = NULL; ++ u64 dm_pa; ++ u32 buf_pool_sz; ++ ++ dm_kva = bfa_meminfo_dma_virt(mi); ++ dm_pa = bfa_meminfo_dma_phys(mi); ++ ++ buf_pool_sz = mod->req_pld_sz * mod->num_fcxps; ++ ++ /* ++ * Initialize the fcxp req payload list ++ */ ++ mod->req_pld_list_kva = dm_kva; ++ mod->req_pld_list_pa = dm_pa; ++ dm_kva += buf_pool_sz; ++ dm_pa += buf_pool_sz; ++ bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz); ++ ++ /* ++ * Initialize the fcxp rsp payload list ++ */ ++ buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps; ++ mod->rsp_pld_list_kva = dm_kva; ++ mod->rsp_pld_list_pa = dm_pa; ++ dm_kva += buf_pool_sz; ++ dm_pa += buf_pool_sz; ++ bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz); ++ ++ bfa_meminfo_dma_virt(mi) = dm_kva; ++ bfa_meminfo_dma_phys(mi) = dm_pa; ++} ++ ++static void ++claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi) ++{ ++ u16 i; ++ struct bfa_fcxp_s *fcxp; ++ ++ fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi); ++ bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps); ++ ++ INIT_LIST_HEAD(&mod->fcxp_free_q); ++ INIT_LIST_HEAD(&mod->fcxp_active_q); ++ ++ mod->fcxp_list = fcxp; ++ ++ for (i = 0; i < mod->num_fcxps; i++) { ++ fcxp->fcxp_mod = mod; ++ fcxp->fcxp_tag = i; ++ ++ list_add_tail(&fcxp->qe, &mod->fcxp_free_q); ++ bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp); ++ fcxp->reqq_waiting = BFA_FALSE; ++ ++ fcxp = fcxp + 1; ++ } ++ ++ bfa_meminfo_kva(mi) = (void *)fcxp; ++} ++ ++static void ++bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, ++ u32 *dm_len) ++{ ++ u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs; ++ ++ if (num_fcxp_reqs == 0) ++ return; ++ ++ /* ++ * Account for req/rsp payload ++ */ ++ *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs; ++ if (cfg->drvcfg.min_cfg) ++ *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs; ++ else ++ *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs; ++ ++ /* ++ * Account for fcxp structs ++ */ ++ *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs; ++} ++ ++static void ++bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ ++ bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s)); ++ mod->bfa = bfa; ++ mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs; ++ ++ /** ++ * Initialize FCXP request and response payload sizes. ++ */ ++ mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ; ++ if (!cfg->drvcfg.min_cfg) ++ mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ; ++ ++ INIT_LIST_HEAD(&mod->wait_q); ++ ++ claim_fcxp_req_rsp_mem(mod, meminfo); ++ claim_fcxps_mem(mod, meminfo); ++} ++ ++static void ++bfa_fcxp_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcxp_detach(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcxp_start(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcxp_stop(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_fcxp_iocdisable(struct bfa_s *bfa) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ struct bfa_fcxp_s *fcxp; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &mod->fcxp_active_q) { ++ fcxp = (struct bfa_fcxp_s *) qe; ++ if (fcxp->caller == NULL) { ++ fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, ++ BFA_STATUS_IOC_FAILURE, 0, 0, NULL); ++ bfa_fcxp_free(fcxp); ++ } else { ++ fcxp->rsp_status = BFA_STATUS_IOC_FAILURE; ++ bfa_cb_queue(bfa, &fcxp->hcb_qe, ++ __bfa_fcxp_send_cbfn, fcxp); ++ } ++ } ++} ++ ++static struct bfa_fcxp_s * ++bfa_fcxp_get(struct bfa_fcxp_mod_s *fm) ++{ ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_q_deq(&fm->fcxp_free_q, &fcxp); ++ ++ if (fcxp) ++ list_add_tail(&fcxp->qe, &fm->fcxp_active_q); ++ ++ return (fcxp); ++} ++ ++static void ++bfa_fcxp_put(struct bfa_fcxp_s *fcxp) ++{ ++ struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; ++ struct bfa_fcxp_wqe_s *wqe; ++ ++ bfa_q_deq(&mod->wait_q, &wqe); ++ if (wqe) { ++ bfa_trc(mod->bfa, fcxp->fcxp_tag); ++ wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp); ++ return; ++ } ++ ++ bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp)); ++ list_del(&fcxp->qe); ++ list_add_tail(&fcxp->qe, &mod->fcxp_free_q); ++} ++ ++static void ++bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ /**discarded fcxp completion */ ++} ++ ++static void ++__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_fcxp_s *fcxp = cbarg; ++ ++ if (complete) { ++ fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, ++ fcxp->rsp_status, fcxp->rsp_len, ++ fcxp->residue_len, &fcxp->rsp_fchs); ++ } else { ++ bfa_fcxp_free(fcxp); ++ } ++} ++ ++static void ++hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ struct bfa_fcxp_s *fcxp; ++ u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag); ++ ++ bfa_trc(bfa, fcxp_tag); ++ ++ fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len); ++ ++ /** ++ * @todo f/w should not set residue to non-0 when everything ++ * is received. ++ */ ++ if (fcxp_rsp->req_status == BFA_STATUS_OK) ++ fcxp_rsp->residue_len = 0; ++ else ++ fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len); ++ ++ fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag); ++ ++ bfa_assert(fcxp->send_cbfn != NULL); ++ ++ hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp); ++ ++ if (fcxp->send_cbfn != NULL) { ++ if (fcxp->caller == NULL) { ++ bfa_trc(mod->bfa, fcxp->fcxp_tag); ++ ++ fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg, ++ fcxp_rsp->req_status, fcxp_rsp->rsp_len, ++ fcxp_rsp->residue_len, &fcxp_rsp->fchs); ++ /* ++ * fcxp automatically freed on return from the callback ++ */ ++ bfa_fcxp_free(fcxp); ++ } else { ++ bfa_trc(mod->bfa, fcxp->fcxp_tag); ++ fcxp->rsp_status = fcxp_rsp->req_status; ++ fcxp->rsp_len = fcxp_rsp->rsp_len; ++ fcxp->residue_len = fcxp_rsp->residue_len; ++ fcxp->rsp_fchs = fcxp_rsp->fchs; ++ ++ bfa_cb_queue(bfa, &fcxp->hcb_qe, ++ __bfa_fcxp_send_cbfn, fcxp); ++ } ++ } else { ++ bfa_trc(bfa, fcxp_tag); ++ } ++} ++ ++static void ++hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa) ++{ ++ union bfi_addr_u sga_zero = { {0} }; ++ ++ sge->sg_len = reqlen; ++ sge->flags = BFI_SGE_DATA_LAST; ++ bfa_dma_addr_set(sge[0].sga, req_pa); ++ bfa_sge_to_be(sge); ++ sge++; ++ ++ sge->sga = sga_zero; ++ sge->sg_len = reqlen; ++ sge->flags = BFI_SGE_PGDLEN; ++ bfa_sge_to_be(sge); ++} ++ ++static void ++hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp, ++ struct fchs_s *fchs) ++{ ++ /* ++ * TODO: TX ox_id ++ */ ++ if (reqlen > 0) { ++ if (fcxp->use_ireqbuf) { ++ u32 pld_w0 = ++ *((u32 *) BFA_FCXP_REQ_PLD(fcxp)); ++ ++ bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, ++ BFA_PL_EID_TX, ++ reqlen + sizeof(struct fchs_s), fchs, pld_w0); ++ } else { ++ bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, ++ BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s), ++ fchs); ++ } ++ } else { ++ bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX, ++ reqlen + sizeof(struct fchs_s), fchs); ++ } ++} ++ ++static void ++hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp, ++ struct bfi_fcxp_send_rsp_s *fcxp_rsp) ++{ ++ if (fcxp_rsp->rsp_len > 0) { ++ if (fcxp->use_irspbuf) { ++ u32 pld_w0 = ++ *((u32 *) BFA_FCXP_RSP_PLD(fcxp)); ++ ++ bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP, ++ BFA_PL_EID_RX, ++ (u16) fcxp_rsp->rsp_len, ++ &fcxp_rsp->fchs, pld_w0); ++ } else { ++ bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, ++ BFA_PL_EID_RX, ++ (u16) fcxp_rsp->rsp_len, ++ &fcxp_rsp->fchs); ++ } ++ } else { ++ bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX, ++ (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs); ++ } ++} ++ ++/** ++ * Handler to resume sending fcxp when space in available in cpe queue. ++ */ ++static void ++bfa_fcxp_qresume(void *cbarg) ++{ ++ struct bfa_fcxp_s *fcxp = cbarg; ++ struct bfa_s *bfa = fcxp->fcxp_mod->bfa; ++ struct bfi_fcxp_send_req_s *send_req; ++ ++ fcxp->reqq_waiting = BFA_FALSE; ++ send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); ++ bfa_fcxp_queue(fcxp, send_req); ++} ++ ++/** ++ * Queue fcxp send request to foimrware. ++ */ ++static void ++bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req) ++{ ++ struct bfa_s *bfa = fcxp->fcxp_mod->bfa; ++ struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; ++ struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; ++ struct bfa_rport_s *rport = reqi->bfa_rport; ++ ++ bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ, ++ bfa_lpuid(bfa)); ++ ++ send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag); ++ if (rport) { ++ send_req->rport_fw_hndl = rport->fw_handle; ++ send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz); ++ if (send_req->max_frmsz == 0) ++ send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ); ++ } else { ++ send_req->rport_fw_hndl = 0; ++ send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ); ++ } ++ ++ send_req->vf_id = bfa_os_htons(reqi->vf_id); ++ send_req->lp_tag = reqi->lp_tag; ++ send_req->class = reqi->class; ++ send_req->rsp_timeout = rspi->rsp_timeout; ++ send_req->cts = reqi->cts; ++ send_req->fchs = reqi->fchs; ++ ++ send_req->req_len = bfa_os_htonl(reqi->req_tot_len); ++ send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen); ++ ++ /* ++ * setup req sgles ++ */ ++ if (fcxp->use_ireqbuf == 1) { ++ hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len, ++ BFA_FCXP_REQ_PLD_PA(fcxp)); ++ } else { ++ if (fcxp->nreq_sgles > 0) { ++ bfa_assert(fcxp->nreq_sgles == 1); ++ hal_fcxp_set_local_sges(send_req->req_sge, ++ reqi->req_tot_len, ++ fcxp->req_sga_cbfn(fcxp->caller, ++ 0)); ++ } else { ++ bfa_assert(reqi->req_tot_len == 0); ++ hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0); ++ } ++ } ++ ++ /* ++ * setup rsp sgles ++ */ ++ if (fcxp->use_irspbuf == 1) { ++ bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ); ++ ++ hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen, ++ BFA_FCXP_RSP_PLD_PA(fcxp)); ++ ++ } else { ++ if (fcxp->nrsp_sgles > 0) { ++ bfa_assert(fcxp->nrsp_sgles == 1); ++ hal_fcxp_set_local_sges(send_req->rsp_sge, ++ rspi->rsp_maxlen, ++ fcxp->rsp_sga_cbfn(fcxp->caller, ++ 0)); ++ } else { ++ bfa_assert(rspi->rsp_maxlen == 0); ++ hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0); ++ } ++ } ++ ++ hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs); ++ ++ bfa_reqq_produce(bfa, BFA_REQQ_FCXP); ++ ++ bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP)); ++ bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP)); ++} ++ ++ ++/** ++ * hal_fcxp_api BFA FCXP API ++ */ ++ ++/** ++ * Allocate an FCXP instance to send a response or to send a request ++ * that has a response. Request/response buffers are allocated by caller. ++ * ++ * @param[in] bfa BFA bfa instance ++ * @param[in] nreq_sgles Number of SG elements required for request ++ * buffer. 0, if fcxp internal buffers are used. ++ * Use bfa_fcxp_get_reqbuf() to get the ++ * internal req buffer. ++ * @param[in] req_sgles SG elements describing request buffer. Will be ++ * copied in by BFA and hence can be freed on ++ * return from this function. ++ * @param[in] get_req_sga function ptr to be called to get a request SG ++ * Address (given the sge index). ++ * @param[in] get_req_sglen function ptr to be called to get a request SG ++ * len (given the sge index). ++ * @param[in] get_rsp_sga function ptr to be called to get a response SG ++ * Address (given the sge index). ++ * @param[in] get_rsp_sglen function ptr to be called to get a response SG ++ * len (given the sge index). ++ * ++ * @return FCXP instance. NULL on failure. ++ */ ++struct bfa_fcxp_s * ++bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles, ++ int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn, ++ bfa_fcxp_get_sglen_t req_sglen_cbfn, ++ bfa_fcxp_get_sgaddr_t rsp_sga_cbfn, ++ bfa_fcxp_get_sglen_t rsp_sglen_cbfn) ++{ ++ struct bfa_fcxp_s *fcxp = NULL; ++ u32 nreq_sgpg, nrsp_sgpg; ++ ++ bfa_assert(bfa != NULL); ++ ++ fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa)); ++ if (fcxp == NULL) ++ return (NULL); ++ ++ bfa_trc(bfa, fcxp->fcxp_tag); ++ ++ fcxp->caller = caller; ++ ++ if (nreq_sgles == 0) { ++ fcxp->use_ireqbuf = 1; ++ } else { ++ bfa_assert(req_sga_cbfn != NULL); ++ bfa_assert(req_sglen_cbfn != NULL); ++ ++ fcxp->use_ireqbuf = 0; ++ fcxp->req_sga_cbfn = req_sga_cbfn; ++ fcxp->req_sglen_cbfn = req_sglen_cbfn; ++ ++ fcxp->nreq_sgles = nreq_sgles; ++ ++ /* ++ * alloc required sgpgs ++ */ ++ if (nreq_sgles > BFI_SGE_INLINE) { ++ nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles); ++ ++ if (bfa_sgpg_malloc ++ (bfa, &fcxp->req_sgpg_q, nreq_sgpg) ++ != BFA_STATUS_OK) { ++ /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe, ++ nreq_sgpg); */ ++ /* ++ * TODO ++ */ ++ } ++ } ++ } ++ ++ if (nrsp_sgles == 0) { ++ fcxp->use_irspbuf = 1; ++ } else { ++ bfa_assert(rsp_sga_cbfn != NULL); ++ bfa_assert(rsp_sglen_cbfn != NULL); ++ ++ fcxp->use_irspbuf = 0; ++ fcxp->rsp_sga_cbfn = rsp_sga_cbfn; ++ fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn; ++ ++ fcxp->nrsp_sgles = nrsp_sgles; ++ /* ++ * alloc required sgpgs ++ */ ++ if (nrsp_sgles > BFI_SGE_INLINE) { ++ nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles); ++ ++ if (bfa_sgpg_malloc ++ (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg) ++ != BFA_STATUS_OK) { ++ /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe, ++ nrsp_sgpg); */ ++ /* ++ * TODO ++ */ ++ } ++ } ++ } ++ ++ return (fcxp); ++} ++ ++/** ++ * Get the internal request buffer pointer ++ * ++ * @param[in] fcxp BFA fcxp pointer ++ * ++ * @return pointer to the internal request buffer ++ */ ++void * ++bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp) ++{ ++ struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; ++ void *reqbuf; ++ ++ bfa_assert(fcxp->use_ireqbuf == 1); ++ reqbuf = ((u8 *)mod->req_pld_list_kva) + ++ fcxp->fcxp_tag * mod->req_pld_sz; ++ return reqbuf; ++} ++ ++u32 ++bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp) ++{ ++ struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; ++ ++ return mod->req_pld_sz; ++} ++ ++/** ++ * Get the internal response buffer pointer ++ * ++ * @param[in] fcxp BFA fcxp pointer ++ * ++ * @return pointer to the internal request buffer ++ */ ++void * ++bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp) ++{ ++ struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; ++ void *rspbuf; ++ ++ bfa_assert(fcxp->use_irspbuf == 1); ++ ++ rspbuf = ((u8 *)mod->rsp_pld_list_kva) + ++ fcxp->fcxp_tag * mod->rsp_pld_sz; ++ return rspbuf; ++} ++ ++/** ++ * Free the BFA FCXP ++ * ++ * @param[in] fcxp BFA fcxp pointer ++ * ++ * @return void ++ */ ++void ++bfa_fcxp_free(struct bfa_fcxp_s *fcxp) ++{ ++ struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod; ++ ++ bfa_assert(fcxp != NULL); ++ bfa_trc(mod->bfa, fcxp->fcxp_tag); ++ bfa_fcxp_put(fcxp); ++} ++ ++/** ++ * Send a FCXP request ++ * ++ * @param[in] fcxp BFA fcxp pointer ++ * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports ++ * @param[in] vf_id virtual Fabric ID ++ * @param[in] lp_tag lport tag ++ * @param[in] cts use Continous sequence ++ * @param[in] cos fc Class of Service ++ * @param[in] reqlen request length, does not include FCHS length ++ * @param[in] fchs fc Header Pointer. The header content will be copied ++ * in by BFA. ++ * ++ * @param[in] cbfn call back function to be called on receiving ++ * the response ++ * @param[in] cbarg arg for cbfn ++ * @param[in] rsp_timeout ++ * response timeout ++ * ++ * @return bfa_status_t ++ */ ++void ++bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport, ++ u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos, ++ u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn, ++ void *cbarg, u32 rsp_maxlen, u8 rsp_timeout) ++{ ++ struct bfa_s *bfa = fcxp->fcxp_mod->bfa; ++ struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info; ++ struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info; ++ struct bfi_fcxp_send_req_s *send_req; ++ ++ bfa_trc(bfa, fcxp->fcxp_tag); ++ ++ /** ++ * setup request/response info ++ */ ++ reqi->bfa_rport = rport; ++ reqi->vf_id = vf_id; ++ reqi->lp_tag = lp_tag; ++ reqi->class = cos; ++ rspi->rsp_timeout = rsp_timeout; ++ reqi->cts = cts; ++ reqi->fchs = *fchs; ++ reqi->req_tot_len = reqlen; ++ rspi->rsp_maxlen = rsp_maxlen; ++ fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp; ++ fcxp->send_cbarg = cbarg; ++ ++ /** ++ * If no room in CPE queue, wait for ++ */ ++ send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP); ++ if (!send_req) { ++ bfa_trc(bfa, fcxp->fcxp_tag); ++ fcxp->reqq_waiting = BFA_TRUE; ++ bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe); ++ return; ++ } ++ ++ bfa_fcxp_queue(fcxp, send_req); ++} ++ ++/** ++ * Abort a BFA FCXP ++ * ++ * @param[in] fcxp BFA fcxp pointer ++ * ++ * @return void ++ */ ++bfa_status_t ++bfa_fcxp_abort(struct bfa_fcxp_s *fcxp) ++{ ++ bfa_assert(0); ++ return (BFA_STATUS_OK); ++} ++ ++void ++bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, ++ bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ ++ bfa_assert(list_empty(&mod->fcxp_free_q)); ++ ++ wqe->alloc_cbfn = alloc_cbfn; ++ wqe->alloc_cbarg = alloc_cbarg; ++ list_add_tail(&wqe->qe, &mod->wait_q); ++} ++ ++void ++bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ ++ bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe)); ++ list_del(&wqe->qe); ++} ++ ++void ++bfa_fcxp_discard(struct bfa_fcxp_s *fcxp) ++{ ++ /** ++ * If waiting for room in request queue, cancel reqq wait ++ * and free fcxp. ++ */ ++ if (fcxp->reqq_waiting) { ++ fcxp->reqq_waiting = BFA_FALSE; ++ bfa_reqq_wcancel(&fcxp->reqq_wqe); ++ bfa_fcxp_free(fcxp); ++ return; ++ } ++ ++ fcxp->send_cbfn = bfa_fcxp_null_comp; ++} ++ ++ ++ ++/** ++ * hal_fcxp_public BFA FCXP public functions ++ */ ++ ++void ++bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) ++{ ++ switch (msg->mhdr.msg_id) { ++ case BFI_FCXP_I2H_SEND_RSP: ++ hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg); ++ break; ++ ++ default: ++ bfa_trc(bfa, msg->mhdr.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++u32 ++bfa_fcxp_get_maxrsp(struct bfa_s *bfa) ++{ ++ struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa); ++ ++ return mod->rsp_pld_sz; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_fcxp_priv.h b/drivers/scsi/bfa/bfa_fcxp_priv.h +new file mode 100644 +index 0000000..4cda493 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fcxp_priv.h +@@ -0,0 +1,138 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCXP_PRIV_H__ ++#define __BFA_FCXP_PRIV_H__ ++ ++#include ++#include ++#include ++#include ++ ++#define BFA_FCXP_MIN (1) ++#define BFA_FCXP_MAX_IBUF_SZ (2 * 1024 + 256) ++#define BFA_FCXP_MAX_LBUF_SZ (4 * 1024 + 256) ++ ++struct bfa_fcxp_mod_s { ++ struct bfa_s *bfa; /* backpointer to BFA */ ++ struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */ ++ u16 num_fcxps; /* max num FCXP requests */ ++ struct list_head fcxp_free_q; /* free FCXPs */ ++ struct list_head fcxp_active_q; /* active FCXPs */ ++ void *req_pld_list_kva; /* list of FCXP req pld */ ++ u64 req_pld_list_pa; /* list of FCXP req pld */ ++ void *rsp_pld_list_kva; /* list of FCXP resp pld */ ++ u64 rsp_pld_list_pa; /* list of FCXP resp pld */ ++ struct list_head wait_q; /* wait queue for free fcxp */ ++ u32 req_pld_sz; ++ u32 rsp_pld_sz; ++}; ++ ++#define BFA_FCXP_MOD(__bfa) (&(__bfa)->modules.fcxp_mod) ++#define BFA_FCXP_FROM_TAG(__mod, __tag) (&(__mod)->fcxp_list[__tag]) ++ ++typedef void (*fcxp_send_cb_t) (struct bfa_s *ioc, struct bfa_fcxp_s *fcxp, ++ void *cb_arg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++/** ++ * Information needed for a FCXP request ++ */ ++struct bfa_fcxp_req_info_s { ++ struct bfa_rport_s *bfa_rport; /* Pointer to the bfa rport that was ++ *returned from bfa_rport_create(). ++ *This could be left NULL for WKA or for ++ *FCXP interactions before the rport ++ *nexus is established ++ */ ++ struct fchs_s fchs; /* request FC header structure */ ++ u8 cts; /* continous sequence */ ++ u8 class; /* FC class for the request/response */ ++ u16 max_frmsz; /* max send frame size */ ++ u16 vf_id; /* vsan tag if applicable */ ++ u8 lp_tag; /* lport tag */ ++ u32 req_tot_len; /* request payload total length */ ++}; ++ ++struct bfa_fcxp_rsp_info_s { ++ struct fchs_s rsp_fchs; /* Response frame's FC header will ++ * be *sent back in this field */ ++ u8 rsp_timeout; /* timeout in seconds, 0-no response ++ */ ++ u8 rsvd2[3]; ++ u32 rsp_maxlen; /* max response length expected */ ++}; ++ ++struct bfa_fcxp_s { ++ struct list_head qe; /* fcxp queue element */ ++ bfa_sm_t sm; /* state machine */ ++ void *caller; /* driver or fcs */ ++ struct bfa_fcxp_mod_s *fcxp_mod; ++ /* back pointer to fcxp mod */ ++ u16 fcxp_tag; /* internal tag */ ++ struct bfa_fcxp_req_info_s req_info; ++ /* request info */ ++ struct bfa_fcxp_rsp_info_s rsp_info; ++ /* response info */ ++ u8 use_ireqbuf; /* use internal req buf */ ++ u8 use_irspbuf; /* use internal rsp buf */ ++ u32 nreq_sgles; /* num request SGLEs */ ++ u32 nrsp_sgles; /* num response SGLEs */ ++ struct list_head req_sgpg_q; /* SG pages for request buf */ ++ struct list_head req_sgpg_wqe; /* wait queue for req SG page */ ++ struct list_head rsp_sgpg_q; /* SG pages for response buf */ ++ struct list_head rsp_sgpg_wqe; /* wait queue for rsp SG page */ ++ ++ bfa_fcxp_get_sgaddr_t req_sga_cbfn; ++ /* SG elem addr user function */ ++ bfa_fcxp_get_sglen_t req_sglen_cbfn; ++ /* SG elem len user function */ ++ bfa_fcxp_get_sgaddr_t rsp_sga_cbfn; ++ /* SG elem addr user function */ ++ bfa_fcxp_get_sglen_t rsp_sglen_cbfn; ++ /* SG elem len user function */ ++ bfa_cb_fcxp_send_t send_cbfn; /* send completion callback */ ++ void *send_cbarg; /* callback arg */ ++ struct bfa_sge_s req_sge[BFA_FCXP_MAX_SGES]; ++ /* req SG elems */ ++ struct bfa_sge_s rsp_sge[BFA_FCXP_MAX_SGES]; ++ /* rsp SG elems */ ++ u8 rsp_status; /* comp: rsp status */ ++ u32 rsp_len; /* comp: actual response len */ ++ u32 residue_len; /* comp: residual rsp length */ ++ struct fchs_s rsp_fchs; /* comp: response fchs */ ++ struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */ ++ struct bfa_reqq_wait_s reqq_wqe; ++ bfa_boolean_t reqq_waiting; ++}; ++ ++#define BFA_FCXP_REQ_PLD(_fcxp) (bfa_fcxp_get_reqbuf(_fcxp)) ++ ++#define BFA_FCXP_RSP_FCHS(_fcxp) (&((_fcxp)->rsp_info.fchs)) ++#define BFA_FCXP_RSP_PLD(_fcxp) (bfa_fcxp_get_rspbuf(_fcxp)) ++ ++#define BFA_FCXP_REQ_PLD_PA(_fcxp) \ ++ ((_fcxp)->fcxp_mod->req_pld_list_pa + \ ++ ((_fcxp)->fcxp_mod->req_pld_sz * (_fcxp)->fcxp_tag)) ++ ++#define BFA_FCXP_RSP_PLD_PA(_fcxp) \ ++ ((_fcxp)->fcxp_mod->rsp_pld_list_pa + \ ++ ((_fcxp)->fcxp_mod->rsp_pld_sz * (_fcxp)->fcxp_tag)) ++ ++void bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++#endif /* __BFA_FCXP_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_fwimg_priv.h b/drivers/scsi/bfa/bfa_fwimg_priv.h +new file mode 100644 +index 0000000..1ec1355 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_fwimg_priv.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FWIMG_PRIV_H__ ++#define __BFA_FWIMG_PRIV_H__ ++ ++#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */ ++#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32)) ++ ++extern u32 *bfi_image_ct_get_chunk(u32 off); ++extern u32 bfi_image_ct_size; ++extern u32 *bfi_image_cb_get_chunk(u32 off); ++extern u32 bfi_image_cb_size; ++extern u32 *bfi_image_cb; ++extern u32 *bfi_image_ct; ++ ++#endif /* __BFA_FWIMG_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c +new file mode 100644 +index 0000000..ede1438 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_hw_cb.c +@@ -0,0 +1,142 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++void ++bfa_hwcb_reginit(struct bfa_s *bfa) ++{ ++ struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs; ++ bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc); ++ int i, q, fn = bfa_ioc_pcifn(&bfa->ioc); ++ ++ if (fn == 0) { ++ bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS); ++ bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK); ++ } else { ++ bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS); ++ bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK); ++ } ++ ++ for (i = 0; i < BFI_IOC_MAX_CQS; i++) { ++ /* ++ * CPE registers ++ */ ++ q = CPE_Q_NUM(fn, i); ++ bfa_regs->cpe_q_pi[i] = (kva + CPE_Q_PI(q)); ++ bfa_regs->cpe_q_ci[i] = (kva + CPE_Q_CI(q)); ++ bfa_regs->cpe_q_depth[i] = (kva + CPE_Q_DEPTH(q)); ++ ++ /* ++ * RME registers ++ */ ++ q = CPE_Q_NUM(fn, i); ++ bfa_regs->rme_q_pi[i] = (kva + RME_Q_PI(q)); ++ bfa_regs->rme_q_ci[i] = (kva + RME_Q_CI(q)); ++ bfa_regs->rme_q_depth[i] = (kva + RME_Q_DEPTH(q)); ++ } ++} ++ ++void ++bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) ++{ ++} ++ ++static void ++bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq) ++{ ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, ++ __HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq)); ++} ++ ++void ++bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap, ++ u32 *num_vecs, u32 *max_vec_bit) ++{ ++#define __HFN_NUMINTS 13 ++ if (bfa_ioc_pcifn(&bfa->ioc) == 0) { ++ *msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | ++ __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 | ++ __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 | ++ __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 | ++ __HFN_INT_MBOX_LPU0); ++ *max_vec_bit = __HFN_INT_MBOX_LPU0; ++ } else { ++ *msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 | ++ __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 | ++ __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 | ++ __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 | ++ __HFN_INT_MBOX_LPU1); ++ *max_vec_bit = __HFN_INT_MBOX_LPU1; ++ } ++ ++ *msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | ++ __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS); ++ *num_vecs = __HFN_NUMINTS; ++} ++ ++/** ++ * No special setup required for crossbow -- vector assignments are implicit. ++ */ ++void ++bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs) ++{ ++ int i; ++ ++ bfa_assert((nvecs == 1) || (nvecs == __HFN_NUMINTS)); ++ ++ bfa->msix.nvecs = nvecs; ++ if (nvecs == 1) { ++ for (i = 0; i < BFA_MSIX_CB_MAX; i++) ++ bfa->msix.handler[i] = bfa_msix_all; ++ return; ++ } ++ ++ for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q7; i++) ++ bfa->msix.handler[i] = bfa_msix_reqq; ++ ++ for (i = BFA_MSIX_RME_Q0; i <= BFA_MSIX_RME_Q7; i++) ++ bfa->msix.handler[i] = bfa_msix_rspq; ++ ++ for (; i < BFA_MSIX_CB_MAX; i++) ++ bfa->msix.handler[i] = bfa_msix_lpu_err; ++} ++ ++/** ++ * Crossbow -- dummy, interrupts are masked ++ */ ++void ++bfa_hwcb_msix_install(struct bfa_s *bfa) ++{ ++} ++ ++void ++bfa_hwcb_msix_uninstall(struct bfa_s *bfa) ++{ ++} ++ ++/** ++ * No special enable/disable -- vector assignments are implicit. ++ */ ++void ++bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) ++{ ++ bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c +new file mode 100644 +index 0000000..51ae574 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_hw_ct.c +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, IOCFC_CT); ++ ++static u32 __ct_msix_err_vec_reg[] = { ++ HOST_MSIX_ERR_INDEX_FN0, ++ HOST_MSIX_ERR_INDEX_FN1, ++ HOST_MSIX_ERR_INDEX_FN2, ++ HOST_MSIX_ERR_INDEX_FN3, ++}; ++ ++static void ++bfa_hwct_msix_lpu_err_set(struct bfa_s *bfa, bfa_boolean_t msix, int vec) ++{ ++ int fn = bfa_ioc_pcifn(&bfa->ioc); ++ bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc); ++ ++ if (msix) ++ bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], vec); ++ else ++ bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], 0); ++} ++ ++/** ++ * Dummy interrupt handler for handling spurious interrupt during chip-reinit. ++ */ ++static void ++bfa_hwct_msix_dummy(struct bfa_s *bfa, int vec) ++{ ++} ++ ++void ++bfa_hwct_reginit(struct bfa_s *bfa) ++{ ++ struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs; ++ bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc); ++ int i, q, fn = bfa_ioc_pcifn(&bfa->ioc); ++ ++ if (fn == 0) { ++ bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS); ++ bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK); ++ } else { ++ bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS); ++ bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK); ++ } ++ ++ for (i = 0; i < BFI_IOC_MAX_CQS; i++) { ++ /* ++ * CPE registers ++ */ ++ q = CPE_Q_NUM(fn, i); ++ bfa_regs->cpe_q_pi[i] = (kva + CPE_PI_PTR_Q(q << 5)); ++ bfa_regs->cpe_q_ci[i] = (kva + CPE_CI_PTR_Q(q << 5)); ++ bfa_regs->cpe_q_depth[i] = (kva + CPE_DEPTH_Q(q << 5)); ++ bfa_regs->cpe_q_ctrl[i] = (kva + CPE_QCTRL_Q(q << 5)); ++ ++ /* ++ * RME registers ++ */ ++ q = CPE_Q_NUM(fn, i); ++ bfa_regs->rme_q_pi[i] = (kva + RME_PI_PTR_Q(q << 5)); ++ bfa_regs->rme_q_ci[i] = (kva + RME_CI_PTR_Q(q << 5)); ++ bfa_regs->rme_q_depth[i] = (kva + RME_DEPTH_Q(q << 5)); ++ bfa_regs->rme_q_ctrl[i] = (kva + RME_QCTRL_Q(q << 5)); ++ } ++} ++ ++void ++bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) ++{ ++ u32 r32; ++ ++ r32 = bfa_reg_read(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]); ++ bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq], r32); ++} ++ ++void ++bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap, ++ u32 *num_vecs, u32 *max_vec_bit) ++{ ++ *msix_vecs_bmap = (1 << BFA_MSIX_CT_MAX) - 1; ++ *max_vec_bit = (1 << (BFA_MSIX_CT_MAX - 1)); ++ *num_vecs = BFA_MSIX_CT_MAX; ++} ++ ++/** ++ * Setup MSI-X vector for catapult ++ */ ++void ++bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs) ++{ ++ bfa_assert((nvecs == 1) || (nvecs == BFA_MSIX_CT_MAX)); ++ bfa_trc(bfa, nvecs); ++ ++ bfa->msix.nvecs = nvecs; ++ bfa_hwct_msix_uninstall(bfa); ++} ++ ++void ++bfa_hwct_msix_install(struct bfa_s *bfa) ++{ ++ int i; ++ ++ if (bfa->msix.nvecs == 0) ++ return; ++ ++ if (bfa->msix.nvecs == 1) { ++ for (i = 0; i < BFA_MSIX_CT_MAX; i++) ++ bfa->msix.handler[i] = bfa_msix_all; ++ return; ++ } ++ ++ for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q3; i++) ++ bfa->msix.handler[i] = bfa_msix_reqq; ++ ++ for (; i <= BFA_MSIX_RME_Q3; i++) ++ bfa->msix.handler[i] = bfa_msix_rspq; ++ ++ bfa_assert(i == BFA_MSIX_LPU_ERR); ++ bfa->msix.handler[BFA_MSIX_LPU_ERR] = bfa_msix_lpu_err; ++} ++ ++void ++bfa_hwct_msix_uninstall(struct bfa_s *bfa) ++{ ++ int i; ++ ++ for (i = 0; i < BFA_MSIX_CT_MAX; i++) ++ bfa->msix.handler[i] = bfa_hwct_msix_dummy; ++} ++ ++/** ++ * Enable MSI-X vectors ++ */ ++void ++bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) ++{ ++ bfa_trc(bfa, 0); ++ bfa_hwct_msix_lpu_err_set(bfa, msix, BFA_MSIX_LPU_ERR); ++ bfa_ioc_isr_mode_set(&bfa->ioc, msix); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c +new file mode 100644 +index 0000000..0ca1257 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_intr.c +@@ -0,0 +1,218 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, INTR); ++ ++static void ++bfa_msix_errint(struct bfa_s *bfa, u32 intr) ++{ ++ bfa_ioc_error_isr(&bfa->ioc); ++} ++ ++static void ++bfa_msix_lpu(struct bfa_s *bfa) ++{ ++ bfa_ioc_mbox_isr(&bfa->ioc); ++} ++ ++void ++bfa_msix_all(struct bfa_s *bfa, int vec) ++{ ++ bfa_intx(bfa); ++} ++ ++/** ++ * hal_intr_api ++ */ ++bfa_boolean_t ++bfa_intx(struct bfa_s *bfa) ++{ ++ u32 intr, qintr; ++ int queue; ++ ++ intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); ++ if (!intr) ++ return BFA_FALSE; ++ ++ /** ++ * RME completion queue interrupt ++ */ ++ qintr = intr & __HFN_INT_RME_MASK; ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr); ++ ++ for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue ++) { ++ if (intr & (__HFN_INT_RME_Q0 << queue)) ++ bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); ++ } ++ intr &= ~qintr; ++ if (!intr) ++ return BFA_TRUE; ++ ++ /** ++ * CPE completion queue interrupt ++ */ ++ qintr = intr & __HFN_INT_CPE_MASK; ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr); ++ ++ for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) { ++ if (intr & (__HFN_INT_CPE_Q0 << queue)) ++ bfa_msix_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1)); ++ } ++ intr &= ~qintr; ++ if (!intr) ++ return BFA_TRUE; ++ ++ bfa_msix_lpu_err(bfa, intr); ++ ++ return BFA_TRUE; ++} ++ ++void ++bfa_isr_enable(struct bfa_s *bfa) ++{ ++ u32 intr_unmask; ++ int pci_func = bfa_ioc_pcifn(&bfa->ioc); ++ ++ bfa_trc(bfa, pci_func); ++ ++ bfa_msix_install(bfa); ++ intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 | ++ __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS); ++ ++ if (pci_func == 0) ++ intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 | ++ __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 | ++ __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 | ++ __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 | ++ __HFN_INT_MBOX_LPU0); ++ else ++ intr_unmask |= (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 | ++ __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 | ++ __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 | ++ __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 | ++ __HFN_INT_MBOX_LPU1); ++ ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask); ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask); ++ bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0); ++} ++ ++void ++bfa_isr_disable(struct bfa_s *bfa) ++{ ++ bfa_isr_mode_set(bfa, BFA_FALSE); ++ bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, -1L); ++ bfa_msix_uninstall(bfa); ++} ++ ++void ++bfa_msix_reqq(struct bfa_s *bfa, int qid) ++{ ++ struct list_head *waitq, *qe, *qen; ++ struct bfa_reqq_wait_s *wqe; ++ ++ qid &= (BFI_IOC_MAX_CQS - 1); ++ ++ waitq = bfa_reqq(bfa, qid); ++ list_for_each_safe(qe, qen, waitq) { ++ /** ++ * Callback only as long as there is room in request queue ++ */ ++ if (bfa_reqq_full(bfa, qid)) ++ break; ++ ++ list_del(qe); ++ wqe = (struct bfa_reqq_wait_s *) qe; ++ wqe->qresume(wqe->cbarg); ++ } ++} ++ ++void ++bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ bfa_trc(bfa, m->mhdr.msg_class); ++ bfa_trc(bfa, m->mhdr.msg_id); ++ bfa_trc(bfa, m->mhdr.mtag.i2htok); ++ bfa_assert(0); ++ bfa_trc_stop(bfa->trcmod); ++} ++ ++void ++bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) ++{ ++ struct bfi_msg_s *m; ++ u32 pi, ci; ++ ++ bfa_trc_fp(bfa, rsp_qid); ++ ++ rsp_qid &= (BFI_IOC_MAX_CQS - 1); ++ ++ bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid); ++ ++ ci = bfa_rspq_ci(bfa, rsp_qid); ++ pi = bfa_rspq_pi(bfa, rsp_qid); ++ ++ bfa_trc_fp(bfa, ci); ++ bfa_trc_fp(bfa, pi); ++ ++ if (bfa->rme_process) { ++ while (ci != pi) { ++ m = bfa_rspq_elem(bfa, rsp_qid, ci); ++ bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); ++ ++ bfa_isrs[m->mhdr.msg_class] (bfa, m); ++ ++ CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems); ++ } ++ } ++ ++ /** ++ * update CI ++ */ ++ bfa_rspq_ci(bfa, rsp_qid) = pi; ++ bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); ++ bfa_os_mmiowb(); ++} ++ ++void ++bfa_msix_lpu_err(struct bfa_s *bfa, int vec) ++{ ++ u32 intr; ++ ++ intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status); ++ ++ if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1)) ++ bfa_msix_lpu(bfa); ++ ++ if (intr & (__HFN_INT_ERR_EMC | ++ __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 | ++ __HFN_INT_ERR_PSS)) ++ bfa_msix_errint(bfa, intr); ++} ++ ++void ++bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func) ++{ ++ bfa_isrs[mc] = isr_func; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_intr_priv.h b/drivers/scsi/bfa/bfa_intr_priv.h +new file mode 100644 +index 0000000..8ce6e6b +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_intr_priv.h +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_INTR_PRIV_H__ ++#define __BFA_INTR_PRIV_H__ ++ ++/** ++ * Message handler ++ */ ++typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); ++void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m); ++void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func); ++ ++ ++#define bfa_reqq_pi(__bfa, __reqq) (__bfa)->iocfc.req_cq_pi[__reqq] ++#define bfa_reqq_ci(__bfa, __reqq) \ ++ *(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva) ++ ++#define bfa_reqq_full(__bfa, __reqq) \ ++ (((bfa_reqq_pi(__bfa, __reqq) + 1) & \ ++ ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1)) == \ ++ bfa_reqq_ci(__bfa, __reqq)) ++ ++#define bfa_reqq_next(__bfa, __reqq) \ ++ (bfa_reqq_full(__bfa, __reqq) ? NULL : \ ++ ((void *)((struct bfi_msg_s *)((__bfa)->iocfc.req_cq_ba[__reqq].kva) \ ++ + bfa_reqq_pi((__bfa), (__reqq))))) ++ ++#define bfa_reqq_produce(__bfa, __reqq) do { \ ++ (__bfa)->iocfc.req_cq_pi[__reqq]++; \ ++ (__bfa)->iocfc.req_cq_pi[__reqq] &= \ ++ ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1); \ ++ bfa_reg_write((__bfa)->iocfc.bfa_regs.cpe_q_pi[__reqq], \ ++ (__bfa)->iocfc.req_cq_pi[__reqq]); \ ++ bfa_os_mmiowb(); \ ++} while (0) ++ ++#define bfa_rspq_pi(__bfa, __rspq) \ ++ *(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva) ++ ++#define bfa_rspq_ci(__bfa, __rspq) (__bfa)->iocfc.rsp_cq_ci[__rspq] ++#define bfa_rspq_elem(__bfa, __rspq, __ci) \ ++ &((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci] ++ ++#define CQ_INCR(__index, __size) \ ++ (__index)++; (__index) &= ((__size) - 1) ++ ++/** ++ * Queue element to wait for room in request queue. FIFO order is ++ * maintained when fullfilling requests. ++ */ ++struct bfa_reqq_wait_s { ++ struct list_head qe; ++ void (*qresume) (void *cbarg); ++ void *cbarg; ++}; ++ ++/** ++ * Circular queue usage assignments ++ */ ++enum { ++ BFA_REQQ_IOC = 0, /* all low-priority IOC msgs */ ++ BFA_REQQ_FCXP = 0, /* all FCXP messages */ ++ BFA_REQQ_LPS = 0, /* all lport service msgs */ ++ BFA_REQQ_PORT = 0, /* all port messages */ ++ BFA_REQQ_FLASH = 0, /* for flash module */ ++ BFA_REQQ_DIAG = 0, /* for diag module */ ++ BFA_REQQ_RPORT = 0, /* all port messages */ ++ BFA_REQQ_SBOOT = 0, /* all san boot messages */ ++ BFA_REQQ_QOS_LO = 1, /* all low priority IO */ ++ BFA_REQQ_QOS_MD = 2, /* all medium priority IO */ ++ BFA_REQQ_QOS_HI = 3, /* all high priority IO */ ++}; ++ ++static inline void ++bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg), ++ void *cbarg) ++{ ++ wqe->qresume = qresume; ++ wqe->cbarg = cbarg; ++} ++ ++#define bfa_reqq(__bfa, __reqq) &(__bfa)->reqq_waitq[__reqq] ++ ++/** ++ * static inline void ++ * bfa_reqq_wait(struct bfa_s *bfa, int reqq, struct bfa_reqq_wait_s *wqe) ++ */ ++#define bfa_reqq_wait(__bfa, __reqq, __wqe) do { \ ++ \ ++ struct list_head *waitq = bfa_reqq(__bfa, __reqq); \ ++ \ ++ bfa_assert(((__reqq) < BFI_IOC_MAX_CQS)); \ ++ bfa_assert((__wqe)->qresume && (__wqe)->cbarg); \ ++ \ ++ list_add_tail(&(__wqe)->qe, waitq); \ ++} while (0) ++ ++#define bfa_reqq_wcancel(__wqe) list_del(&(__wqe)->qe) ++ ++#endif /* __BFA_INTR_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c +new file mode 100644 +index 0000000..1493489 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_ioc.c +@@ -0,0 +1,2382 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, IOC); ++ ++/** ++ * IOC local definitions ++ */ ++#define BFA_IOC_TOV 2000 /* msecs */ ++#define BFA_IOC_HB_TOV 1000 /* msecs */ ++#define BFA_IOC_HB_FAIL_MAX 4 ++#define BFA_IOC_HWINIT_MAX 2 ++#define BFA_IOC_FWIMG_MINSZ (16 * 1024) ++#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \ ++ + BFA_IOC_TOV) ++ ++#define bfa_ioc_timer_start(__ioc) \ ++ bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \ ++ bfa_ioc_timeout, (__ioc), BFA_IOC_TOV) ++#define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer) ++ ++#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS) ++#define BFA_DBG_FWTRC_LEN \ ++ (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \ ++ (sizeof(struct bfa_trc_mod_s) - \ ++ BFA_TRC_MAX * sizeof(struct bfa_trc_s))) ++#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn)) ++#define bfa_ioc_stats(_ioc, _stats) (_ioc)->stats._stats ++ ++ ++#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) ++#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) ++#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) ++bfa_boolean_t bfa_auto_recover = BFA_FALSE; ++ ++/* ++ * forward declarations ++ */ ++static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa, ++ enum bfa_ioc_aen_event event); ++static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc); ++static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc); ++static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc); ++static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force); ++static void bfa_ioc_timeout(void *ioc); ++static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc); ++static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc); ++static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc); ++static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc); ++static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc); ++static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force); ++static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc); ++static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc); ++static void bfa_ioc_recover(struct bfa_ioc_s *ioc); ++static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc); ++static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc); ++static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); ++static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); ++ ++/** ++ * bfa_ioc_sm ++ */ ++ ++/** ++ * IOC state machine events ++ */ ++enum ioc_event { ++ IOC_E_ENABLE = 1, /* IOC enable request */ ++ IOC_E_DISABLE = 2, /* IOC disable request */ ++ IOC_E_TIMEOUT = 3, /* f/w response timeout */ ++ IOC_E_FWREADY = 4, /* f/w initialization done */ ++ IOC_E_FWRSP_GETATTR = 5, /* IOC get attribute response */ ++ IOC_E_FWRSP_ENABLE = 6, /* enable f/w response */ ++ IOC_E_FWRSP_DISABLE = 7, /* disable f/w response */ ++ IOC_E_HBFAIL = 8, /* heartbeat failure */ ++ IOC_E_HWERROR = 9, /* hardware error interrupt */ ++ IOC_E_SEMLOCKED = 10, /* h/w semaphore is locked */ ++ IOC_E_DETACH = 11, /* driver detach cleanup */ ++}; ++ ++bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); ++bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); ++ ++static struct bfa_sm_table_s ioc_sm_table[] = { ++ {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, ++ {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH}, ++ {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH}, ++ {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT}, ++ {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT}, ++ {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT}, ++ {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, ++ {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, ++ {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL}, ++ {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL}, ++ {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, ++ {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, ++}; ++ ++/** ++ * Reset entry actions -- initialize state machine ++ */ ++static void ++bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc) ++{ ++ ioc->retry_count = 0; ++ ioc->auto_recover = bfa_auto_recover; ++} ++ ++/** ++ * Beginning state. IOC is in reset state. ++ */ ++static void ++bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_ENABLE: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_disable_comp(ioc); ++ break; ++ ++ case IOC_E_DETACH: ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++/** ++ * Semaphore should be acquired for version check. ++ */ ++static void ++bfa_ioc_sm_fwcheck_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_hw_sem_get(ioc); ++} ++ ++/** ++ * Awaiting h/w semaphore to continue with version check. ++ */ ++static void ++bfa_ioc_sm_fwcheck(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_SEMLOCKED: ++ if (bfa_ioc_firmware_lock(ioc)) { ++ ioc->retry_count = 0; ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); ++ } else { ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch); ++ } ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_disable_comp(ioc); ++ /* ++ * fall through ++ */ ++ ++ case IOC_E_DETACH: ++ bfa_ioc_hw_sem_get_cancel(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); ++ break; ++ ++ case IOC_E_FWREADY: ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++/** ++ * Notify enable completion callback and generate mismatch AEN. ++ */ ++static void ++bfa_ioc_sm_mismatch_entry(struct bfa_ioc_s *ioc) ++{ ++ /** ++ * Provide enable completion callback and AEN notification only once. ++ */ ++ if (ioc->retry_count == 0) { ++ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); ++ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH); ++ } ++ ioc->retry_count++; ++ bfa_ioc_timer_start(ioc); ++} ++ ++/** ++ * Awaiting firmware version match. ++ */ ++static void ++bfa_ioc_sm_mismatch(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_TIMEOUT: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_disable_comp(ioc); ++ /* ++ * fall through ++ */ ++ ++ case IOC_E_DETACH: ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); ++ break; ++ ++ case IOC_E_FWREADY: ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++/** ++ * Request for semaphore. ++ */ ++static void ++bfa_ioc_sm_semwait_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_hw_sem_get(ioc); ++} ++ ++/** ++ * Awaiting semaphore for h/w initialzation. ++ */ ++static void ++bfa_ioc_sm_semwait(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_SEMLOCKED: ++ ioc->retry_count = 0; ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_hw_sem_get_cancel(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_hwinit_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_timer_start(ioc); ++ bfa_ioc_reset(ioc, BFA_FALSE); ++} ++ ++/** ++ * Hardware is being initialized. Interrupts are enabled. ++ * Holding hardware semaphore lock. ++ */ ++static void ++bfa_ioc_sm_hwinit(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_FWREADY: ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); ++ break; ++ ++ case IOC_E_HWERROR: ++ bfa_ioc_timer_stop(ioc); ++ /* ++ * fall through ++ */ ++ ++ case IOC_E_TIMEOUT: ++ ioc->retry_count++; ++ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { ++ bfa_ioc_timer_start(ioc); ++ bfa_ioc_reset(ioc, BFA_TRUE); ++ break; ++ } ++ ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_timer_start(ioc); ++ bfa_ioc_send_enable(ioc); ++} ++ ++/** ++ * Host IOC function is being enabled, awaiting response from firmware. ++ * Semaphore is acquired. ++ */ ++static void ++bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_FWRSP_ENABLE: ++ bfa_ioc_timer_stop(ioc); ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); ++ break; ++ ++ case IOC_E_HWERROR: ++ bfa_ioc_timer_stop(ioc); ++ /* ++ * fall through ++ */ ++ ++ case IOC_E_TIMEOUT: ++ ioc->retry_count++; ++ if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { ++ bfa_reg_write(ioc->ioc_regs.ioc_fwstate, ++ BFI_IOC_UNINIT); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); ++ break; ++ } ++ ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_timer_stop(ioc); ++ bfa_ioc_hw_sem_release(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ case IOC_E_FWREADY: ++ bfa_ioc_send_enable(ioc); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_timer_start(ioc); ++ bfa_ioc_send_getattr(ioc); ++} ++ ++/** ++ * IOC configuration in progress. Timer is active. ++ */ ++static void ++bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_FWRSP_GETATTR: ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_op); ++ break; ++ ++ case IOC_E_HWERROR: ++ bfa_ioc_timer_stop(ioc); ++ /* ++ * fall through ++ */ ++ ++ case IOC_E_TIMEOUT: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) ++{ ++ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); ++ bfa_ioc_hb_monitor(ioc); ++ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE); ++} ++ ++static void ++bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_ENABLE: ++ break; ++ ++ case IOC_E_DISABLE: ++ bfa_ioc_hb_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); ++ break; ++ ++ case IOC_E_HWERROR: ++ case IOC_E_FWREADY: ++ /** ++ * Hard error or IOC recovery by other function. ++ * Treat it same as heartbeat failure. ++ */ ++ bfa_ioc_hb_stop(ioc); ++ /* ++ * !!! fall through !!! ++ */ ++ ++ case IOC_E_HBFAIL: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE); ++ bfa_ioc_timer_start(ioc); ++ bfa_ioc_send_disable(ioc); ++} ++ ++/** ++ * IOC is being disabled ++ */ ++static void ++bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_HWERROR: ++ case IOC_E_FWRSP_DISABLE: ++ bfa_ioc_timer_stop(ioc); ++ /* ++ * !!! fall through !!! ++ */ ++ ++ case IOC_E_TIMEOUT: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++/** ++ * IOC disable completion entry. ++ */ ++static void ++bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_disable_comp(ioc); ++} ++ ++static void ++bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_ENABLE: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); ++ break; ++ ++ case IOC_E_DISABLE: ++ ioc->cbfn->disable_cbfn(ioc->bfa); ++ break; ++ ++ case IOC_E_FWREADY: ++ break; ++ ++ case IOC_E_DETACH: ++ bfa_ioc_firmware_unlock(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc) ++{ ++ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); ++ bfa_ioc_timer_start(ioc); ++} ++ ++/** ++ * Hardware initialization failed. ++ */ ++static void ++bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ case IOC_E_DISABLE: ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ case IOC_E_DETACH: ++ bfa_ioc_timer_stop(ioc); ++ bfa_ioc_firmware_unlock(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); ++ break; ++ ++ case IOC_E_TIMEOUT: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++static void ++bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc) ++{ ++ struct list_head *qe; ++ struct bfa_ioc_hbfail_notify_s *notify; ++ ++ /** ++ * Mark IOC as failed in hardware and stop firmware. ++ */ ++ bfa_ioc_lpu_stop(ioc); ++ bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL); ++ ++ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { ++ bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P); ++ /* ++ * Wait for halt to take effect ++ */ ++ bfa_reg_read(ioc->ioc_regs.ll_halt); ++ } ++ ++ /** ++ * Notify driver and common modules registered for notification. ++ */ ++ ioc->cbfn->hbfail_cbfn(ioc->bfa); ++ list_for_each(qe, &ioc->hb_notify_q) { ++ notify = (struct bfa_ioc_hbfail_notify_s *)qe; ++ notify->cbfn(notify->cbarg); ++ } ++ ++ /** ++ * Flush any queued up mailbox requests. ++ */ ++ bfa_ioc_mbox_hbfail(ioc); ++ bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL); ++ ++ /** ++ * Trigger auto-recovery after a delay. ++ */ ++ if (ioc->auto_recover) { ++ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, ++ bfa_ioc_timeout, ioc, BFA_IOC_TOV_RECOVER); ++ } ++} ++ ++/** ++ * IOC heartbeat failure. ++ */ ++static void ++bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event) ++{ ++ bfa_trc(ioc, event); ++ ++ switch (event) { ++ ++ case IOC_E_ENABLE: ++ ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); ++ break; ++ ++ case IOC_E_DISABLE: ++ if (ioc->auto_recover) ++ bfa_ioc_timer_stop(ioc); ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); ++ break; ++ ++ case IOC_E_TIMEOUT: ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); ++ break; ++ ++ case IOC_E_FWREADY: ++ /** ++ * Recovery is already initiated by other function. ++ */ ++ break; ++ ++ default: ++ bfa_sm_fault(ioc, event); ++ } ++} ++ ++ ++ ++/** ++ * bfa_ioc_pvt BFA IOC private functions ++ */ ++ ++static void ++bfa_ioc_disable_comp(struct bfa_ioc_s *ioc) ++{ ++ struct list_head *qe; ++ struct bfa_ioc_hbfail_notify_s *notify; ++ ++ ioc->cbfn->disable_cbfn(ioc->bfa); ++ ++ /** ++ * Notify common modules registered for notification. ++ */ ++ list_for_each(qe, &ioc->hb_notify_q) { ++ notify = (struct bfa_ioc_hbfail_notify_s *)qe; ++ notify->cbfn(notify->cbarg); ++ } ++} ++ ++static void ++bfa_ioc_sem_timeout(void *ioc_arg) ++{ ++ struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; ++ ++ bfa_ioc_hw_sem_get(ioc); ++} ++ ++static void ++bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc) ++{ ++ u32 r32; ++ int cnt = 0; ++#define BFA_SEM_SPINCNT 1000 ++ ++ do { ++ r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg); ++ cnt++; ++ if (cnt > BFA_SEM_SPINCNT) ++ break; ++ } while (r32 != 0); ++ bfa_assert(cnt < BFA_SEM_SPINCNT); ++} ++ ++static void ++bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc) ++{ ++ bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1); ++} ++ ++static void ++bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc) ++{ ++ u32 r32; ++ ++ /** ++ * First read to the semaphore register will return 0, subsequent reads ++ * will return 1. Semaphore is released by writing 0 to the register ++ */ ++ r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg); ++ if (r32 == 0) { ++ bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED); ++ return; ++ } ++ ++ bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout, ++ ioc, BFA_IOC_TOV); ++} ++ ++static void ++bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc) ++{ ++ bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1); ++} ++ ++static void ++bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc) ++{ ++ bfa_timer_stop(&ioc->sem_timer); ++} ++ ++/** ++ * Initialize LPU local memory (aka secondary memory / SRAM) ++ */ ++static void ++bfa_ioc_lmem_init(struct bfa_ioc_s *ioc) ++{ ++ u32 pss_ctl; ++ int i; ++#define PSS_LMEM_INIT_TIME 10000 ++ ++ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg); ++ pss_ctl &= ~__PSS_LMEM_RESET; ++ pss_ctl |= __PSS_LMEM_INIT_EN; ++ pss_ctl |= __PSS_I2C_CLK_DIV(3UL); /* i2c workaround 12.5khz clock */ ++ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl); ++ ++ /** ++ * wait for memory initialization to be complete ++ */ ++ i = 0; ++ do { ++ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg); ++ i++; ++ } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); ++ ++ /** ++ * If memory initialization is not successful, IOC timeout will catch ++ * such failures. ++ */ ++ bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE); ++ bfa_trc(ioc, pss_ctl); ++ ++ pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); ++ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl); ++} ++ ++static void ++bfa_ioc_lpu_start(struct bfa_ioc_s *ioc) ++{ ++ u32 pss_ctl; ++ ++ /** ++ * Take processor out of reset. ++ */ ++ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg); ++ pss_ctl &= ~__PSS_LPU0_RESET; ++ ++ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl); ++} ++ ++static void ++bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc) ++{ ++ u32 pss_ctl; ++ ++ /** ++ * Put processors in reset. ++ */ ++ pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg); ++ pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); ++ ++ bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl); ++} ++ ++/** ++ * Get driver and firmware versions. ++ */ ++static void ++bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) ++{ ++ u32 pgnum, pgoff; ++ u32 loff = 0; ++ int i; ++ u32 *fwsig = (u32 *) fwhdr; ++ ++ pgnum = bfa_ioc_smem_pgnum(ioc, loff); ++ pgoff = bfa_ioc_smem_pgoff(ioc, loff); ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); ++ ++ for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32)); ++ i++) { ++ fwsig[i] = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); ++ loff += sizeof(u32); ++ } ++} ++ ++static u32 * ++bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off) ++{ ++ if (ioc->ctdev) ++ return bfi_image_ct_get_chunk(off); ++ return bfi_image_cb_get_chunk(off); ++} ++ ++static u32 ++bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc) ++{ ++return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size; ++} ++ ++/** ++ * Returns TRUE if same. ++ */ ++static bfa_boolean_t ++bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr) ++{ ++ struct bfi_ioc_image_hdr_s *drv_fwhdr; ++ int i; ++ ++ drv_fwhdr = ++ (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0); ++ ++ for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { ++ if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) { ++ bfa_trc(ioc, i); ++ bfa_trc(ioc, fwhdr->md5sum[i]); ++ bfa_trc(ioc, drv_fwhdr->md5sum[i]); ++ return BFA_FALSE; ++ } ++ } ++ ++ bfa_trc(ioc, fwhdr->md5sum[0]); ++ return BFA_TRUE; ++} ++ ++/** ++ * Return true if current running version is valid. Firmware signature and ++ * execution context (driver/bios) must match. ++ */ ++static bfa_boolean_t ++bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc) ++{ ++ struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr; ++ ++ /** ++ * If bios/efi boot (flash based) -- return true ++ */ ++ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) ++ return BFA_TRUE; ++ ++ bfa_ioc_fwver_get(ioc, &fwhdr); ++ drv_fwhdr = ++ (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0); ++ ++ if (fwhdr.signature != drv_fwhdr->signature) { ++ bfa_trc(ioc, fwhdr.signature); ++ bfa_trc(ioc, drv_fwhdr->signature); ++ return BFA_FALSE; ++ } ++ ++ if (fwhdr.exec != drv_fwhdr->exec) { ++ bfa_trc(ioc, fwhdr.exec); ++ bfa_trc(ioc, drv_fwhdr->exec); ++ return BFA_FALSE; ++ } ++ ++ return bfa_ioc_fwver_cmp(ioc, &fwhdr); ++} ++ ++/** ++ * Return true if firmware of current driver matches the running firmware. ++ */ ++static bfa_boolean_t ++bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc) ++{ ++ enum bfi_ioc_state ioc_fwstate; ++ u32 usecnt; ++ struct bfi_ioc_image_hdr_s fwhdr; ++ ++ /** ++ * Firmware match check is relevant only for CNA. ++ */ ++ if (!ioc->cna) ++ return BFA_TRUE; ++ ++ /** ++ * If bios boot (flash based) -- do not increment usage count ++ */ ++ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) ++ return BFA_TRUE; ++ ++ bfa_ioc_usage_sem_get(ioc); ++ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); ++ ++ /** ++ * If usage count is 0, always return TRUE. ++ */ ++ if (usecnt == 0) { ++ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1); ++ bfa_ioc_usage_sem_release(ioc); ++ bfa_trc(ioc, usecnt); ++ return BFA_TRUE; ++ } ++ ++ ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); ++ bfa_trc(ioc, ioc_fwstate); ++ ++ /** ++ * Use count cannot be non-zero and chip in uninitialized state. ++ */ ++ bfa_assert(ioc_fwstate != BFI_IOC_UNINIT); ++ ++ /** ++ * Check if another driver with a different firmware is active ++ */ ++ bfa_ioc_fwver_get(ioc, &fwhdr); ++ if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { ++ bfa_ioc_usage_sem_release(ioc); ++ bfa_trc(ioc, usecnt); ++ return BFA_FALSE; ++ } ++ ++ /** ++ * Same firmware version. Increment the reference count. ++ */ ++ usecnt++; ++ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); ++ bfa_ioc_usage_sem_release(ioc); ++ bfa_trc(ioc, usecnt); ++ return BFA_TRUE; ++} ++ ++static void ++bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc) ++{ ++ u32 usecnt; ++ ++ /** ++ * Firmware lock is relevant only for CNA. ++ * If bios boot (flash based) -- do not decrement usage count ++ */ ++ if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)) ++ return; ++ ++ /** ++ * decrement usage count ++ */ ++ bfa_ioc_usage_sem_get(ioc); ++ usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg); ++ bfa_assert(usecnt > 0); ++ ++ usecnt--; ++ bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt); ++ bfa_trc(ioc, usecnt); ++ ++ bfa_ioc_usage_sem_release(ioc); ++} ++ ++/** ++ * Conditionally flush any pending message from firmware at start. ++ */ ++static void ++bfa_ioc_msgflush(struct bfa_ioc_s *ioc) ++{ ++ u32 r32; ++ ++ r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd); ++ if (r32) ++ bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1); ++} ++ ++ ++static void ++bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force) ++{ ++ enum bfi_ioc_state ioc_fwstate; ++ bfa_boolean_t fwvalid; ++ ++ ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate); ++ ++ if (force) ++ ioc_fwstate = BFI_IOC_UNINIT; ++ ++ bfa_trc(ioc, ioc_fwstate); ++ ++ /** ++ * check if firmware is valid ++ */ ++ fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? ++ BFA_FALSE : bfa_ioc_fwver_valid(ioc); ++ ++ if (!fwvalid) { ++ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); ++ return; ++ } ++ ++ /** ++ * If hardware initialization is in progress (initialized by other IOC), ++ * just wait for an initialization completion interrupt. ++ */ ++ if (ioc_fwstate == BFI_IOC_INITING) { ++ bfa_trc(ioc, ioc_fwstate); ++ ioc->cbfn->reset_cbfn(ioc->bfa); ++ return; ++ } ++ ++ /** ++ * If IOC function is disabled and firmware version is same, ++ * just re-enable IOC. ++ */ ++ if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) { ++ bfa_trc(ioc, ioc_fwstate); ++ ++ /** ++ * When using MSI-X any pending firmware ready event should ++ * be flushed. Otherwise MSI-X interrupts are not delivered. ++ */ ++ bfa_ioc_msgflush(ioc); ++ ioc->cbfn->reset_cbfn(ioc->bfa); ++ bfa_fsm_send_event(ioc, IOC_E_FWREADY); ++ return; ++ } ++ ++ /** ++ * Initialize the h/w for any other states. ++ */ ++ bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); ++} ++ ++static void ++bfa_ioc_timeout(void *ioc_arg) ++{ ++ struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg; ++ ++ bfa_trc(ioc, 0); ++ bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); ++} ++ ++void ++bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len) ++{ ++ u32 *msgp = (u32 *) ioc_msg; ++ u32 i; ++ ++ bfa_trc(ioc, msgp[0]); ++ bfa_trc(ioc, len); ++ ++ bfa_assert(len <= BFI_IOC_MSGLEN_MAX); ++ ++ /* ++ * first write msg to mailbox registers ++ */ ++ for (i = 0; i < len / sizeof(u32); i++) ++ bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), ++ bfa_os_wtole(msgp[i])); ++ ++ for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) ++ bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0); ++ ++ /* ++ * write 1 to mailbox CMD to trigger LPU event ++ */ ++ bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1); ++ (void)bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd); ++} ++ ++static void ++bfa_ioc_send_enable(struct bfa_ioc_s *ioc) ++{ ++ struct bfi_ioc_ctrl_req_s enable_req; ++ ++ bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, ++ bfa_ioc_portid(ioc)); ++ enable_req.ioc_class = ioc->ioc_mc; ++ bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s)); ++} ++ ++static void ++bfa_ioc_send_disable(struct bfa_ioc_s *ioc) ++{ ++ struct bfi_ioc_ctrl_req_s disable_req; ++ ++ bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, ++ bfa_ioc_portid(ioc)); ++ bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s)); ++} ++ ++static void ++bfa_ioc_send_getattr(struct bfa_ioc_s *ioc) ++{ ++ struct bfi_ioc_getattr_req_s attr_req; ++ ++ bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, ++ bfa_ioc_portid(ioc)); ++ bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); ++ bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); ++} ++ ++static void ++bfa_ioc_hb_check(void *cbarg) ++{ ++ struct bfa_ioc_s *ioc = cbarg; ++ u32 hb_count; ++ ++ hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); ++ if (ioc->hb_count == hb_count) { ++ ioc->hb_fail++; ++ } else { ++ ioc->hb_count = hb_count; ++ ioc->hb_fail = 0; ++ } ++ ++ if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) { ++ bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count); ++ ioc->hb_fail = 0; ++ bfa_ioc_recover(ioc); ++ return; ++ } ++ ++ bfa_ioc_mbox_poll(ioc); ++ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, ++ BFA_IOC_HB_TOV); ++} ++ ++static void ++bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc) ++{ ++ ioc->hb_fail = 0; ++ ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat); ++ bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc, ++ BFA_IOC_HB_TOV); ++} ++ ++static void ++bfa_ioc_hb_stop(struct bfa_ioc_s *ioc) ++{ ++ bfa_timer_stop(&ioc->ioc_timer); ++} ++ ++/** ++ * Host to LPU mailbox message addresses ++ */ ++static struct { ++ u32 hfn_mbox, lpu_mbox, hfn_pgn; ++} iocreg_fnreg[] = { ++ { ++ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, { ++ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, { ++ HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, { ++ HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3} ++}; ++ ++/** ++ * Host <-> LPU mailbox command/status registers - port 0 ++ */ ++static struct { ++ u32 hfn, lpu; ++} iocreg_mbcmd_p0[] = { ++ { ++ HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, { ++ HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, { ++ HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, { ++ HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT} ++}; ++ ++/** ++ * Host <-> LPU mailbox command/status registers - port 1 ++ */ ++static struct { ++ u32 hfn, lpu; ++} iocreg_mbcmd_p1[] = { ++ { ++ HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, { ++ HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, { ++ HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, { ++ HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT} ++}; ++ ++/** ++ * Shared IRQ handling in INTX mode ++ */ ++static struct { ++ u32 isr, msk; ++} iocreg_shirq_next[] = { ++ { ++ HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, { ++ HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, { ++ HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, { ++HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},}; ++ ++static void ++bfa_ioc_reg_init(struct bfa_ioc_s *ioc) ++{ ++ bfa_os_addr_t rb; ++ int pcifn = bfa_ioc_pcifn(ioc); ++ ++ rb = bfa_ioc_bar0(ioc); ++ ++ ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; ++ ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; ++ ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; ++ ++ if (ioc->port_id == 0) { ++ ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; ++ ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; ++ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; ++ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; ++ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; ++ } else { ++ ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); ++ ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); ++ ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; ++ ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; ++ ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; ++ } ++ ++ /** ++ * Shared IRQ handling in INTX mode ++ */ ++ ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr; ++ ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk; ++ ++ /* ++ * PSS control registers ++ */ ++ ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); ++ ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); ++ ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); ++ ++ /* ++ * IOC semaphore registers and serialization ++ */ ++ ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); ++ ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); ++ ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); ++ ++ /** ++ * sram memory access ++ */ ++ ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); ++ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB; ++ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) ++ ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; ++} ++ ++/** ++ * Initiate a full firmware download. ++ */ ++static void ++bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type, ++ u32 boot_param) ++{ ++ u32 *fwimg; ++ u32 pgnum, pgoff; ++ u32 loff = 0; ++ u32 chunkno = 0; ++ u32 i; ++ ++ /** ++ * Initialize LMEM first before code download ++ */ ++ bfa_ioc_lmem_init(ioc); ++ ++ /** ++ * Flash based firmware boot ++ */ ++ bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc)); ++ if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ) ++ boot_type = BFI_BOOT_TYPE_FLASH; ++ fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno); ++ fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type); ++ fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] = ++ bfa_os_swap32(boot_param); ++ ++ pgnum = bfa_ioc_smem_pgnum(ioc, loff); ++ pgoff = bfa_ioc_smem_pgoff(ioc, loff); ++ ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); ++ ++ for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) { ++ ++ if (BFA_FLASH_CHUNK_NO(i) != chunkno) { ++ chunkno = BFA_FLASH_CHUNK_NO(i); ++ fwimg = bfa_ioc_fwimg_get_chunk(ioc, ++ BFA_FLASH_CHUNK_ADDR(chunkno)); ++ } ++ ++ /** ++ * write smem ++ */ ++ bfa_mem_write(ioc->ioc_regs.smem_page_start, loff, ++ fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]); ++ ++ loff += sizeof(u32); ++ ++ /** ++ * handle page offset wrap around ++ */ ++ loff = PSS_SMEM_PGOFF(loff); ++ if (loff == 0) { ++ pgnum++; ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); ++ } ++ } ++ ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, ++ bfa_ioc_smem_pgnum(ioc, 0)); ++} ++ ++static void ++bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force) ++{ ++ bfa_ioc_hwinit(ioc, force); ++} ++ ++/** ++ * Update BFA configuration from firmware configuration. ++ */ ++static void ++bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc) ++{ ++ struct bfi_ioc_attr_s *attr = ioc->attr; ++ ++ attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop); ++ attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize); ++ ++ bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); ++} ++ ++/** ++ * Attach time initialization of mbox logic. ++ */ ++static void ++bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ int mc; ++ ++ INIT_LIST_HEAD(&mod->cmd_q); ++ for (mc = 0; mc < BFI_MC_MAX; mc++) { ++ mod->mbhdlr[mc].cbfn = NULL; ++ mod->mbhdlr[mc].cbarg = ioc->bfa; ++ } ++} ++ ++/** ++ * Mbox poll timer -- restarts any pending mailbox requests. ++ */ ++static void ++bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ struct bfa_mbox_cmd_s *cmd; ++ u32 stat; ++ ++ /** ++ * If no command pending, do nothing ++ */ ++ if (list_empty(&mod->cmd_q)) ++ return; ++ ++ /** ++ * If previous command is not yet fetched by firmware, do nothing ++ */ ++ stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd); ++ if (stat) ++ return; ++ ++ /** ++ * Enqueue command to firmware. ++ */ ++ bfa_q_deq(&mod->cmd_q, &cmd); ++ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); ++} ++ ++/** ++ * Cleanup any pending requests. ++ */ ++static void ++bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ struct bfa_mbox_cmd_s *cmd; ++ ++ while (!list_empty(&mod->cmd_q)) ++ bfa_q_deq(&mod->cmd_q, &cmd); ++} ++ ++/** ++ * Initialize IOC to port mapping. ++ */ ++ ++#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) ++static void ++bfa_ioc_map_port(struct bfa_ioc_s *ioc) ++{ ++ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; ++ u32 r32; ++ ++ /** ++ * For crossbow, port id is same as pci function. ++ */ ++ if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) { ++ ioc->port_id = bfa_ioc_pcifn(ioc); ++ return; ++ } ++ ++ /** ++ * For catapult, base port id on personality register and IOC type ++ */ ++ r32 = bfa_reg_read(rb + FNC_PERS_REG); ++ r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); ++ ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; ++ ++ bfa_trc(ioc, bfa_ioc_pcifn(ioc)); ++ bfa_trc(ioc, ioc->port_id); ++} ++ ++ ++ ++/** ++ * bfa_ioc_public ++ */ ++ ++/** ++* Set interrupt mode for a function: INTX or MSIX ++ */ ++void ++bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) ++{ ++ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; ++ u32 r32, mode; ++ ++ r32 = bfa_reg_read(rb + FNC_PERS_REG); ++ bfa_trc(ioc, r32); ++ ++ mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & ++ __F0_INTX_STATUS; ++ ++ /** ++ * If already in desired mode, do not change anything ++ */ ++ if (!msix && mode) ++ return; ++ ++ if (msix) ++ mode = __F0_INTX_STATUS_MSIX; ++ else ++ mode = __F0_INTX_STATUS_INTA; ++ ++ r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); ++ r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); ++ bfa_trc(ioc, r32); ++ ++ bfa_reg_write(rb + FNC_PERS_REG, r32); ++} ++ ++bfa_status_t ++bfa_ioc_pll_init(struct bfa_ioc_s *ioc) ++{ ++ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; ++ u32 pll_sclk, pll_fclk, r32; ++ ++ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { ++ pll_sclk = ++ __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | ++ __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) | ++ __APP_PLL_312_JITLMT0_1(3U) | ++ __APP_PLL_312_CNTLMT0_1(1U); ++ pll_fclk = ++ __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | ++ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) | ++ __APP_PLL_425_JITLMT0_1(3U) | ++ __APP_PLL_425_CNTLMT0_1(1U); ++ ++ /** ++ * For catapult, choose operational mode FC/FCoE ++ */ ++ if (ioc->fcmode) { ++ bfa_reg_write((rb + OP_MODE), 0); ++ bfa_reg_write((rb + ETH_MAC_SER_REG), ++ __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 ++ | __APP_EMS_CHANNEL_SEL); ++ } else { ++ ioc->pllinit = BFA_TRUE; ++ bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE); ++ bfa_reg_write((rb + ETH_MAC_SER_REG), ++ __APP_EMS_REFCKBUFEN1); ++ } ++ } else { ++ pll_sclk = ++ __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN | ++ __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) | ++ __APP_PLL_312_CNTLMT0_1(3U); ++ pll_fclk = ++ __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN | ++ __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | ++ __APP_PLL_425_JITLMT0_1(3U) | ++ __APP_PLL_425_CNTLMT0_1(3U); ++ } ++ ++ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT); ++ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT); ++ ++ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU); ++ ++ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, ++ __APP_PLL_312_LOGIC_SOFT_RESET); ++ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, ++ __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET); ++ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, ++ __APP_PLL_425_LOGIC_SOFT_RESET); ++ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, ++ __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET); ++ bfa_os_udelay(2); ++ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, ++ __APP_PLL_312_LOGIC_SOFT_RESET); ++ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, ++ __APP_PLL_425_LOGIC_SOFT_RESET); ++ ++ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, ++ pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET); ++ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, ++ pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET); ++ ++ /** ++ * Wait for PLLs to lock. ++ */ ++ bfa_os_udelay(2000); ++ bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU); ++ bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU); ++ ++ bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk); ++ bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk); ++ ++ if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) { ++ bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START); ++ bfa_os_udelay(1000); ++ r32 = bfa_reg_read((rb + MBIST_STAT_REG)); ++ bfa_trc(ioc, r32); ++ } ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Interface used by diag module to do firmware boot with memory test ++ * as the entry vector. ++ */ ++void ++bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param) ++{ ++ bfa_os_addr_t rb; ++ ++ bfa_ioc_stats(ioc, ioc_boots); ++ ++ if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) ++ return; ++ ++ /** ++ * Initialize IOC state of all functions on a chip reset. ++ */ ++ rb = ioc->pcidev.pci_bar_kva; ++ if (boot_param == BFI_BOOT_TYPE_MEMTEST) { ++ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST); ++ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST); ++ } else { ++ bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING); ++ bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING); ++ } ++ ++ bfa_ioc_download_fw(ioc, boot_type, boot_param); ++ ++ /** ++ * Enable interrupts just before starting LPU ++ */ ++ ioc->cbfn->reset_cbfn(ioc->bfa); ++ bfa_ioc_lpu_start(ioc); ++} ++ ++/** ++ * Enable/disable IOC failure auto recovery. ++ */ ++void ++bfa_ioc_auto_recover(bfa_boolean_t auto_recover) ++{ ++ bfa_auto_recover = BFA_FALSE; ++} ++ ++ ++bfa_boolean_t ++bfa_ioc_is_operational(struct bfa_ioc_s *ioc) ++{ ++ return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op); ++} ++ ++void ++bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg) ++{ ++ u32 *msgp = mbmsg; ++ u32 r32; ++ int i; ++ ++ /** ++ * read the MBOX msg ++ */ ++ for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); ++ i++) { ++ r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox + ++ i * sizeof(u32)); ++ msgp[i] = bfa_os_htonl(r32); ++ } ++ ++ /** ++ * turn off mailbox interrupt by clearing mailbox status ++ */ ++ bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1); ++ bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd); ++} ++ ++void ++bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m) ++{ ++ union bfi_ioc_i2h_msg_u *msg; ++ ++ msg = (union bfi_ioc_i2h_msg_u *)m; ++ ++ bfa_ioc_stats(ioc, ioc_isrs); ++ ++ switch (msg->mh.msg_id) { ++ case BFI_IOC_I2H_HBEAT: ++ break; ++ ++ case BFI_IOC_I2H_READY_EVENT: ++ bfa_fsm_send_event(ioc, IOC_E_FWREADY); ++ break; ++ ++ case BFI_IOC_I2H_ENABLE_REPLY: ++ bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE); ++ break; ++ ++ case BFI_IOC_I2H_DISABLE_REPLY: ++ bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE); ++ break; ++ ++ case BFI_IOC_I2H_GETATTR_REPLY: ++ bfa_ioc_getattr_reply(ioc); ++ break; ++ ++ default: ++ bfa_trc(ioc, msg->mh.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IOC attach time initialization and setup. ++ * ++ * @param[in] ioc memory for IOC ++ * @param[in] bfa driver instance structure ++ * @param[in] trcmod kernel trace module ++ * @param[in] aen kernel aen event module ++ * @param[in] logm kernel logging module ++ */ ++void ++bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn, ++ struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod, ++ struct bfa_aen_s *aen, struct bfa_log_mod_s *logm) ++{ ++ ioc->bfa = bfa; ++ ioc->cbfn = cbfn; ++ ioc->timer_mod = timer_mod; ++ ioc->trcmod = trcmod; ++ ioc->aen = aen; ++ ioc->logm = logm; ++ ioc->fcmode = BFA_FALSE; ++ ioc->pllinit = BFA_FALSE; ++ ioc->dbg_fwsave_once = BFA_TRUE; ++ ++ bfa_ioc_mbox_attach(ioc); ++ INIT_LIST_HEAD(&ioc->hb_notify_q); ++ ++ bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); ++} ++ ++/** ++ * Driver detach time IOC cleanup. ++ */ ++void ++bfa_ioc_detach(struct bfa_ioc_s *ioc) ++{ ++ bfa_fsm_send_event(ioc, IOC_E_DETACH); ++} ++ ++/** ++ * Setup IOC PCI properties. ++ * ++ * @param[in] pcidev PCI device information for this IOC ++ */ ++void ++bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, ++ enum bfi_mclass mc) ++{ ++ ioc->ioc_mc = mc; ++ ioc->pcidev = *pcidev; ++ ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT); ++ ioc->cna = ioc->ctdev && !ioc->fcmode; ++ ++ bfa_ioc_map_port(ioc); ++ bfa_ioc_reg_init(ioc); ++} ++ ++/** ++ * Initialize IOC dma memory ++ * ++ * @param[in] dm_kva kernel virtual address of IOC dma memory ++ * @param[in] dm_pa physical address of IOC dma memory ++ */ ++void ++bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa) ++{ ++ /** ++ * dma memory for firmware attribute ++ */ ++ ioc->attr_dma.kva = dm_kva; ++ ioc->attr_dma.pa = dm_pa; ++ ioc->attr = (struct bfi_ioc_attr_s *)dm_kva; ++} ++ ++/** ++ * Return size of dma memory required. ++ */ ++u32 ++bfa_ioc_meminfo(void) ++{ ++ return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ); ++} ++ ++void ++bfa_ioc_enable(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_stats(ioc, ioc_enables); ++ ioc->dbg_fwsave_once = BFA_TRUE; ++ ++ bfa_fsm_send_event(ioc, IOC_E_ENABLE); ++} ++ ++void ++bfa_ioc_disable(struct bfa_ioc_s *ioc) ++{ ++ bfa_ioc_stats(ioc, ioc_disables); ++ bfa_fsm_send_event(ioc, IOC_E_DISABLE); ++} ++ ++/** ++ * Returns memory required for saving firmware trace in case of crash. ++ * Driver must call this interface to allocate memory required for ++ * automatic saving of firmware trace. Driver should call ++ * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this ++ * trace memory. ++ */ ++int ++bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover) ++{ ++return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0; ++} ++ ++/** ++ * Initialize memory for saving firmware trace. Driver must initialize ++ * trace memory before call bfa_ioc_enable(). ++ */ ++void ++bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave) ++{ ++ bfa_assert(ioc->auto_recover); ++ ioc->dbg_fwsave = dbg_fwsave; ++ ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover); ++} ++ ++u32 ++bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr) ++{ ++ return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); ++} ++ ++u32 ++bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr) ++{ ++ return PSS_SMEM_PGOFF(fmaddr); ++} ++ ++/** ++ * Register mailbox message handler functions ++ * ++ * @param[in] ioc IOC instance ++ * @param[in] mcfuncs message class handler functions ++ */ ++void ++bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ int mc; ++ ++ for (mc = 0; mc < BFI_MC_MAX; mc++) ++ mod->mbhdlr[mc].cbfn = mcfuncs[mc]; ++} ++ ++/** ++ * Register mailbox message handler function, to be called by common modules ++ */ ++void ++bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, ++ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ ++ mod->mbhdlr[mc].cbfn = cbfn; ++ mod->mbhdlr[mc].cbarg = cbarg; ++} ++ ++/** ++ * Queue a mailbox command request to firmware. Waits if mailbox is busy. ++ * Responsibility of caller to serialize ++ * ++ * @param[in] ioc IOC instance ++ * @param[i] cmd Mailbox command ++ */ ++void ++bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ u32 stat; ++ ++ /** ++ * If a previous command is pending, queue new command ++ */ ++ if (!list_empty(&mod->cmd_q)) { ++ list_add_tail(&cmd->qe, &mod->cmd_q); ++ return; ++ } ++ ++ /** ++ * If mailbox is busy, queue command for poll timer ++ */ ++ stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd); ++ if (stat) { ++ list_add_tail(&cmd->qe, &mod->cmd_q); ++ return; ++ } ++ ++ /** ++ * mailbox is free -- queue command to firmware ++ */ ++ bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); ++} ++ ++/** ++ * Handle mailbox interrupts ++ */ ++void ++bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc) ++{ ++ struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod; ++ struct bfi_mbmsg_s m; ++ int mc; ++ ++ bfa_ioc_msgget(ioc, &m); ++ ++ /** ++ * Treat IOC message class as special. ++ */ ++ mc = m.mh.msg_class; ++ if (mc == BFI_MC_IOC) { ++ bfa_ioc_isr(ioc, &m); ++ return; ++ } ++ ++ if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) ++ return; ++ ++ mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); ++} ++ ++void ++bfa_ioc_error_isr(struct bfa_ioc_s *ioc) ++{ ++ bfa_fsm_send_event(ioc, IOC_E_HWERROR); ++} ++ ++#ifndef BFA_BIOS_BUILD ++ ++/** ++ * return true if IOC is disabled ++ */ ++bfa_boolean_t ++bfa_ioc_is_disabled(struct bfa_ioc_s *ioc) ++{ ++ return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling) ++ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)); ++} ++ ++/** ++ * return true if IOC firmware is different. ++ */ ++bfa_boolean_t ++bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc) ++{ ++ return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset) ++ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck) ++ || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch)); ++} ++ ++#define bfa_ioc_state_disabled(__sm) \ ++ (((__sm) == BFI_IOC_UNINIT) || \ ++ ((__sm) == BFI_IOC_INITING) || \ ++ ((__sm) == BFI_IOC_HWINIT) || \ ++ ((__sm) == BFI_IOC_DISABLED) || \ ++ ((__sm) == BFI_IOC_HBFAIL) || \ ++ ((__sm) == BFI_IOC_CFG_DISABLED)) ++ ++/** ++ * Check if adapter is disabled -- both IOCs should be in a disabled ++ * state. ++ */ ++bfa_boolean_t ++bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc) ++{ ++ u32 ioc_state; ++ bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva; ++ ++ if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled)) ++ return BFA_FALSE; ++ ++ ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG); ++ if (!bfa_ioc_state_disabled(ioc_state)) ++ return BFA_FALSE; ++ ++ ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG); ++ if (!bfa_ioc_state_disabled(ioc_state)) ++ return BFA_FALSE; ++ ++ return BFA_TRUE; ++} ++ ++/** ++ * Add to IOC heartbeat failure notification queue. To be used by common ++ * modules such as ++ */ ++void ++bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, ++ struct bfa_ioc_hbfail_notify_s *notify) ++{ ++ list_add_tail(¬ify->qe, &ioc->hb_notify_q); ++} ++ ++#define BFA_MFG_NAME "Brocade" ++void ++bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, ++ struct bfa_adapter_attr_s *ad_attr) ++{ ++ struct bfi_ioc_attr_s *ioc_attr; ++ char model[BFA_ADAPTER_MODEL_NAME_LEN]; ++ ++ ioc_attr = ioc->attr; ++ bfa_os_memcpy((void *)&ad_attr->serial_num, ++ (void *)ioc_attr->brcd_serialnum, ++ BFA_ADAPTER_SERIAL_NUM_LEN); ++ ++ bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN); ++ bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version, ++ BFA_VERSION_LEN); ++ bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME, ++ BFA_ADAPTER_MFG_NAME_LEN); ++ bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd, ++ sizeof(struct bfa_mfg_vpd_s)); ++ ++ ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop); ++ ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); ++ ++ /** ++ * model name ++ */ ++ if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) { ++ strcpy(model, "BR-10?0"); ++ model[5] = '0' + ad_attr->nports; ++ } else { ++ strcpy(model, "Brocade-??5"); ++ model[8] = ++ '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop); ++ model[9] = '0' + ad_attr->nports; ++ } ++ ++ if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) ++ ad_attr->prototype = 1; ++ else ++ ad_attr->prototype = 0; ++ ++ bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN); ++ bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model, ++ BFA_ADAPTER_MODEL_NAME_LEN); ++ ++ ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); ++ ad_attr->mac = bfa_ioc_get_mac(ioc); ++ ++ ad_attr->pcie_gen = ioc_attr->pcie_gen; ++ ad_attr->pcie_lanes = ioc_attr->pcie_lanes; ++ ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; ++ ad_attr->asic_rev = ioc_attr->asic_rev; ++ ad_attr->hw_ver[0] = 'R'; ++ ad_attr->hw_ver[1] = 'e'; ++ ad_attr->hw_ver[2] = 'v'; ++ ad_attr->hw_ver[3] = '-'; ++ ad_attr->hw_ver[4] = ioc_attr->asic_rev; ++ ad_attr->hw_ver[5] = '\0'; ++ ++ ad_attr->cna_capable = ioc->cna; ++} ++ ++void ++bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr) ++{ ++ bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s)); ++ ++ ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm); ++ ioc_attr->port_id = ioc->port_id; ++ ++ if (!ioc->ctdev) ++ ioc_attr->ioc_type = BFA_IOC_TYPE_FC; ++ else if (ioc->ioc_mc == BFI_MC_IOCFC) ++ ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE; ++ else if (ioc->ioc_mc == BFI_MC_LL) ++ ioc_attr->ioc_type = BFA_IOC_TYPE_LL; ++ ++ bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); ++ ++ ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; ++ ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; ++ ioc_attr->pci_attr.chip_rev[0] = 'R'; ++ ioc_attr->pci_attr.chip_rev[1] = 'e'; ++ ioc_attr->pci_attr.chip_rev[2] = 'v'; ++ ioc_attr->pci_attr.chip_rev[3] = '-'; ++ ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev; ++ ioc_attr->pci_attr.chip_rev[5] = '\0'; ++} ++ ++/** ++ * hal_wwn_public ++ */ ++wwn_t ++bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc) ++{ ++ union { ++ wwn_t wwn; ++ u8 byte[sizeof(wwn_t)]; ++ } ++ w; ++ ++ w.wwn = ioc->attr->mfg_wwn; ++ ++ if (bfa_ioc_portid(ioc) == 1) ++ w.byte[7]++; ++ ++ return w.wwn; ++} ++ ++wwn_t ++bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc) ++{ ++ union { ++ wwn_t wwn; ++ u8 byte[sizeof(wwn_t)]; ++ } ++ w; ++ ++ w.wwn = ioc->attr->mfg_wwn; ++ ++ if (bfa_ioc_portid(ioc) == 1) ++ w.byte[7]++; ++ ++ w.byte[0] = 0x20; ++ ++ return w.wwn; ++} ++ ++wwn_t ++bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst) ++{ ++ union { ++ wwn_t wwn; ++ u8 byte[sizeof(wwn_t)]; ++ } ++ w , w5; ++ ++ bfa_trc(ioc, inst); ++ ++ w.wwn = ioc->attr->mfg_wwn; ++ w5.byte[0] = 0x50 | w.byte[2] >> 4; ++ w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4; ++ w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4; ++ w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4; ++ w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4; ++ w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4; ++ w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8; ++ w5.byte[7] = (inst & 0xff); ++ ++ return w5.wwn; ++} ++ ++u64 ++bfa_ioc_get_adid(struct bfa_ioc_s *ioc) ++{ ++ return ioc->attr->mfg_wwn; ++} ++ ++mac_t ++bfa_ioc_get_mac(struct bfa_ioc_s *ioc) ++{ ++ mac_t mac; ++ ++ mac = ioc->attr->mfg_mac; ++ mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); ++ ++ return mac; ++} ++ ++void ++bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc) ++{ ++ ioc->fcmode = BFA_TRUE; ++ ioc->port_id = bfa_ioc_pcifn(ioc); ++} ++ ++bfa_boolean_t ++bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc) ++{ ++ return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT); ++} ++ ++/** ++ * Return true if interrupt should be claimed. ++ */ ++bfa_boolean_t ++bfa_ioc_intx_claim(struct bfa_ioc_s *ioc) ++{ ++ u32 isr, msk; ++ ++ /** ++ * Always claim if not catapult. ++ */ ++ if (!ioc->ctdev) ++ return BFA_TRUE; ++ ++ /** ++ * FALSE if next device is claiming interrupt. ++ * TRUE if next device is not interrupting or not present. ++ */ ++ msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next); ++ isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next); ++ return !(isr & ~msk); ++} ++ ++/** ++ * Send AEN notification ++ */ ++static void ++bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = ioc->logm; ++ s32 inst_num = 0; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ switch (event) { ++ case BFA_IOC_AEN_HBGOOD: ++ bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num); ++ break; ++ case BFA_IOC_AEN_HBFAIL: ++ bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num); ++ break; ++ case BFA_IOC_AEN_ENABLE: ++ bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num); ++ break; ++ case BFA_IOC_AEN_DISABLE: ++ bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num); ++ break; ++ case BFA_IOC_AEN_FWMISMATCH: ++ bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num); ++ break; ++ default: ++ break; ++ } ++ ++ memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn)); ++ memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac)); ++ bfa_ioc_get_attr(ioc, &ioc_attr); ++ switch (ioc_attr.ioc_type) { ++ case BFA_IOC_TYPE_FC: ++ aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); ++ break; ++ case BFA_IOC_TYPE_FCoE: ++ aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc); ++ aen_data.ioc.mac = bfa_ioc_get_mac(ioc); ++ break; ++ case BFA_IOC_TYPE_LL: ++ aen_data.ioc.mac = bfa_ioc_get_mac(ioc); ++ break; ++ default: ++ bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC); ++ break; ++ } ++ aen_data.ioc.ioc_type = ioc_attr.ioc_type; ++} ++ ++/** ++ * Retrieve saved firmware trace from a prior IOC failure. ++ */ ++bfa_status_t ++bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) ++{ ++ int tlen; ++ ++ if (ioc->dbg_fwsave_len == 0) ++ return BFA_STATUS_ENOFSAVE; ++ ++ tlen = *trclen; ++ if (tlen > ioc->dbg_fwsave_len) ++ tlen = ioc->dbg_fwsave_len; ++ ++ bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen); ++ *trclen = tlen; ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Retrieve saved firmware trace from a prior IOC failure. ++ */ ++bfa_status_t ++bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen) ++{ ++ u32 pgnum; ++ u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc)); ++ int i, tlen; ++ u32 *tbuf = trcdata, r32; ++ ++ bfa_trc(ioc, *trclen); ++ ++ pgnum = bfa_ioc_smem_pgnum(ioc, loff); ++ loff = bfa_ioc_smem_pgoff(ioc, loff); ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); ++ ++ tlen = *trclen; ++ if (tlen > BFA_DBG_FWTRC_LEN) ++ tlen = BFA_DBG_FWTRC_LEN; ++ tlen /= sizeof(u32); ++ ++ bfa_trc(ioc, tlen); ++ ++ for (i = 0; i < tlen; i++) { ++ r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff); ++ tbuf[i] = bfa_os_ntohl(r32); ++ loff += sizeof(u32); ++ ++ /** ++ * handle page offset wrap around ++ */ ++ loff = PSS_SMEM_PGOFF(loff); ++ if (loff == 0) { ++ pgnum++; ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum); ++ } ++ } ++ bfa_reg_write(ioc->ioc_regs.host_page_num_fn, ++ bfa_ioc_smem_pgnum(ioc, 0)); ++ bfa_trc(ioc, pgnum); ++ ++ *trclen = tlen * sizeof(u32); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Save firmware trace if configured. ++ */ ++static void ++bfa_ioc_debug_save(struct bfa_ioc_s *ioc) ++{ ++ int tlen; ++ ++ if (ioc->dbg_fwsave_len) { ++ tlen = ioc->dbg_fwsave_len; ++ bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); ++ } ++} ++ ++/** ++ * Firmware failure detected. Start recovery actions. ++ */ ++static void ++bfa_ioc_recover(struct bfa_ioc_s *ioc) ++{ ++ if (ioc->dbg_fwsave_once) { ++ ioc->dbg_fwsave_once = BFA_FALSE; ++ bfa_ioc_debug_save(ioc); ++ } ++ ++ bfa_ioc_stats(ioc, ioc_hbfails); ++ bfa_fsm_send_event(ioc, IOC_E_HBFAIL); ++} ++ ++#else ++ ++static void ++bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event) ++{ ++} ++ ++static void ++bfa_ioc_recover(struct bfa_ioc_s *ioc) ++{ ++ bfa_assert(0); ++} ++ ++#endif ++ ++ +diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h +new file mode 100644 +index 0000000..58efd4b +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_ioc.h +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_IOC_H__ ++#define __BFA_IOC_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * PCI device information required by IOC ++ */ ++struct bfa_pcidev_s { ++ int pci_slot; ++ u8 pci_func; ++ u16 device_id; ++ bfa_os_addr_t pci_bar_kva; ++}; ++ ++/** ++ * Structure used to remember the DMA-able memory block's KVA and Physical ++ * Address ++ */ ++struct bfa_dma_s { ++ void *kva; /*! Kernel virtual address */ ++ u64 pa; /*! Physical address */ ++}; ++ ++#define BFA_DMA_ALIGN_SZ 256 ++#define BFA_ROUNDUP(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1)) ++ ++ ++ ++#define bfa_dma_addr_set(dma_addr, pa) \ ++ __bfa_dma_addr_set(&dma_addr, (u64)pa) ++ ++static inline void ++__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa) ++{ ++ dma_addr->a32.addr_lo = (u32) pa; ++ dma_addr->a32.addr_hi = (u32) (bfa_os_u32(pa)); ++} ++ ++ ++#define bfa_dma_be_addr_set(dma_addr, pa) \ ++ __bfa_dma_be_addr_set(&dma_addr, (u64)pa) ++static inline void ++__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa) ++{ ++ dma_addr->a32.addr_lo = (u32) bfa_os_htonl(pa); ++ dma_addr->a32.addr_hi = (u32) bfa_os_htonl(bfa_os_u32(pa)); ++} ++ ++struct bfa_ioc_regs_s { ++ bfa_os_addr_t hfn_mbox_cmd; ++ bfa_os_addr_t hfn_mbox; ++ bfa_os_addr_t lpu_mbox_cmd; ++ bfa_os_addr_t lpu_mbox; ++ bfa_os_addr_t pss_ctl_reg; ++ bfa_os_addr_t app_pll_fast_ctl_reg; ++ bfa_os_addr_t app_pll_slow_ctl_reg; ++ bfa_os_addr_t ioc_sem_reg; ++ bfa_os_addr_t ioc_usage_sem_reg; ++ bfa_os_addr_t ioc_usage_reg; ++ bfa_os_addr_t host_page_num_fn; ++ bfa_os_addr_t heartbeat; ++ bfa_os_addr_t ioc_fwstate; ++ bfa_os_addr_t ll_halt; ++ bfa_os_addr_t shirq_isr_next; ++ bfa_os_addr_t shirq_msk_next; ++ bfa_os_addr_t smem_page_start; ++ u32 smem_pg0; ++}; ++ ++#define bfa_reg_read(_raddr) bfa_os_reg_read(_raddr) ++#define bfa_reg_write(_raddr, _val) bfa_os_reg_write(_raddr, _val) ++#define bfa_mem_read(_raddr, _off) bfa_os_mem_read(_raddr, _off) ++#define bfa_mem_write(_raddr, _off, _val) \ ++ bfa_os_mem_write(_raddr, _off, _val) ++/** ++ * IOC Mailbox structures ++ */ ++struct bfa_mbox_cmd_s { ++ struct list_head qe; ++ u32 msg[BFI_IOC_MSGSZ]; ++}; ++ ++/** ++ * IOC mailbox module ++ */ ++typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg_s *m); ++struct bfa_ioc_mbox_mod_s { ++ struct list_head cmd_q; /* pending mbox queue */ ++ int nmclass; /* number of handlers */ ++ struct { ++ bfa_ioc_mbox_mcfunc_t cbfn; /* message handlers */ ++ void *cbarg; ++ } mbhdlr[BFI_MC_MAX]; ++}; ++ ++/** ++ * IOC callback function interfaces ++ */ ++typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status); ++typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa); ++typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa); ++typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa); ++struct bfa_ioc_cbfn_s { ++ bfa_ioc_enable_cbfn_t enable_cbfn; ++ bfa_ioc_disable_cbfn_t disable_cbfn; ++ bfa_ioc_hbfail_cbfn_t hbfail_cbfn; ++ bfa_ioc_reset_cbfn_t reset_cbfn; ++}; ++ ++/** ++ * Heartbeat failure notification queue element. ++ */ ++struct bfa_ioc_hbfail_notify_s { ++ struct list_head qe; ++ bfa_ioc_hbfail_cbfn_t cbfn; ++ void *cbarg; ++}; ++ ++/** ++ * Initialize a heartbeat failure notification structure ++ */ ++#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \ ++ (__notify)->cbfn = (__cbfn); \ ++ (__notify)->cbarg = (__cbarg); \ ++} while (0) ++ ++struct bfa_ioc_s { ++ bfa_fsm_t fsm; ++ struct bfa_s *bfa; ++ struct bfa_pcidev_s pcidev; ++ struct bfa_timer_mod_s *timer_mod; ++ struct bfa_timer_s ioc_timer; ++ struct bfa_timer_s sem_timer; ++ u32 hb_count; ++ u32 hb_fail; ++ u32 retry_count; ++ struct list_head hb_notify_q; ++ void *dbg_fwsave; ++ int dbg_fwsave_len; ++ bfa_boolean_t dbg_fwsave_once; ++ enum bfi_mclass ioc_mc; ++ struct bfa_ioc_regs_s ioc_regs; ++ struct bfa_trc_mod_s *trcmod; ++ struct bfa_aen_s *aen; ++ struct bfa_log_mod_s *logm; ++ struct bfa_ioc_drv_stats_s stats; ++ bfa_boolean_t auto_recover; ++ bfa_boolean_t fcmode; ++ bfa_boolean_t ctdev; ++ bfa_boolean_t cna; ++ bfa_boolean_t pllinit; ++ u8 port_id; ++ ++ struct bfa_dma_s attr_dma; ++ struct bfi_ioc_attr_s *attr; ++ struct bfa_ioc_cbfn_s *cbfn; ++ struct bfa_ioc_mbox_mod_s mbox_mod; ++}; ++ ++#define bfa_ioc_pcifn(__ioc) (__ioc)->pcidev.pci_func ++#define bfa_ioc_devid(__ioc) (__ioc)->pcidev.device_id ++#define bfa_ioc_bar0(__ioc) (__ioc)->pcidev.pci_bar_kva ++#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) ++#define bfa_ioc_fetch_stats(__ioc, __stats) \ ++ ((__stats)->drv_stats) = (__ioc)->stats ++#define bfa_ioc_clr_stats(__ioc) \ ++ bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats)) ++#define bfa_ioc_maxfrsize(__ioc) (__ioc)->attr->maxfrsize ++#define bfa_ioc_rx_bbcredit(__ioc) (__ioc)->attr->rx_bbcredit ++#define bfa_ioc_speed_sup(__ioc) \ ++ BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) ++ ++/** ++ * IOC mailbox interface ++ */ ++void bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd); ++void bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, ++ bfa_ioc_mbox_mcfunc_t *mcfuncs); ++void bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc); ++void bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len); ++void bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg); ++void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc, ++ bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg); ++ ++/** ++ * IOC interfaces ++ */ ++void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, ++ struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod, ++ struct bfa_trc_mod_s *trcmod, ++ struct bfa_aen_s *aen, struct bfa_log_mod_s *logm); ++void bfa_ioc_detach(struct bfa_ioc_s *ioc); ++void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev, ++ enum bfi_mclass mc); ++u32 bfa_ioc_meminfo(void); ++void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa); ++void bfa_ioc_enable(struct bfa_ioc_s *ioc); ++void bfa_ioc_disable(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc); ++ ++void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param); ++void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg); ++void bfa_ioc_error_isr(struct bfa_ioc_s *ioc); ++void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx); ++bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc); ++void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc); ++void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr); ++void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc, ++ struct bfa_adapter_attr_s *ad_attr); ++int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover); ++void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave); ++bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, ++ int *trclen); ++bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, ++ int *trclen); ++u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr); ++u32 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr); ++void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc); ++bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc); ++void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc, ++ struct bfa_ioc_hbfail_notify_s *notify); ++ ++/* ++ * bfa mfg wwn API functions ++ */ ++wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc); ++wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc); ++wwn_t bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst); ++mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc); ++u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc); ++ ++#endif /* __BFA_IOC_H__ */ ++ +diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c +new file mode 100644 +index 0000000..12350b0 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_iocfc.c +@@ -0,0 +1,872 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfa_callback_priv.h" ++#include "bfad_drv.h" ++ ++BFA_TRC_FILE(HAL, IOCFC); ++ ++/** ++ * IOC local definitions ++ */ ++#define BFA_IOCFC_TOV 5000 /* msecs */ ++ ++enum { ++ BFA_IOCFC_ACT_NONE = 0, ++ BFA_IOCFC_ACT_INIT = 1, ++ BFA_IOCFC_ACT_STOP = 2, ++ BFA_IOCFC_ACT_DISABLE = 3, ++}; ++ ++/* ++ * forward declarations ++ */ ++static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status); ++static void bfa_iocfc_disable_cbfn(void *bfa_arg); ++static void bfa_iocfc_hbfail_cbfn(void *bfa_arg); ++static void bfa_iocfc_reset_cbfn(void *bfa_arg); ++static void bfa_iocfc_stats_clear(void *bfa_arg); ++static void bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d, ++ struct bfa_fw_stats_s *s); ++static void bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete); ++static void bfa_iocfc_stats_clr_timeout(void *bfa_arg); ++static void bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete); ++static void bfa_iocfc_stats_timeout(void *bfa_arg); ++ ++static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn; ++ ++/** ++ * bfa_ioc_pvt BFA IOC private functions ++ */ ++ ++static void ++bfa_iocfc_cqs_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len) ++{ ++ int i, per_reqq_sz, per_rspq_sz; ++ ++ per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ), ++ BFA_DMA_ALIGN_SZ); ++ per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ), ++ BFA_DMA_ALIGN_SZ); ++ ++ /* ++ * Calculate CQ size ++ */ ++ for (i = 0; i < cfg->fwcfg.num_cqs; i++) { ++ *dm_len = *dm_len + per_reqq_sz; ++ *dm_len = *dm_len + per_rspq_sz; ++ } ++ ++ /* ++ * Calculate Shadow CI/PI size ++ */ ++ for (i = 0; i < cfg->fwcfg.num_cqs; i++) ++ *dm_len += (2 * BFA_CACHELINE_SZ); ++} ++ ++static void ++bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len) ++{ ++ *dm_len += ++ BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ); ++ *dm_len += ++ BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s), ++ BFA_CACHELINE_SZ); ++ *dm_len += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ); ++} ++ ++/** ++ * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ ++ */ ++static void ++bfa_iocfc_send_cfg(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_cfg_req_s cfg_req; ++ struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo; ++ struct bfa_iocfc_cfg_s *cfg = &iocfc->cfg; ++ int i; ++ ++ bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS); ++ bfa_trc(bfa, cfg->fwcfg.num_cqs); ++ ++ iocfc->cfgdone = BFA_FALSE; ++ bfa_iocfc_reset_queues(bfa); ++ ++ /** ++ * initialize IOC configuration info ++ */ ++ cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG; ++ cfg_info->num_cqs = cfg->fwcfg.num_cqs; ++ ++ bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa); ++ bfa_dma_be_addr_set(cfg_info->stats_addr, iocfc->stats_pa); ++ ++ /** ++ * dma map REQ and RSP circular queues and shadow pointers ++ */ ++ for (i = 0; i < cfg->fwcfg.num_cqs; i++) { ++ bfa_dma_be_addr_set(cfg_info->req_cq_ba[i], ++ iocfc->req_cq_ba[i].pa); ++ bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i], ++ iocfc->req_cq_shadow_ci[i].pa); ++ cfg_info->req_cq_elems[i] = ++ bfa_os_htons(cfg->drvcfg.num_reqq_elems); ++ ++ bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i], ++ iocfc->rsp_cq_ba[i].pa); ++ bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i], ++ iocfc->rsp_cq_shadow_pi[i].pa); ++ cfg_info->rsp_cq_elems[i] = ++ bfa_os_htons(cfg->drvcfg.num_rspq_elems); ++ } ++ ++ /** ++ * dma map IOC configuration itself ++ */ ++ bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ, ++ bfa_lpuid(bfa)); ++ bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa); ++ ++ bfa_ioc_mbox_send(&bfa->ioc, &cfg_req, ++ sizeof(struct bfi_iocfc_cfg_req_s)); ++} ++ ++static void ++bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ bfa->bfad = bfad; ++ iocfc->bfa = bfa; ++ iocfc->action = BFA_IOCFC_ACT_NONE; ++ ++ bfa_os_assign(iocfc->cfg, *cfg); ++ ++ /** ++ * Initialize chip specific handlers. ++ */ ++ if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { ++ iocfc->hwif.hw_reginit = bfa_hwct_reginit; ++ iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; ++ iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; ++ iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; ++ iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall; ++ iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set; ++ iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; ++ } else { ++ iocfc->hwif.hw_reginit = bfa_hwcb_reginit; ++ iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; ++ iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; ++ iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; ++ iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall; ++ iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set; ++ iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs; ++ } ++ ++ iocfc->hwif.hw_reginit(bfa); ++ bfa->msix.nvecs = 0; ++} ++ ++static void ++bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo) ++{ ++ u8 *dm_kva; ++ u64 dm_pa; ++ int i, per_reqq_sz, per_rspq_sz; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ int dbgsz; ++ ++ dm_kva = bfa_meminfo_dma_virt(meminfo); ++ dm_pa = bfa_meminfo_dma_phys(meminfo); ++ ++ /* ++ * First allocate dma memory for IOC. ++ */ ++ bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa); ++ dm_kva += bfa_ioc_meminfo(); ++ dm_pa += bfa_ioc_meminfo(); ++ ++ /* ++ * Claim DMA-able memory for the request/response queues and for shadow ++ * ci/pi registers ++ */ ++ per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ), ++ BFA_DMA_ALIGN_SZ); ++ per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ), ++ BFA_DMA_ALIGN_SZ); ++ ++ for (i = 0; i < cfg->fwcfg.num_cqs; i++) { ++ iocfc->req_cq_ba[i].kva = dm_kva; ++ iocfc->req_cq_ba[i].pa = dm_pa; ++ bfa_os_memset(dm_kva, 0, per_reqq_sz); ++ dm_kva += per_reqq_sz; ++ dm_pa += per_reqq_sz; ++ ++ iocfc->rsp_cq_ba[i].kva = dm_kva; ++ iocfc->rsp_cq_ba[i].pa = dm_pa; ++ bfa_os_memset(dm_kva, 0, per_rspq_sz); ++ dm_kva += per_rspq_sz; ++ dm_pa += per_rspq_sz; ++ } ++ ++ for (i = 0; i < cfg->fwcfg.num_cqs; i++) { ++ iocfc->req_cq_shadow_ci[i].kva = dm_kva; ++ iocfc->req_cq_shadow_ci[i].pa = dm_pa; ++ dm_kva += BFA_CACHELINE_SZ; ++ dm_pa += BFA_CACHELINE_SZ; ++ ++ iocfc->rsp_cq_shadow_pi[i].kva = dm_kva; ++ iocfc->rsp_cq_shadow_pi[i].pa = dm_pa; ++ dm_kva += BFA_CACHELINE_SZ; ++ dm_pa += BFA_CACHELINE_SZ; ++ } ++ ++ /* ++ * Claim DMA-able memory for the config info page ++ */ ++ bfa->iocfc.cfg_info.kva = dm_kva; ++ bfa->iocfc.cfg_info.pa = dm_pa; ++ bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva; ++ dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ); ++ dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ); ++ ++ /* ++ * Claim DMA-able memory for the config response ++ */ ++ bfa->iocfc.cfgrsp_dma.kva = dm_kva; ++ bfa->iocfc.cfgrsp_dma.pa = dm_pa; ++ bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva; ++ ++ dm_kva += ++ BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s), ++ BFA_CACHELINE_SZ); ++ dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s), ++ BFA_CACHELINE_SZ); ++ ++ /* ++ * Claim DMA-able memory for iocfc stats ++ */ ++ bfa->iocfc.stats_kva = dm_kva; ++ bfa->iocfc.stats_pa = dm_pa; ++ bfa->iocfc.fw_stats = (struct bfa_fw_stats_s *) dm_kva; ++ dm_kva += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ); ++ dm_pa += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ); ++ ++ bfa_meminfo_dma_virt(meminfo) = dm_kva; ++ bfa_meminfo_dma_phys(meminfo) = dm_pa; ++ ++ dbgsz = bfa_ioc_debug_trcsz(bfa_auto_recover); ++ if (dbgsz > 0) { ++ bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo)); ++ bfa_meminfo_kva(meminfo) += dbgsz; ++ } ++} ++ ++/** ++ * BFA submodules initialization completion notification. ++ */ ++static void ++bfa_iocfc_initdone_submod(struct bfa_s *bfa) ++{ ++ int i; ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->initdone(bfa); ++} ++ ++/** ++ * Start BFA submodules. ++ */ ++static void ++bfa_iocfc_start_submod(struct bfa_s *bfa) ++{ ++ int i; ++ ++ bfa->rme_process = BFA_TRUE; ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->start(bfa); ++} ++ ++/** ++ * Disable BFA submodules. ++ */ ++static void ++bfa_iocfc_disable_submod(struct bfa_s *bfa) ++{ ++ int i; ++ ++ for (i = 0; hal_mods[i]; i++) ++ hal_mods[i]->iocdisable(bfa); ++} ++ ++static void ++bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ ++ if (complete) { ++ if (bfa->iocfc.cfgdone) ++ bfa_cb_init(bfa->bfad, BFA_STATUS_OK); ++ else ++ bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED); ++ } else ++ bfa->iocfc.action = BFA_IOCFC_ACT_NONE; ++} ++ ++static void ++bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfad_s *bfad = bfa->bfad; ++ ++ if (compl) ++ complete(&bfad->comp); ++ ++ else ++ bfa->iocfc.action = BFA_IOCFC_ACT_NONE; ++} ++ ++static void ++bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfad_s *bfad = bfa->bfad; ++ ++ if (compl) ++ complete(&bfad->disable_comp); ++} ++ ++/** ++ * Update BFA configuration from firmware configuration. ++ */ ++static void ++bfa_iocfc_cfgrsp(struct bfa_s *bfa) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; ++ struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg; ++ struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo; ++ ++ fwcfg->num_cqs = fwcfg->num_cqs; ++ fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs); ++ fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs); ++ fwcfg->num_fcxp_reqs = bfa_os_ntohs(fwcfg->num_fcxp_reqs); ++ fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs); ++ fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports); ++ ++ cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce; ++ cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay); ++ cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency); ++ ++ iocfc->cfgdone = BFA_TRUE; ++ ++ /** ++ * Configuration is complete - initialize/start submodules ++ */ ++ if (iocfc->action == BFA_IOCFC_ACT_INIT) ++ bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa); ++ else ++ bfa_iocfc_start_submod(bfa); ++} ++ ++static void ++bfa_iocfc_stats_clear(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_stats_req_s stats_req; ++ ++ bfa_timer_start(bfa, &iocfc->stats_timer, ++ bfa_iocfc_stats_clr_timeout, bfa, ++ BFA_IOCFC_TOV); ++ ++ bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CLEAR_STATS_REQ, ++ bfa_lpuid(bfa)); ++ bfa_ioc_mbox_send(&bfa->ioc, &stats_req, ++ sizeof(struct bfi_iocfc_stats_req_s)); ++} ++ ++static void ++bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d, struct bfa_fw_stats_s *s) ++{ ++ u32 *dip = (u32 *) d; ++ u32 *sip = (u32 *) s; ++ int i; ++ ++ for (i = 0; i < (sizeof(struct bfa_fw_stats_s) / sizeof(u32)); i++) ++ dip[i] = bfa_os_ntohl(sip[i]); ++} ++ ++static void ++bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ if (complete) { ++ bfa_ioc_clr_stats(&bfa->ioc); ++ iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status); ++ } else { ++ iocfc->stats_busy = BFA_FALSE; ++ iocfc->stats_status = BFA_STATUS_OK; ++ } ++} ++ ++static void ++bfa_iocfc_stats_clr_timeout(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ bfa_trc(bfa, 0); ++ ++ iocfc->stats_status = BFA_STATUS_ETIMER; ++ bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_clr_cb, bfa); ++} ++ ++static void ++bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ if (complete) { ++ if (iocfc->stats_status == BFA_STATUS_OK) { ++ bfa_os_memset(iocfc->stats_ret, 0, ++ sizeof(*iocfc->stats_ret)); ++ bfa_iocfc_stats_swap(&iocfc->stats_ret->fw_stats, ++ iocfc->fw_stats); ++ } ++ iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status); ++ } else { ++ iocfc->stats_busy = BFA_FALSE; ++ iocfc->stats_status = BFA_STATUS_OK; ++ } ++} ++ ++static void ++bfa_iocfc_stats_timeout(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ bfa_trc(bfa, 0); ++ ++ iocfc->stats_status = BFA_STATUS_ETIMER; ++ bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb, bfa); ++} ++ ++static void ++bfa_iocfc_stats_query(struct bfa_s *bfa) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_stats_req_s stats_req; ++ ++ bfa_timer_start(bfa, &iocfc->stats_timer, ++ bfa_iocfc_stats_timeout, bfa, BFA_IOCFC_TOV); ++ ++ bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_GET_STATS_REQ, ++ bfa_lpuid(bfa)); ++ bfa_ioc_mbox_send(&bfa->ioc, &stats_req, ++ sizeof(struct bfi_iocfc_stats_req_s)); ++} ++ ++void ++bfa_iocfc_reset_queues(struct bfa_s *bfa) ++{ ++ int q; ++ ++ for (q = 0; q < BFI_IOC_MAX_CQS; q++) { ++ bfa_reqq_ci(bfa, q) = 0; ++ bfa_reqq_pi(bfa, q) = 0; ++ bfa_rspq_ci(bfa, q) = 0; ++ bfa_rspq_pi(bfa, q) = 0; ++ } ++} ++ ++/** ++ * IOC enable request is complete ++ */ ++static void ++bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ ++ if (status != BFA_STATUS_OK) { ++ bfa_isr_disable(bfa); ++ if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) ++ bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, ++ bfa_iocfc_init_cb, bfa); ++ return; ++ } ++ ++ bfa_iocfc_initdone_submod(bfa); ++ bfa_iocfc_send_cfg(bfa); ++} ++ ++/** ++ * IOC disable request is complete ++ */ ++static void ++bfa_iocfc_disable_cbfn(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ ++ bfa_isr_disable(bfa); ++ bfa_iocfc_disable_submod(bfa); ++ ++ if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP) ++ bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb, ++ bfa); ++ else { ++ bfa_assert(bfa->iocfc.action == BFA_IOCFC_ACT_DISABLE); ++ bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb, ++ bfa); ++ } ++} ++ ++/** ++ * Notify sub-modules of hardware failure. ++ */ ++static void ++bfa_iocfc_hbfail_cbfn(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ ++ bfa->rme_process = BFA_FALSE; ++ ++ bfa_isr_disable(bfa); ++ bfa_iocfc_disable_submod(bfa); ++ ++ if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT) ++ bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb, ++ bfa); ++} ++ ++/** ++ * Actions on chip-reset completion. ++ */ ++static void ++bfa_iocfc_reset_cbfn(void *bfa_arg) ++{ ++ struct bfa_s *bfa = bfa_arg; ++ ++ bfa_iocfc_reset_queues(bfa); ++ bfa_isr_enable(bfa); ++} ++ ++ ++ ++/** ++ * bfa_ioc_public ++ */ ++ ++/** ++ * Query IOC memory requirement information. ++ */ ++void ++bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len) ++{ ++ /* dma memory for IOC */ ++ *dm_len += bfa_ioc_meminfo(); ++ ++ bfa_iocfc_fw_cfg_sz(cfg, dm_len); ++ bfa_iocfc_cqs_sz(cfg, dm_len); ++ *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover); ++} ++ ++/** ++ * Query IOC memory requirement information. ++ */ ++void ++bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ int i; ++ ++ bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn; ++ bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn; ++ bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn; ++ bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn; ++ ++ bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod, ++ bfa->trcmod, bfa->aen, bfa->logm); ++ bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC); ++ bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs); ++ ++ /** ++ * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode. ++ */ ++ if (0) ++ bfa_ioc_set_fcmode(&bfa->ioc); ++ ++ bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev); ++ bfa_iocfc_mem_claim(bfa, cfg, meminfo); ++ bfa_timer_init(&bfa->timer_mod); ++ ++ INIT_LIST_HEAD(&bfa->comp_q); ++ for (i = 0; i < BFI_IOC_MAX_CQS; i++) ++ INIT_LIST_HEAD(&bfa->reqq_waitq[i]); ++} ++ ++/** ++ * Query IOC memory requirement information. ++ */ ++void ++bfa_iocfc_detach(struct bfa_s *bfa) ++{ ++ bfa_ioc_detach(&bfa->ioc); ++} ++ ++/** ++ * Query IOC memory requirement information. ++ */ ++void ++bfa_iocfc_init(struct bfa_s *bfa) ++{ ++ bfa->iocfc.action = BFA_IOCFC_ACT_INIT; ++ bfa_ioc_enable(&bfa->ioc); ++ bfa_msix_install(bfa); ++} ++ ++/** ++ * IOC start called from bfa_start(). Called to start IOC operations ++ * at driver instantiation for this instance. ++ */ ++void ++bfa_iocfc_start(struct bfa_s *bfa) ++{ ++ if (bfa->iocfc.cfgdone) ++ bfa_iocfc_start_submod(bfa); ++} ++ ++/** ++ * IOC stop called from bfa_stop(). Called only when driver is unloaded ++ * for this instance. ++ */ ++void ++bfa_iocfc_stop(struct bfa_s *bfa) ++{ ++ bfa->iocfc.action = BFA_IOCFC_ACT_STOP; ++ ++ bfa->rme_process = BFA_FALSE; ++ bfa_ioc_disable(&bfa->ioc); ++} ++ ++void ++bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m) ++{ ++ struct bfa_s *bfa = bfaarg; ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ union bfi_iocfc_i2h_msg_u *msg; ++ ++ msg = (union bfi_iocfc_i2h_msg_u *) m; ++ bfa_trc(bfa, msg->mh.msg_id); ++ ++ switch (msg->mh.msg_id) { ++ case BFI_IOCFC_I2H_CFG_REPLY: ++ iocfc->cfg_reply = &msg->cfg_reply; ++ bfa_iocfc_cfgrsp(bfa); ++ break; ++ ++ case BFI_IOCFC_I2H_GET_STATS_RSP: ++ if (iocfc->stats_busy == BFA_FALSE ++ || iocfc->stats_status == BFA_STATUS_ETIMER) ++ break; ++ ++ bfa_timer_stop(&iocfc->stats_timer); ++ iocfc->stats_status = BFA_STATUS_OK; ++ bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb, ++ bfa); ++ break; ++ case BFI_IOCFC_I2H_CLEAR_STATS_RSP: ++ /* ++ * check for timer pop before processing the rsp ++ */ ++ if (iocfc->stats_busy == BFA_FALSE ++ || iocfc->stats_status == BFA_STATUS_ETIMER) ++ break; ++ ++ bfa_timer_stop(&iocfc->stats_timer); ++ iocfc->stats_status = BFA_STATUS_OK; ++ bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, ++ bfa_iocfc_stats_clr_cb, bfa); ++ break; ++ case BFI_IOCFC_I2H_UPDATEQ_RSP: ++ iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK); ++ break; ++ default: ++ bfa_assert(0); ++ } ++} ++ ++#ifndef BFA_BIOS_BUILD ++void ++bfa_adapter_get_attr(struct bfa_s *bfa, struct bfa_adapter_attr_s *ad_attr) ++{ ++ bfa_ioc_get_adapter_attr(&bfa->ioc, ad_attr); ++} ++ ++u64 ++bfa_adapter_get_id(struct bfa_s *bfa) ++{ ++ return bfa_ioc_get_adid(&bfa->ioc); ++} ++ ++void ++bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ attr->intr_attr = iocfc->cfginfo->intr_attr; ++ attr->config = iocfc->cfg; ++} ++ ++bfa_status_t ++bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_set_intr_req_s *m; ++ ++ iocfc->cfginfo->intr_attr = *attr; ++ if (!bfa_iocfc_is_operational(bfa)) ++ return BFA_STATUS_OK; ++ ++ m = bfa_reqq_next(bfa, BFA_REQQ_IOC); ++ if (!m) ++ return BFA_STATUS_DEVBUSY; ++ ++ bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ, ++ bfa_lpuid(bfa)); ++ m->coalesce = attr->coalesce; ++ m->delay = bfa_os_htons(attr->delay); ++ m->latency = bfa_os_htons(attr->latency); ++ ++ bfa_trc(bfa, attr->delay); ++ bfa_trc(bfa, attr->latency); ++ ++ bfa_reqq_produce(bfa, BFA_REQQ_IOC); ++ return BFA_STATUS_OK; ++} ++ ++void ++bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1); ++ bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase, snsbase_pa); ++} ++ ++bfa_status_t ++bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats, ++ bfa_cb_ioc_t cbfn, void *cbarg) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ if (iocfc->stats_busy) { ++ bfa_trc(bfa, iocfc->stats_busy); ++ return (BFA_STATUS_DEVBUSY); ++ } ++ ++ iocfc->stats_busy = BFA_TRUE; ++ iocfc->stats_ret = stats; ++ iocfc->stats_cbfn = cbfn; ++ iocfc->stats_cbarg = cbarg; ++ ++ bfa_iocfc_stats_query(bfa); ++ ++ return (BFA_STATUS_OK); ++} ++ ++bfa_status_t ++bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ ++ if (iocfc->stats_busy) { ++ bfa_trc(bfa, iocfc->stats_busy); ++ return (BFA_STATUS_DEVBUSY); ++ } ++ ++ iocfc->stats_busy = BFA_TRUE; ++ iocfc->stats_cbfn = cbfn; ++ iocfc->stats_cbarg = cbarg; ++ ++ bfa_iocfc_stats_clear(bfa); ++ return (BFA_STATUS_OK); ++} ++ ++/** ++ * Enable IOC after it is disabled. ++ */ ++void ++bfa_iocfc_enable(struct bfa_s *bfa) ++{ ++ bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, ++ "IOC Enable"); ++ bfa_ioc_enable(&bfa->ioc); ++} ++ ++void ++bfa_iocfc_disable(struct bfa_s *bfa) ++{ ++ bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0, ++ "IOC Disable"); ++ bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE; ++ ++ bfa->rme_process = BFA_FALSE; ++ bfa_ioc_disable(&bfa->ioc); ++} ++ ++ ++bfa_boolean_t ++bfa_iocfc_is_operational(struct bfa_s *bfa) ++{ ++ return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone; ++} ++ ++/** ++ * Return boot target port wwns -- read from boot information in flash. ++ */ ++void ++bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; ++ ++ *nwwns = cfgrsp->bootwwns.nwwns; ++ *wwns = cfgrsp->bootwwns.wwn; ++} ++ ++#endif ++ ++ +diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h +new file mode 100644 +index 0000000..7ad177e +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_iocfc.h +@@ -0,0 +1,168 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_IOCFC_H__ ++#define __BFA_IOCFC_H__ ++ ++#include ++#include ++#include ++#include ++ ++#define BFA_REQQ_NELEMS_MIN (4) ++#define BFA_RSPQ_NELEMS_MIN (4) ++ ++struct bfa_iocfc_regs_s { ++ bfa_os_addr_t intr_status; ++ bfa_os_addr_t intr_mask; ++ bfa_os_addr_t cpe_q_pi[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t cpe_q_ci[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t cpe_q_depth[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t cpe_q_ctrl[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t rme_q_ci[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t rme_q_pi[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t rme_q_depth[BFI_IOC_MAX_CQS]; ++ bfa_os_addr_t rme_q_ctrl[BFI_IOC_MAX_CQS]; ++}; ++ ++/** ++ * MSIX vector handlers ++ */ ++#define BFA_MSIX_MAX_VECTORS 22 ++typedef void (*bfa_msix_handler_t)(struct bfa_s *bfa, int vec); ++struct bfa_msix_s { ++ int nvecs; ++ bfa_msix_handler_t handler[BFA_MSIX_MAX_VECTORS]; ++}; ++ ++/** ++ * Chip specific interfaces ++ */ ++struct bfa_hwif_s { ++ void (*hw_reginit)(struct bfa_s *bfa); ++ void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); ++ void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); ++ void (*hw_msix_install)(struct bfa_s *bfa); ++ void (*hw_msix_uninstall)(struct bfa_s *bfa); ++ void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix); ++ void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap, ++ u32 *nvecs, u32 *maxvec); ++}; ++typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status); ++ ++struct bfa_iocfc_s { ++ struct bfa_s *bfa; ++ struct bfa_iocfc_cfg_s cfg; ++ int action; ++ ++ u32 req_cq_pi[BFI_IOC_MAX_CQS]; ++ u32 rsp_cq_ci[BFI_IOC_MAX_CQS]; ++ ++ struct bfa_cb_qe_s init_hcb_qe; ++ struct bfa_cb_qe_s stop_hcb_qe; ++ struct bfa_cb_qe_s dis_hcb_qe; ++ struct bfa_cb_qe_s stats_hcb_qe; ++ bfa_boolean_t cfgdone; ++ ++ struct bfa_dma_s cfg_info; ++ struct bfi_iocfc_cfg_s *cfginfo; ++ struct bfa_dma_s cfgrsp_dma; ++ struct bfi_iocfc_cfgrsp_s *cfgrsp; ++ struct bfi_iocfc_cfg_reply_s *cfg_reply; ++ ++ u8 *stats_kva; ++ u64 stats_pa; ++ struct bfa_fw_stats_s *fw_stats; ++ struct bfa_timer_s stats_timer; /* timer */ ++ struct bfa_iocfc_stats_s *stats_ret; /* driver stats location */ ++ bfa_status_t stats_status; /* stats/statsclr status */ ++ bfa_boolean_t stats_busy; /* outstanding stats */ ++ bfa_cb_ioc_t stats_cbfn; /* driver callback function */ ++ void *stats_cbarg; /* user callback arg */ ++ ++ struct bfa_dma_s req_cq_ba[BFI_IOC_MAX_CQS]; ++ struct bfa_dma_s req_cq_shadow_ci[BFI_IOC_MAX_CQS]; ++ struct bfa_dma_s rsp_cq_ba[BFI_IOC_MAX_CQS]; ++ struct bfa_dma_s rsp_cq_shadow_pi[BFI_IOC_MAX_CQS]; ++ struct bfa_iocfc_regs_s bfa_regs; /* BFA device registers */ ++ struct bfa_hwif_s hwif; ++ ++ bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */ ++ void *updateq_cbarg; /* bios callback arg */ ++}; ++ ++#define bfa_lpuid(__bfa) bfa_ioc_portid(&(__bfa)->ioc) ++#define bfa_msix_init(__bfa, __nvecs) \ ++ (__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs) ++#define bfa_msix_install(__bfa) \ ++ (__bfa)->iocfc.hwif.hw_msix_install(__bfa) ++#define bfa_msix_uninstall(__bfa) \ ++ (__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa) ++#define bfa_isr_mode_set(__bfa, __msix) \ ++ (__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix) ++#define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) \ ++ (__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) ++ ++/* ++ * FC specific IOC functions. ++ */ ++void bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len); ++void bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, ++ struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo, ++ struct bfa_pcidev_s *pcidev); ++void bfa_iocfc_detach(struct bfa_s *bfa); ++void bfa_iocfc_init(struct bfa_s *bfa); ++void bfa_iocfc_start(struct bfa_s *bfa); ++void bfa_iocfc_stop(struct bfa_s *bfa); ++void bfa_iocfc_isr(void *bfa, struct bfi_mbmsg_s *msg); ++void bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa); ++bfa_boolean_t bfa_iocfc_is_operational(struct bfa_s *bfa); ++void bfa_iocfc_reset_queues(struct bfa_s *bfa); ++void bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba, ++ u32 reqq_sci, u32 rspq_spi, ++ bfa_cb_iocfc_t cbfn, void *cbarg); ++ ++void bfa_msix_all(struct bfa_s *bfa, int vec); ++void bfa_msix_reqq(struct bfa_s *bfa, int vec); ++void bfa_msix_rspq(struct bfa_s *bfa, int vec); ++void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); ++ ++void bfa_hwcb_reginit(struct bfa_s *bfa); ++void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); ++void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); ++void bfa_hwcb_msix_install(struct bfa_s *bfa); ++void bfa_hwcb_msix_uninstall(struct bfa_s *bfa); ++void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix); ++void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, ++ u32 *nvecs, u32 *maxvec); ++void bfa_hwct_reginit(struct bfa_s *bfa); ++void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); ++void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); ++void bfa_hwct_msix_install(struct bfa_s *bfa); ++void bfa_hwct_msix_uninstall(struct bfa_s *bfa); ++void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix); ++void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, ++ u32 *nvecs, u32 *maxvec); ++ ++void bfa_com_meminfo(bfa_boolean_t mincfg, u32 *dm_len); ++void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi, ++ bfa_boolean_t mincfg); ++void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns); ++ ++#endif /* __BFA_IOCFC_H__ */ ++ +diff --git a/drivers/scsi/bfa/bfa_iocfc_q.c b/drivers/scsi/bfa/bfa_iocfc_q.c +new file mode 100644 +index 0000000..500a17d +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_iocfc_q.c +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include "bfa_intr_priv.h" ++ ++BFA_TRC_FILE(HAL, IOCFC_Q); ++ ++void ++bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba, ++ u32 reqq_sci, u32 rspq_spi, bfa_cb_iocfc_t cbfn, ++ void *cbarg) ++{ ++ struct bfa_iocfc_s *iocfc = &bfa->iocfc; ++ struct bfi_iocfc_updateq_req_s updateq_req; ++ ++ iocfc->updateq_cbfn = cbfn; ++ iocfc->updateq_cbarg = cbarg; ++ ++ bfi_h2i_set(updateq_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_UPDATEQ_REQ, ++ bfa_lpuid(bfa)); ++ ++ updateq_req.reqq_ba = bfa_os_htonl(reqq_ba); ++ updateq_req.rspq_ba = bfa_os_htonl(rspq_ba); ++ updateq_req.reqq_sci = bfa_os_htonl(reqq_sci); ++ updateq_req.rspq_spi = bfa_os_htonl(rspq_spi); ++ ++ bfa_ioc_mbox_send(&bfa->ioc, &updateq_req, ++ sizeof(struct bfi_iocfc_updateq_req_s)); ++} +diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c +new file mode 100644 +index 0000000..7ae2552 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_ioim.c +@@ -0,0 +1,1311 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, IOIM); ++ ++/* ++ * forward declarations. ++ */ ++static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim); ++static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim); ++static void bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim); ++static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim); ++static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim); ++static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); ++ ++/** ++ * bfa_ioim_sm ++ */ ++ ++/** ++ * IO state machine events ++ */ ++enum bfa_ioim_event { ++ BFA_IOIM_SM_START = 1, /* io start request from host */ ++ BFA_IOIM_SM_COMP_GOOD = 2, /* io good comp, resource free */ ++ BFA_IOIM_SM_COMP = 3, /* io comp, resource is free */ ++ BFA_IOIM_SM_COMP_UTAG = 4, /* io comp, resource is free */ ++ BFA_IOIM_SM_DONE = 5, /* io comp, resource not free */ ++ BFA_IOIM_SM_FREE = 6, /* io resource is freed */ ++ BFA_IOIM_SM_ABORT = 7, /* abort request from scsi stack */ ++ BFA_IOIM_SM_ABORT_COMP = 8, /* abort from f/w */ ++ BFA_IOIM_SM_ABORT_DONE = 9, /* abort completion from f/w */ ++ BFA_IOIM_SM_QRESUME = 10, /* CQ space available to queue IO */ ++ BFA_IOIM_SM_SGALLOCED = 11, /* SG page allocation successful */ ++ BFA_IOIM_SM_SQRETRY = 12, /* sequence recovery retry */ ++ BFA_IOIM_SM_HCB = 13, /* bfa callback complete */ ++ BFA_IOIM_SM_CLEANUP = 14, /* IO cleanup from itnim */ ++ BFA_IOIM_SM_TMSTART = 15, /* IO cleanup from tskim */ ++ BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */ ++ BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */ ++ BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */ ++}; ++ ++/* ++ * forward declaration of IO state machine ++ */ ++static void bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_active(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++static void bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, ++ enum bfa_ioim_event event); ++ ++/** ++ * IO is not started (unallocated). ++ */ ++static void ++bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_trc_fp(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_START: ++ if (!bfa_itnim_is_online(ioim->itnim)) { ++ if (!bfa_itnim_hold_io(ioim->itnim)) { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, ++ &ioim->fcpim->ioim_comp_q); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ++ __bfa_cb_ioim_pathtov, ioim); ++ } else { ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, ++ &ioim->itnim->pending_q); ++ } ++ break; ++ } ++ ++ if (ioim->nsges > BFI_SGE_INLINE) { ++ if (!bfa_ioim_sge_setup(ioim)) { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc); ++ return; ++ } ++ } ++ ++ if (!bfa_ioim_send_ioreq(ioim)) { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_qfull); ++ break; ++ } ++ ++ bfa_sm_set_state(ioim, bfa_ioim_sm_active); ++ break; ++ ++ case BFA_IOIM_SM_IOTOV: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ++ __bfa_cb_ioim_pathtov, ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ /** ++ * IO in pending queue can get abort requests. Complete abort ++ * requests immediately. ++ */ ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_assert(bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is waiting for SG pages. ++ */ ++static void ++bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_SGALLOCED: ++ if (!bfa_ioim_send_ioreq(ioim)) { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_qfull); ++ break; ++ } ++ bfa_sm_set_state(ioim, bfa_ioim_sm_active); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is active. ++ */ ++static void ++bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_trc_fp(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_COMP_GOOD: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ++ __bfa_cb_ioim_good_comp, ioim); ++ break; ++ ++ case BFA_IOIM_SM_COMP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_DONE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ ioim->iosp->abort_explicit = BFA_TRUE; ++ ioim->io_cbfn = __bfa_cb_ioim_abort; ++ ++ if (bfa_ioim_send_abort(ioim)) ++ bfa_sm_set_state(ioim, bfa_ioim_sm_abort); ++ else { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull); ++ bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq, ++ &ioim->iosp->reqq_wait); ++ } ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ ioim->iosp->abort_explicit = BFA_FALSE; ++ ioim->io_cbfn = __bfa_cb_ioim_failed; ++ ++ if (bfa_ioim_send_abort(ioim)) ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); ++ else { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); ++ bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq, ++ &ioim->iosp->reqq_wait); ++ } ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is being aborted, waiting for completion from firmware. ++ */ ++static void ++bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_COMP_GOOD: ++ case BFA_IOIM_SM_COMP: ++ case BFA_IOIM_SM_DONE: ++ case BFA_IOIM_SM_FREE: ++ break; ++ ++ case BFA_IOIM_SM_ABORT_DONE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT_COMP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_COMP_UTAG: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE); ++ ioim->iosp->abort_explicit = BFA_FALSE; ++ ++ if (bfa_ioim_send_abort(ioim)) ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); ++ else { ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); ++ bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq, ++ &ioim->iosp->reqq_wait); ++ } ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is being cleaned up (implicit abort), waiting for completion from ++ * firmware. ++ */ ++static void ++bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_COMP_GOOD: ++ case BFA_IOIM_SM_COMP: ++ case BFA_IOIM_SM_DONE: ++ case BFA_IOIM_SM_FREE: ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ /** ++ * IO is already being aborted implicitly ++ */ ++ ioim->io_cbfn = __bfa_cb_ioim_abort; ++ break; ++ ++ case BFA_IOIM_SM_ABORT_DONE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT_COMP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_COMP_UTAG: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ /** ++ * IO can be in cleanup state already due to TM command. 2nd cleanup ++ * request comes from ITN offline event. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is waiting for room in request CQ ++ */ ++static void ++bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_QRESUME: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_active); ++ bfa_ioim_send_ioreq(ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Active IO is being aborted, waiting for room in request CQ. ++ */ ++static void ++bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_QRESUME: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_abort); ++ bfa_ioim_send_abort(ioim); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE); ++ ioim->iosp->abort_explicit = BFA_FALSE; ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); ++ break; ++ ++ case BFA_IOIM_SM_COMP_GOOD: ++ case BFA_IOIM_SM_COMP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_DONE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, ++ ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Active IO is being cleaned up, waiting for room in request CQ. ++ */ ++static void ++bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_QRESUME: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); ++ bfa_ioim_send_abort(ioim); ++ break; ++ ++ case BFA_IOIM_SM_ABORT: ++ /** ++ * IO is alraedy being cleaned up implicitly ++ */ ++ ioim->io_cbfn = __bfa_cb_ioim_abort; ++ break; ++ ++ case BFA_IOIM_SM_COMP_GOOD: ++ case BFA_IOIM_SM_COMP: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_DONE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ bfa_reqq_wcancel(&ioim->iosp->reqq_wait); ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, ++ ioim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO bfa callback is pending. ++ */ ++static void ++bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_trc_fp(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_HCB: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); ++ bfa_ioim_free(ioim); ++ bfa_cb_ioim_resfree(ioim->bfa->bfad); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO bfa callback is pending. IO resource cannot be freed. ++ */ ++static void ++bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_HCB: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_resfree); ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q); ++ break; ++ ++ case BFA_IOIM_SM_FREE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IO is completed, waiting resource free from firmware. ++ */ ++static void ++bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, event); ++ ++ switch (event) { ++ case BFA_IOIM_SM_FREE: ++ bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); ++ bfa_ioim_free(ioim); ++ bfa_cb_ioim_resfree(ioim->bfa->bfad); ++ break; ++ ++ case BFA_IOIM_SM_CLEANUP: ++ bfa_ioim_notify_cleanup(ioim); ++ break; ++ ++ case BFA_IOIM_SM_HWFAIL: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_ioim_private ++ */ ++ ++static void ++__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); ++ return; ++ } ++ ++ bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio); ++} ++ ++static void ++__bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ struct bfi_ioim_rsp_s *m; ++ u8 *snsinfo = NULL; ++ u8 sns_len = 0; ++ s32 residue = 0; ++ ++ if (!complete) { ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); ++ return; ++ } ++ ++ m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg; ++ if (m->io_status == BFI_IOIM_STS_OK) { ++ /** ++ * setup sense information, if present ++ */ ++ if (m->scsi_status == SCSI_STATUS_CHECK_CONDITION ++ && m->sns_len) { ++ sns_len = m->sns_len; ++ snsinfo = ioim->iosp->snsinfo; ++ } ++ ++ /** ++ * setup residue value correctly for normal completions ++ */ ++ if (m->resid_flags == FCP_RESID_UNDER) ++ residue = bfa_os_ntohl(m->residue); ++ if (m->resid_flags == FCP_RESID_OVER) { ++ residue = bfa_os_ntohl(m->residue); ++ residue = -residue; ++ } ++ } ++ ++ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status, ++ m->scsi_status, sns_len, snsinfo, residue); ++} ++ ++static void ++__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); ++ return; ++ } ++ ++ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, ++ 0, 0, NULL, 0); ++} ++ ++static void ++__bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); ++ return; ++ } ++ ++ bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, ++ 0, 0, NULL, 0); ++} ++ ++static void ++__bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); ++ return; ++ } ++ ++ bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); ++} ++ ++static void ++bfa_ioim_sgpg_alloced(void *cbarg) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); ++ list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q); ++ bfa_ioim_sgpg_setup(ioim); ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED); ++} ++ ++/** ++ * Send I/O request to firmware. ++ */ ++static bfa_boolean_t ++bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim) ++{ ++ struct bfa_itnim_s *itnim = ioim->itnim; ++ struct bfi_ioim_req_s *m; ++ static struct fcp_cmnd_s cmnd_z0 = { 0 }; ++ struct bfi_sge_s *sge; ++ u32 pgdlen = 0; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(ioim->bfa, itnim->reqq); ++ if (!m) { ++ bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq, ++ &ioim->iosp->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ /** ++ * build i/o request message next ++ */ ++ m->io_tag = bfa_os_htons(ioim->iotag); ++ m->rport_hdl = ioim->itnim->rport->fw_handle; ++ m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio); ++ ++ /** ++ * build inline IO SG element here ++ */ ++ sge = &m->sges[0]; ++ if (ioim->nsges) { ++ sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, 0); ++ pgdlen = bfa_cb_ioim_get_sglen(ioim->dio, 0); ++ sge->sg_len = pgdlen; ++ sge->flags = (ioim->nsges > BFI_SGE_INLINE) ? ++ BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST; ++ bfa_sge_to_be(sge); ++ sge++; ++ } ++ ++ if (ioim->nsges > BFI_SGE_INLINE) { ++ sge->sga = ioim->sgpg->sgpg_pa; ++ } else { ++ sge->sga.a32.addr_lo = 0; ++ sge->sga.a32.addr_hi = 0; ++ } ++ sge->sg_len = pgdlen; ++ sge->flags = BFI_SGE_PGDLEN; ++ bfa_sge_to_be(sge); ++ ++ /** ++ * set up I/O command parameters ++ */ ++ bfa_os_assign(m->cmnd, cmnd_z0); ++ m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio); ++ m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio); ++ bfa_os_assign(m->cmnd.cdb, ++ *(struct scsi_cdb_s *)bfa_cb_ioim_get_cdb(ioim->dio)); ++ m->cmnd.fcp_dl = bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio)); ++ ++ /** ++ * set up I/O message header ++ */ ++ switch (m->cmnd.iodir) { ++ case FCP_IODIR_READ: ++ bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa)); ++ bfa_stats(itnim, input_reqs); ++ break; ++ case FCP_IODIR_WRITE: ++ bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa)); ++ bfa_stats(itnim, output_reqs); ++ break; ++ case FCP_IODIR_RW: ++ bfa_stats(itnim, input_reqs); ++ bfa_stats(itnim, output_reqs); ++ default: ++ bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); ++ } ++ if (itnim->seq_rec || ++ (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1))) ++ bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); ++ ++#ifdef IOIM_ADVANCED ++ m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio); ++ m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio); ++ m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio); ++ ++ /** ++ * Handle large CDB (>16 bytes). ++ */ ++ m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) - ++ FCP_CMND_CDB_LEN) / sizeof(u32); ++ if (m->cmnd.addl_cdb_len) { ++ bfa_os_memcpy(&m->cmnd.cdb + 1, (struct scsi_cdb_s *) ++ bfa_cb_ioim_get_cdb(ioim->dio) + 1, ++ m->cmnd.addl_cdb_len * sizeof(u32)); ++ fcp_cmnd_fcpdl(&m->cmnd) = ++ bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio)); ++ } ++#endif ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(ioim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++/** ++ * Setup any additional SG pages needed.Inline SG element is setup ++ * at queuing time. ++ */ ++static bfa_boolean_t ++bfa_ioim_sge_setup(struct bfa_ioim_s *ioim) ++{ ++ u16 nsgpgs; ++ ++ bfa_assert(ioim->nsges > BFI_SGE_INLINE); ++ ++ /** ++ * allocate SG pages needed ++ */ ++ nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); ++ if (!nsgpgs) ++ return BFA_TRUE; ++ ++ if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs) ++ != BFA_STATUS_OK) { ++ bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs); ++ return BFA_FALSE; ++ } ++ ++ ioim->nsgpgs = nsgpgs; ++ bfa_ioim_sgpg_setup(ioim); ++ ++ return BFA_TRUE; ++} ++ ++static void ++bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim) ++{ ++ int sgeid, nsges, i; ++ struct bfi_sge_s *sge; ++ struct bfa_sgpg_s *sgpg; ++ u32 pgcumsz; ++ ++ sgeid = BFI_SGE_INLINE; ++ ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q); ++ ++ do { ++ sge = sgpg->sgpg->sges; ++ nsges = ioim->nsges - sgeid; ++ if (nsges > BFI_SGPG_DATA_SGES) ++ nsges = BFI_SGPG_DATA_SGES; ++ ++ pgcumsz = 0; ++ for (i = 0; i < nsges; i++, sge++, sgeid++) { ++ sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid); ++ sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid); ++ pgcumsz += sge->sg_len; ++ ++ /** ++ * set flags ++ */ ++ if (i < (nsges - 1)) ++ sge->flags = BFI_SGE_DATA; ++ else if (sgeid < (ioim->nsges - 1)) ++ sge->flags = BFI_SGE_DATA_CPL; ++ else ++ sge->flags = BFI_SGE_DATA_LAST; ++ } ++ ++ sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg); ++ ++ /** ++ * set the link element of each page ++ */ ++ if (sgeid == ioim->nsges) { ++ sge->flags = BFI_SGE_PGDLEN; ++ sge->sga.a32.addr_lo = 0; ++ sge->sga.a32.addr_hi = 0; ++ } else { ++ sge->flags = BFI_SGE_LINK; ++ sge->sga = sgpg->sgpg_pa; ++ } ++ sge->sg_len = pgcumsz; ++ } while (sgeid < ioim->nsges); ++} ++ ++/** ++ * Send I/O abort request to firmware. ++ */ ++static bfa_boolean_t ++bfa_ioim_send_abort(struct bfa_ioim_s *ioim) ++{ ++ struct bfa_itnim_s *itnim = ioim->itnim; ++ struct bfi_ioim_abort_req_s *m; ++ enum bfi_ioim_h2i msgop; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(ioim->bfa, itnim->reqq); ++ if (!m) ++ return BFA_FALSE; ++ ++ /** ++ * build i/o request message next ++ */ ++ if (ioim->iosp->abort_explicit) ++ msgop = BFI_IOIM_H2I_IOABORT_REQ; ++ else ++ msgop = BFI_IOIM_H2I_IOCLEANUP_REQ; ++ ++ bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa)); ++ m->io_tag = bfa_os_htons(ioim->iotag); ++ m->abort_tag = ++ioim->abort_tag; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(ioim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++/** ++ * Call to resume any I/O requests waiting for room in request queue. ++ */ ++static void ++bfa_ioim_qresume(void *cbarg) ++{ ++ struct bfa_ioim_s *ioim = cbarg; ++ ++ bfa_fcpim_stats(ioim->fcpim, qresumes); ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME); ++} ++ ++ ++static void ++bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim) ++{ ++ /** ++ * Move IO from itnim queue to fcpim global queue since itnim will be ++ * freed. ++ */ ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); ++ ++ if (!ioim->iosp->tskim) { ++ if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) { ++ bfa_cb_dequeue(&ioim->hcb_qe); ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q); ++ } ++ bfa_itnim_iodone(ioim->itnim); ++ } else ++ bfa_tskim_iodone(ioim->iosp->tskim); ++} ++ ++/** ++ * or after the link comes back. ++ */ ++void ++bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov) ++{ ++ /** ++ * If path tov timer expired, failback with PATHTOV status - these ++ * IO requests are not normally retried by IO stack. ++ * ++ * Otherwise device cameback online and fail it with normal failed ++ * status so that IO stack retries these failed IO requests. ++ */ ++ if (iotov) ++ ioim->io_cbfn = __bfa_cb_ioim_pathtov; ++ else ++ ioim->io_cbfn = __bfa_cb_ioim_failed; ++ ++ bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); ++ ++ /** ++ * Move IO to fcpim global queue since itnim will be ++ * freed. ++ */ ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); ++} ++ ++ ++ ++/** ++ * bfa_ioim_friend ++ */ ++ ++/** ++ * Memory allocation and initialization. ++ */ ++void ++bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo) ++{ ++ struct bfa_ioim_s *ioim; ++ struct bfa_ioim_sp_s *iosp; ++ u16 i; ++ u8 *snsinfo; ++ u32 snsbufsz; ++ ++ /** ++ * claim memory first ++ */ ++ ioim = (struct bfa_ioim_s *) bfa_meminfo_kva(minfo); ++ fcpim->ioim_arr = ioim; ++ bfa_meminfo_kva(minfo) = (u8 *) (ioim + fcpim->num_ioim_reqs); ++ ++ iosp = (struct bfa_ioim_sp_s *) bfa_meminfo_kva(minfo); ++ fcpim->ioim_sp_arr = iosp; ++ bfa_meminfo_kva(minfo) = (u8 *) (iosp + fcpim->num_ioim_reqs); ++ ++ /** ++ * Claim DMA memory for per IO sense data. ++ */ ++ snsbufsz = fcpim->num_ioim_reqs * BFI_IOIM_SNSLEN; ++ fcpim->snsbase.pa = bfa_meminfo_dma_phys(minfo); ++ bfa_meminfo_dma_phys(minfo) += snsbufsz; ++ ++ fcpim->snsbase.kva = bfa_meminfo_dma_virt(minfo); ++ bfa_meminfo_dma_virt(minfo) += snsbufsz; ++ snsinfo = fcpim->snsbase.kva; ++ bfa_iocfc_set_snsbase(fcpim->bfa, fcpim->snsbase.pa); ++ ++ /** ++ * Initialize ioim free queues ++ */ ++ INIT_LIST_HEAD(&fcpim->ioim_free_q); ++ INIT_LIST_HEAD(&fcpim->ioim_resfree_q); ++ INIT_LIST_HEAD(&fcpim->ioim_comp_q); ++ ++ for (i = 0; i < fcpim->num_ioim_reqs; ++ i++, ioim++, iosp++, snsinfo += BFI_IOIM_SNSLEN) { ++ /* ++ * initialize IOIM ++ */ ++ bfa_os_memset(ioim, 0, sizeof(struct bfa_ioim_s)); ++ ioim->iotag = i; ++ ioim->bfa = fcpim->bfa; ++ ioim->fcpim = fcpim; ++ ioim->iosp = iosp; ++ iosp->snsinfo = snsinfo; ++ INIT_LIST_HEAD(&ioim->sgpg_q); ++ bfa_reqq_winit(&ioim->iosp->reqq_wait, ++ bfa_ioim_qresume, ioim); ++ bfa_sgpg_winit(&ioim->iosp->sgpg_wqe, ++ bfa_ioim_sgpg_alloced, ioim); ++ bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); ++ ++ list_add_tail(&ioim->qe, &fcpim->ioim_free_q); ++ } ++} ++ ++/** ++ * Driver detach time call. ++ */ ++void ++bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim) ++{ ++} ++ ++void ++bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m; ++ struct bfa_ioim_s *ioim; ++ u16 iotag; ++ enum bfa_ioim_event evt = BFA_IOIM_SM_COMP; ++ ++ iotag = bfa_os_ntohs(rsp->io_tag); ++ ++ ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); ++ bfa_assert(ioim->iotag == iotag); ++ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_trc(ioim->bfa, rsp->io_status); ++ bfa_trc(ioim->bfa, rsp->reuse_io_tag); ++ ++ if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active)) ++ bfa_os_assign(ioim->iosp->comp_rspmsg, *m); ++ ++ switch (rsp->io_status) { ++ case BFI_IOIM_STS_OK: ++ bfa_fcpim_stats(fcpim, iocomp_ok); ++ if (rsp->reuse_io_tag == 0) ++ evt = BFA_IOIM_SM_DONE; ++ else ++ evt = BFA_IOIM_SM_COMP; ++ break; ++ ++ case BFI_IOIM_STS_TIMEDOUT: ++ case BFI_IOIM_STS_ABORTED: ++ rsp->io_status = BFI_IOIM_STS_ABORTED; ++ bfa_fcpim_stats(fcpim, iocomp_aborted); ++ if (rsp->reuse_io_tag == 0) ++ evt = BFA_IOIM_SM_DONE; ++ else ++ evt = BFA_IOIM_SM_COMP; ++ break; ++ ++ case BFI_IOIM_STS_PROTO_ERR: ++ bfa_fcpim_stats(fcpim, iocom_proto_err); ++ bfa_assert(rsp->reuse_io_tag); ++ evt = BFA_IOIM_SM_COMP; ++ break; ++ ++ case BFI_IOIM_STS_SQER_NEEDED: ++ bfa_fcpim_stats(fcpim, iocom_sqer_needed); ++ bfa_assert(rsp->reuse_io_tag == 0); ++ evt = BFA_IOIM_SM_SQRETRY; ++ break; ++ ++ case BFI_IOIM_STS_RES_FREE: ++ bfa_fcpim_stats(fcpim, iocom_res_free); ++ evt = BFA_IOIM_SM_FREE; ++ break; ++ ++ case BFI_IOIM_STS_HOST_ABORTED: ++ bfa_fcpim_stats(fcpim, iocom_hostabrts); ++ if (rsp->abort_tag != ioim->abort_tag) { ++ bfa_trc(ioim->bfa, rsp->abort_tag); ++ bfa_trc(ioim->bfa, ioim->abort_tag); ++ return; ++ } ++ ++ if (rsp->reuse_io_tag) ++ evt = BFA_IOIM_SM_ABORT_COMP; ++ else ++ evt = BFA_IOIM_SM_ABORT_DONE; ++ break; ++ ++ case BFI_IOIM_STS_UTAG: ++ bfa_fcpim_stats(fcpim, iocom_utags); ++ evt = BFA_IOIM_SM_COMP_UTAG; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++ ++ bfa_sm_send_event(ioim, evt); ++} ++ ++void ++bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m; ++ struct bfa_ioim_s *ioim; ++ u16 iotag; ++ ++ iotag = bfa_os_ntohs(rsp->io_tag); ++ ++ ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); ++ bfa_assert(ioim->iotag == iotag); ++ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); ++} ++ ++/** ++ * Called by itnim to clean up IO while going offline. ++ */ ++void ++bfa_ioim_cleanup(struct bfa_ioim_s *ioim) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_fcpim_stats(ioim->fcpim, io_cleanups); ++ ++ ioim->iosp->tskim = NULL; ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP); ++} ++ ++void ++bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_fcpim_stats(ioim->fcpim, io_tmaborts); ++ ++ ioim->iosp->tskim = tskim; ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP); ++} ++ ++/** ++ * IOC failure handling. ++ */ ++void ++bfa_ioim_iocdisable(struct bfa_ioim_s *ioim) ++{ ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL); ++} ++ ++/** ++ * IO offline TOV popped. Fail the pending IO. ++ */ ++void ++bfa_ioim_tov(struct bfa_ioim_s *ioim) ++{ ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV); ++} ++ ++ ++ ++/** ++ * bfa_ioim_api ++ */ ++ ++/** ++ * Allocate IOIM resource for initiator mode I/O request. ++ */ ++struct bfa_ioim_s * ++bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio, ++ struct bfa_itnim_s *itnim, u16 nsges) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfa_ioim_s *ioim; ++ ++ /** ++ * alocate IOIM resource ++ */ ++ bfa_q_deq(&fcpim->ioim_free_q, &ioim); ++ if (!ioim) { ++ bfa_fcpim_stats(fcpim, no_iotags); ++ return NULL; ++ } ++ ++ ioim->dio = dio; ++ ioim->itnim = itnim; ++ ioim->nsges = nsges; ++ ioim->nsgpgs = 0; ++ ++ bfa_stats(fcpim, total_ios); ++ bfa_stats(itnim, ios); ++ fcpim->ios_active++; ++ ++ list_add_tail(&ioim->qe, &itnim->io_q); ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ ++ return ioim; ++} ++ ++void ++bfa_ioim_free(struct bfa_ioim_s *ioim) ++{ ++ struct bfa_fcpim_mod_s *fcpim = ioim->fcpim; ++ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_assert_fp(bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit)); ++ ++ bfa_assert_fp(list_empty(&ioim->sgpg_q) ++ || (ioim->nsges > BFI_SGE_INLINE)); ++ ++ if (ioim->nsgpgs > 0) ++ bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs); ++ ++ bfa_stats(ioim->itnim, io_comps); ++ fcpim->ios_active--; ++ ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &fcpim->ioim_free_q); ++} ++ ++void ++bfa_ioim_start(struct bfa_ioim_s *ioim) ++{ ++ bfa_trc_fp(ioim->bfa, ioim->iotag); ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_START); ++} ++ ++/** ++ * Driver I/O abort request. ++ */ ++void ++bfa_ioim_abort(struct bfa_ioim_s *ioim) ++{ ++ bfa_trc(ioim->bfa, ioim->iotag); ++ bfa_fcpim_stats(ioim->fcpim, io_aborts); ++ bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c +new file mode 100644 +index 0000000..4d5c61a +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_itnim.c +@@ -0,0 +1,1088 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include "bfa_fcpim_priv.h" ++ ++BFA_TRC_FILE(HAL, ITNIM); ++ ++#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \ ++ ((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))) ++ ++#define bfa_fcpim_additn(__itnim) \ ++ list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q) ++#define bfa_fcpim_delitn(__itnim) do { \ ++ bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \ ++ list_del(&(__itnim)->qe); \ ++ bfa_assert(list_empty(&(__itnim)->io_q)); \ ++ bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \ ++ bfa_assert(list_empty(&(__itnim)->pending_q)); \ ++} while (0) ++ ++#define bfa_itnim_online_cb(__itnim) do { \ ++ if ((__itnim)->bfa->fcs) \ ++ bfa_cb_itnim_online((__itnim)->ditn); \ ++ else { \ ++ bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ ++ __bfa_cb_itnim_online, (__itnim)); \ ++ } \ ++} while (0) ++ ++#define bfa_itnim_offline_cb(__itnim) do { \ ++ if ((__itnim)->bfa->fcs) \ ++ bfa_cb_itnim_offline((__itnim)->ditn); \ ++ else { \ ++ bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ ++ __bfa_cb_itnim_offline, (__itnim)); \ ++ } \ ++} while (0) ++ ++#define bfa_itnim_sler_cb(__itnim) do { \ ++ if ((__itnim)->bfa->fcs) \ ++ bfa_cb_itnim_sler((__itnim)->ditn); \ ++ else { \ ++ bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ ++ __bfa_cb_itnim_sler, (__itnim)); \ ++ } \ ++} while (0) ++ ++/* ++ * forward declarations ++ */ ++static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim); ++static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim); ++static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim); ++static void bfa_itnim_cleanp_comp(void *itnim_cbarg); ++static void bfa_itnim_cleanup(struct bfa_itnim_s *itnim); ++static void __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete); ++static void bfa_itnim_iotov_online(struct bfa_itnim_s *itnim); ++static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim); ++static void bfa_itnim_iotov(void *itnim_arg); ++static void bfa_itnim_iotov_start(struct bfa_itnim_s *itnim); ++static void bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim); ++static void bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim); ++ ++/** ++ * bfa_itnim_sm BFA itnim state machine ++ */ ++ ++ ++enum bfa_itnim_event { ++ BFA_ITNIM_SM_CREATE = 1, /* itnim is created */ ++ BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */ ++ BFA_ITNIM_SM_OFFLINE = 3, /* itnim is offline */ ++ BFA_ITNIM_SM_FWRSP = 4, /* firmware response */ ++ BFA_ITNIM_SM_DELETE = 5, /* deleting an existing itnim */ ++ BFA_ITNIM_SM_CLEANUP = 6, /* IO cleanup completion */ ++ BFA_ITNIM_SM_SLER = 7, /* second level error recovery */ ++ BFA_ITNIM_SM_HWFAIL = 8, /* IOC h/w failure event */ ++ BFA_ITNIM_SM_QRESUME = 9, /* queue space available */ ++}; ++ ++static void bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_created(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_online(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event); ++ ++/** ++ * Beginning/unallocated state - no events expected. ++ */ ++static void ++bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_CREATE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_created); ++ itnim->is_online = BFA_FALSE; ++ bfa_fcpim_additn(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Beginning state, only online event expected. ++ */ ++static void ++bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_ONLINE: ++ if (bfa_itnim_send_fwcreate(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Waiting for itnim create response from firmware. ++ */ ++static void ++bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_FWRSP: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_online); ++ itnim->is_online = BFA_TRUE; ++ bfa_itnim_iotov_online(itnim); ++ bfa_itnim_online_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending); ++ break; ++ ++ case BFA_ITNIM_SM_OFFLINE: ++ if (bfa_itnim_send_fwdelete(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_QRESUME: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); ++ bfa_itnim_send_fwcreate(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_reqq_wcancel(&itnim->reqq_wait); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_offline); ++ bfa_reqq_wcancel(&itnim->reqq_wait); ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_reqq_wcancel(&itnim->reqq_wait); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Waiting for itnim create response from firmware, a delete is pending. ++ */ ++static void ++bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_FWRSP: ++ if (bfa_itnim_send_fwdelete(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Online state - normal parking state. ++ */ ++static void ++bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); ++ itnim->is_online = BFA_FALSE; ++ bfa_itnim_iotov_start(itnim); ++ bfa_itnim_cleanup(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); ++ itnim->is_online = BFA_FALSE; ++ bfa_itnim_cleanup(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_SLER: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_sler); ++ itnim->is_online = BFA_FALSE; ++ bfa_itnim_iotov_start(itnim); ++ bfa_itnim_sler_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ itnim->is_online = BFA_FALSE; ++ bfa_itnim_iotov_start(itnim); ++ bfa_itnim_iocdisable_cleanup(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Second level error recovery need. ++ */ ++static void ++bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); ++ bfa_itnim_cleanup(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); ++ bfa_itnim_cleanup(itnim); ++ bfa_itnim_iotov_delete(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_itnim_iocdisable_cleanup(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Going offline. Waiting for active IO cleanup. ++ */ ++static void ++bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_CLEANUP: ++ if (bfa_itnim_send_fwdelete(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); ++ bfa_itnim_iotov_delete(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_itnim_iocdisable_cleanup(itnim); ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_SLER: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Deleting itnim. Waiting for active IO cleanup. ++ */ ++static void ++bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_CLEANUP: ++ if (bfa_itnim_send_fwdelete(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_itnim_iocdisable_cleanup(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport offline. Fimrware itnim is being deleted - awaiting f/w response. ++ */ ++static void ++bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_FWRSP: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_offline); ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_QRESUME: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); ++ bfa_itnim_send_fwdelete(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ bfa_reqq_wcancel(&itnim->reqq_wait); ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Offline state. ++ */ ++static void ++bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_itnim_iotov_delete(itnim); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_ONLINE: ++ if (bfa_itnim_send_fwcreate(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IOC h/w failed state. ++ */ ++static void ++bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_itnim_iotov_delete(itnim); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_OFFLINE: ++ bfa_itnim_offline_cb(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_ONLINE: ++ if (bfa_itnim_send_fwcreate(itnim)) ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); ++ else ++ bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Itnim is deleted, waiting for firmware response to delete. ++ */ ++static void ++bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_FWRSP: ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, ++ enum bfa_itnim_event event) ++{ ++ bfa_trc(itnim->bfa, itnim->rport->rport_tag); ++ bfa_trc(itnim->bfa, event); ++ ++ switch (event) { ++ case BFA_ITNIM_SM_QRESUME: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); ++ bfa_itnim_send_fwdelete(itnim); ++ break; ++ ++ case BFA_ITNIM_SM_HWFAIL: ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ bfa_reqq_wcancel(&itnim->reqq_wait); ++ bfa_fcpim_delitn(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_itnim_private ++ */ ++ ++/** ++ * Initiate cleanup of all IOs on an IOC failure. ++ */ ++static void ++bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim) ++{ ++ struct bfa_tskim_s *tskim; ++ struct bfa_ioim_s *ioim; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &itnim->tsk_q) { ++ tskim = (struct bfa_tskim_s *) qe; ++ bfa_tskim_iocdisable(tskim); ++ } ++ ++ list_for_each_safe(qe, qen, &itnim->io_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ bfa_ioim_iocdisable(ioim); ++ } ++ ++ /** ++ * For IO request in pending queue, we pretend an early timeout. ++ */ ++ list_for_each_safe(qe, qen, &itnim->pending_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ bfa_ioim_tov(ioim); ++ } ++ ++ list_for_each_safe(qe, qen, &itnim->io_cleanup_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ bfa_ioim_iocdisable(ioim); ++ } ++} ++ ++/** ++ * IO cleanup completion ++ */ ++static void ++bfa_itnim_cleanp_comp(void *itnim_cbarg) ++{ ++ struct bfa_itnim_s *itnim = itnim_cbarg; ++ ++ bfa_stats(itnim, cleanup_comps); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP); ++} ++ ++/** ++ * Initiate cleanup of all IOs. ++ */ ++static void ++bfa_itnim_cleanup(struct bfa_itnim_s *itnim) ++{ ++ struct bfa_ioim_s *ioim; ++ struct bfa_tskim_s *tskim; ++ struct list_head *qe, *qen; ++ ++ bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim); ++ ++ list_for_each_safe(qe, qen, &itnim->io_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ ++ /** ++ * Move IO to a cleanup queue from active queue so that a later ++ * TM will not pickup this IO. ++ */ ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &itnim->io_cleanup_q); ++ ++ bfa_wc_up(&itnim->wc); ++ bfa_ioim_cleanup(ioim); ++ } ++ ++ list_for_each_safe(qe, qen, &itnim->tsk_q) { ++ tskim = (struct bfa_tskim_s *) qe; ++ bfa_wc_up(&itnim->wc); ++ bfa_tskim_cleanup(tskim); ++ } ++ ++ bfa_wc_wait(&itnim->wc); ++} ++ ++static void ++__bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_itnim_s *itnim = cbarg; ++ ++ if (complete) ++ bfa_cb_itnim_online(itnim->ditn); ++} ++ ++static void ++__bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_itnim_s *itnim = cbarg; ++ ++ if (complete) ++ bfa_cb_itnim_offline(itnim->ditn); ++} ++ ++static void ++__bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_itnim_s *itnim = cbarg; ++ ++ if (complete) ++ bfa_cb_itnim_sler(itnim->ditn); ++} ++ ++/** ++ * Call to resume any I/O requests waiting for room in request queue. ++ */ ++static void ++bfa_itnim_qresume(void *cbarg) ++{ ++ struct bfa_itnim_s *itnim = cbarg; ++ ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME); ++} ++ ++ ++ ++ ++/** ++ * bfa_itnim_public ++ */ ++ ++void ++bfa_itnim_iodone(struct bfa_itnim_s *itnim) ++{ ++ bfa_wc_down(&itnim->wc); ++} ++ ++void ++bfa_itnim_tskdone(struct bfa_itnim_s *itnim) ++{ ++ bfa_wc_down(&itnim->wc); ++} ++ ++void ++bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len) ++{ ++ /** ++ * ITN memory ++ */ ++ *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s); ++} ++ ++void ++bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo) ++{ ++ struct bfa_s *bfa = fcpim->bfa; ++ struct bfa_itnim_s *itnim; ++ int i; ++ ++ INIT_LIST_HEAD(&fcpim->itnim_q); ++ ++ itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo); ++ fcpim->itnim_arr = itnim; ++ ++ for (i = 0; i < fcpim->num_itnims; i++, itnim++) { ++ bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s)); ++ itnim->bfa = bfa; ++ itnim->fcpim = fcpim; ++ itnim->reqq = BFA_REQQ_QOS_LO; ++ itnim->rport = BFA_RPORT_FROM_TAG(bfa, i); ++ itnim->iotov_active = BFA_FALSE; ++ bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim); ++ ++ INIT_LIST_HEAD(&itnim->io_q); ++ INIT_LIST_HEAD(&itnim->io_cleanup_q); ++ INIT_LIST_HEAD(&itnim->pending_q); ++ INIT_LIST_HEAD(&itnim->tsk_q); ++ INIT_LIST_HEAD(&itnim->delay_comp_q); ++ bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); ++ } ++ ++ bfa_meminfo_kva(minfo) = (u8 *) itnim; ++} ++ ++void ++bfa_itnim_iocdisable(struct bfa_itnim_s *itnim) ++{ ++ bfa_stats(itnim, ioc_disabled); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL); ++} ++ ++static bfa_boolean_t ++bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim) ++{ ++ struct bfi_itnim_create_req_s *m; ++ ++ itnim->msg_no++; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(itnim->bfa, itnim->reqq); ++ if (!m) { ++ bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ, ++ bfa_lpuid(itnim->bfa)); ++ m->fw_handle = itnim->rport->fw_handle; ++ m->class = FC_CLASS_3; ++ m->seq_rec = itnim->seq_rec; ++ m->msg_no = itnim->msg_no; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(itnim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++static bfa_boolean_t ++bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim) ++{ ++ struct bfi_itnim_delete_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(itnim->bfa, itnim->reqq); ++ if (!m) { ++ bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ, ++ bfa_lpuid(itnim->bfa)); ++ m->fw_handle = itnim->rport->fw_handle; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(itnim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++/** ++ * Cleanup all pending failed inflight requests. ++ */ ++static void ++bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov) ++{ ++ struct bfa_ioim_s *ioim; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &itnim->delay_comp_q) { ++ ioim = (struct bfa_ioim_s *)qe; ++ bfa_ioim_delayed_comp(ioim, iotov); ++ } ++} ++ ++/** ++ * Start all pending IO requests. ++ */ ++static void ++bfa_itnim_iotov_online(struct bfa_itnim_s *itnim) ++{ ++ struct bfa_ioim_s *ioim; ++ ++ bfa_itnim_iotov_stop(itnim); ++ ++ /** ++ * Abort all inflight IO requests in the queue ++ */ ++ bfa_itnim_delayed_comp(itnim, BFA_FALSE); ++ ++ /** ++ * Start all pending IO requests. ++ */ ++ while (!list_empty(&itnim->pending_q)) { ++ bfa_q_deq(&itnim->pending_q, &ioim); ++ list_add_tail(&ioim->qe, &itnim->io_q); ++ bfa_ioim_start(ioim); ++ } ++} ++ ++/** ++ * Fail all pending IO requests ++ */ ++static void ++bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim) ++{ ++ struct bfa_ioim_s *ioim; ++ ++ /** ++ * Fail all inflight IO requests in the queue ++ */ ++ bfa_itnim_delayed_comp(itnim, BFA_TRUE); ++ ++ /** ++ * Fail any pending IO requests. ++ */ ++ while (!list_empty(&itnim->pending_q)) { ++ bfa_q_deq(&itnim->pending_q, &ioim); ++ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); ++ bfa_ioim_tov(ioim); ++ } ++} ++ ++/** ++ * IO TOV timer callback. Fail any pending IO requests. ++ */ ++static void ++bfa_itnim_iotov(void *itnim_arg) ++{ ++ struct bfa_itnim_s *itnim = itnim_arg; ++ ++ itnim->iotov_active = BFA_FALSE; ++ ++ bfa_cb_itnim_tov_begin(itnim->ditn); ++ bfa_itnim_iotov_cleanup(itnim); ++ bfa_cb_itnim_tov(itnim->ditn); ++} ++ ++/** ++ * Start IO TOV timer for failing back pending IO requests in offline state. ++ */ ++static void ++bfa_itnim_iotov_start(struct bfa_itnim_s *itnim) ++{ ++ if (itnim->fcpim->path_tov > 0) { ++ ++ itnim->iotov_active = BFA_TRUE; ++ bfa_assert(bfa_itnim_hold_io(itnim)); ++ bfa_timer_start(itnim->bfa, &itnim->timer, ++ bfa_itnim_iotov, itnim, itnim->fcpim->path_tov); ++ } ++} ++ ++/** ++ * Stop IO TOV timer. ++ */ ++static void ++bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim) ++{ ++ if (itnim->iotov_active) { ++ itnim->iotov_active = BFA_FALSE; ++ bfa_timer_stop(&itnim->timer); ++ } ++} ++ ++/** ++ * Stop IO TOV timer. ++ */ ++static void ++bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim) ++{ ++ bfa_boolean_t pathtov_active = BFA_FALSE; ++ ++ if (itnim->iotov_active) ++ pathtov_active = BFA_TRUE; ++ ++ bfa_itnim_iotov_stop(itnim); ++ if (pathtov_active) ++ bfa_cb_itnim_tov_begin(itnim->ditn); ++ bfa_itnim_iotov_cleanup(itnim); ++ if (pathtov_active) ++ bfa_cb_itnim_tov(itnim->ditn); ++} ++ ++ ++ ++/** ++ * bfa_itnim_public ++ */ ++ ++/** ++ * Itnim interrupt processing. ++ */ ++void ++bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ union bfi_itnim_i2h_msg_u msg; ++ struct bfa_itnim_s *itnim; ++ ++ bfa_trc(bfa, m->mhdr.msg_id); ++ ++ msg.msg = m; ++ ++ switch (m->mhdr.msg_id) { ++ case BFI_ITNIM_I2H_CREATE_RSP: ++ itnim = BFA_ITNIM_FROM_TAG(fcpim, ++ msg.create_rsp->bfa_handle); ++ bfa_assert(msg.create_rsp->status == BFA_STATUS_OK); ++ bfa_stats(itnim, create_comps); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); ++ break; ++ ++ case BFI_ITNIM_I2H_DELETE_RSP: ++ itnim = BFA_ITNIM_FROM_TAG(fcpim, ++ msg.delete_rsp->bfa_handle); ++ bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK); ++ bfa_stats(itnim, delete_comps); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); ++ break; ++ ++ case BFI_ITNIM_I2H_SLER_EVENT: ++ itnim = BFA_ITNIM_FROM_TAG(fcpim, ++ msg.sler_event->bfa_handle); ++ bfa_stats(itnim, sler_events); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER); ++ break; ++ ++ default: ++ bfa_trc(bfa, m->mhdr.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_itnim_api ++ */ ++ ++struct bfa_itnim_s * ++bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfa_itnim_s *itnim; ++ ++ itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag); ++ bfa_assert(itnim->rport == rport); ++ ++ itnim->ditn = ditn; ++ ++ bfa_stats(itnim, creates); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE); ++ ++ return (itnim); ++} ++ ++void ++bfa_itnim_delete(struct bfa_itnim_s *itnim) ++{ ++ bfa_stats(itnim, deletes); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE); ++} ++ ++void ++bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec) ++{ ++ itnim->seq_rec = seq_rec; ++ bfa_stats(itnim, onlines); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE); ++} ++ ++void ++bfa_itnim_offline(struct bfa_itnim_s *itnim) ++{ ++ bfa_stats(itnim, offlines); ++ bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE); ++} ++ ++/** ++ * Return true if itnim is considered offline for holding off IO request. ++ * IO is not held if itnim is being deleted. ++ */ ++bfa_boolean_t ++bfa_itnim_hold_io(struct bfa_itnim_s *itnim) ++{ ++ return ( ++ itnim->fcpim->path_tov && itnim->iotov_active && ++ (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) || ++ bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) || ++ bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) || ++ bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) || ++ bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) || ++ bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)) ++); ++} ++ ++void ++bfa_itnim_get_stats(struct bfa_itnim_s *itnim, ++ struct bfa_itnim_hal_stats_s *stats) ++{ ++ *stats = itnim->stats; ++} ++ ++void ++bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) ++{ ++ bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats)); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_log.c b/drivers/scsi/bfa/bfa_log.c +new file mode 100644 +index 0000000..c2735e5 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_log.c +@@ -0,0 +1,346 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_log.c BFA log library ++ */ ++ ++#include ++#include ++ ++/* ++ * global log info structure ++ */ ++struct bfa_log_info_s { ++ u32 start_idx; /* start index for a module */ ++ u32 total_count; /* total count for a module */ ++ enum bfa_log_severity level; /* global log level */ ++ bfa_log_cb_t cbfn; /* callback function */ ++}; ++ ++static struct bfa_log_info_s bfa_log_info[BFA_LOG_MODULE_ID_MAX + 1]; ++static u32 bfa_log_msg_total_count; ++static int bfa_log_initialized; ++ ++static char *bfa_log_severity[] = ++ { "[none]", "[critical]", "[error]", "[warn]", "[info]", "" }; ++ ++/** ++ * BFA log library initialization ++ * ++ * The log library initialization includes the following, ++ * - set log instance name and callback function ++ * - read the message array generated from xml files ++ * - calculate start index for each module ++ * - calculate message count for each module ++ * - perform error checking ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] instance_name - instance name ++ * @param[in] cbfn - callback function ++ * ++ * It return 0 on success, or -1 on failure ++ */ ++int ++bfa_log_init(struct bfa_log_mod_s *log_mod, char *instance_name, ++ bfa_log_cb_t cbfn) ++{ ++ struct bfa_log_msgdef_s *msg; ++ u32 pre_mod_id = 0; ++ u32 cur_mod_id = 0; ++ u32 i, pre_idx, idx, msg_id; ++ ++ /* ++ * set instance name ++ */ ++ if (log_mod) { ++ strncpy(log_mod->instance_info, instance_name, ++ sizeof(log_mod->instance_info)); ++ log_mod->cbfn = cbfn; ++ for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++) ++ log_mod->log_level[i] = BFA_LOG_WARNING; ++ } ++ ++ if (bfa_log_initialized) ++ return 0; ++ ++ for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++) { ++ bfa_log_info[i].start_idx = 0; ++ bfa_log_info[i].total_count = 0; ++ bfa_log_info[i].level = BFA_LOG_WARNING; ++ bfa_log_info[i].cbfn = cbfn; ++ } ++ ++ pre_idx = 0; ++ idx = 0; ++ msg = bfa_log_msg_array; ++ msg_id = BFA_LOG_GET_MSG_ID(msg); ++ pre_mod_id = BFA_LOG_GET_MOD_ID(msg_id); ++ while (msg_id != 0) { ++ cur_mod_id = BFA_LOG_GET_MOD_ID(msg_id); ++ ++ if (cur_mod_id > BFA_LOG_MODULE_ID_MAX) { ++ cbfn(log_mod, msg_id, ++ "%s%s log: module id %u out of range\n", ++ BFA_LOG_CAT_NAME, ++ bfa_log_severity[BFA_LOG_ERROR], ++ cur_mod_id); ++ return -1; ++ } ++ ++ if (pre_mod_id > BFA_LOG_MODULE_ID_MAX) { ++ cbfn(log_mod, msg_id, ++ "%s%s log: module id %u out of range\n", ++ BFA_LOG_CAT_NAME, ++ bfa_log_severity[BFA_LOG_ERROR], ++ pre_mod_id); ++ return -1; ++ } ++ ++ if (cur_mod_id != pre_mod_id) { ++ bfa_log_info[pre_mod_id].start_idx = pre_idx; ++ bfa_log_info[pre_mod_id].total_count = idx - pre_idx; ++ pre_mod_id = cur_mod_id; ++ pre_idx = idx; ++ } ++ ++ idx++; ++ msg++; ++ msg_id = BFA_LOG_GET_MSG_ID(msg); ++ } ++ ++ bfa_log_info[cur_mod_id].start_idx = pre_idx; ++ bfa_log_info[cur_mod_id].total_count = idx - pre_idx; ++ bfa_log_msg_total_count = idx; ++ ++ cbfn(log_mod, msg_id, "%s%s log: init OK, msg total count %u\n", ++ BFA_LOG_CAT_NAME, ++ bfa_log_severity[BFA_LOG_INFO], bfa_log_msg_total_count); ++ ++ bfa_log_initialized = 1; ++ ++ return 0; ++} ++ ++/** ++ * BFA log set log level for a module ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] mod_id - module id ++ * @param[in] log_level - log severity level ++ * ++ * It return BFA_STATUS_OK on success, or > 0 on failure ++ */ ++bfa_status_t ++bfa_log_set_level(struct bfa_log_mod_s *log_mod, int mod_id, ++ enum bfa_log_severity log_level) ++{ ++ if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX) ++ return BFA_STATUS_EINVAL; ++ ++ if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX) ++ return BFA_STATUS_EINVAL; ++ ++ if (log_mod) ++ log_mod->log_level[mod_id] = log_level; ++ else ++ bfa_log_info[mod_id].level = log_level; ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * BFA log set log level for all modules ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] log_level - log severity level ++ * ++ * It return BFA_STATUS_OK on success, or > 0 on failure ++ */ ++bfa_status_t ++bfa_log_set_level_all(struct bfa_log_mod_s *log_mod, ++ enum bfa_log_severity log_level) ++{ ++ int mod_id = BFA_LOG_UNUSED_ID + 1; ++ ++ if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX) ++ return BFA_STATUS_EINVAL; ++ ++ if (log_mod) { ++ for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++) ++ log_mod->log_level[mod_id] = log_level; ++ } else { ++ for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++) ++ bfa_log_info[mod_id].level = log_level; ++ } ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * BFA log set log level for all aen sub-modules ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] log_level - log severity level ++ * ++ * It return BFA_STATUS_OK on success, or > 0 on failure ++ */ ++bfa_status_t ++bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod, ++ enum bfa_log_severity log_level) ++{ ++ int mod_id = BFA_LOG_AEN_MIN + 1; ++ ++ if (log_mod) { ++ for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++) ++ log_mod->log_level[mod_id] = log_level; ++ } else { ++ for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++) ++ bfa_log_info[mod_id].level = log_level; ++ } ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * BFA log get log level for a module ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] mod_id - module id ++ * ++ * It returns log level or -1 on error ++ */ ++enum bfa_log_severity ++bfa_log_get_level(struct bfa_log_mod_s *log_mod, int mod_id) ++{ ++ if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX) ++ return BFA_LOG_INVALID; ++ ++ if (log_mod) ++ return (log_mod->log_level[mod_id]); ++ else ++ return (bfa_log_info[mod_id].level); ++} ++ ++enum bfa_log_severity ++bfa_log_get_msg_level(struct bfa_log_mod_s *log_mod, u32 msg_id) ++{ ++ struct bfa_log_msgdef_s *msg; ++ u32 mod = BFA_LOG_GET_MOD_ID(msg_id); ++ u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1; ++ ++ if (!bfa_log_initialized) ++ return BFA_LOG_INVALID; ++ ++ if (mod > BFA_LOG_MODULE_ID_MAX) ++ return BFA_LOG_INVALID; ++ ++ if (idx >= bfa_log_info[mod].total_count) { ++ bfa_log_info[mod].cbfn(log_mod, msg_id, ++ "%s%s log: inconsistent idx %u vs. total count %u\n", ++ BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx, ++ bfa_log_info[mod].total_count); ++ return BFA_LOG_INVALID; ++ } ++ ++ msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx; ++ if (msg_id != BFA_LOG_GET_MSG_ID(msg)) { ++ bfa_log_info[mod].cbfn(log_mod, msg_id, ++ "%s%s log: inconsistent msg id %u array msg id %u\n", ++ BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], ++ msg_id, BFA_LOG_GET_MSG_ID(msg)); ++ return BFA_LOG_INVALID; ++ } ++ ++ return BFA_LOG_GET_SEVERITY(msg); ++} ++ ++/** ++ * BFA log message handling ++ * ++ * BFA log message handling finds the message based on message id and prints ++ * out the message based on its format and arguments. It also does prefix ++ * the severity etc. ++ * ++ * @param[in] log_mod - log module info ++ * @param[in] msg_id - message id ++ * @param[in] ... - message arguments ++ * ++ * It return 0 on success, or -1 on errors ++ */ ++int ++bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...) ++{ ++ va_list ap; ++ char buf[256]; ++ struct bfa_log_msgdef_s *msg; ++ int log_level; ++ u32 mod = BFA_LOG_GET_MOD_ID(msg_id); ++ u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1; ++ ++ if (!bfa_log_initialized) ++ return -1; ++ ++ if (mod > BFA_LOG_MODULE_ID_MAX) ++ return -1; ++ ++ if (idx >= bfa_log_info[mod].total_count) { ++ bfa_log_info[mod]. ++ cbfn ++ (log_mod, msg_id, ++ "%s%s log: inconsistent idx %u vs. total count %u\n", ++ BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx, ++ bfa_log_info[mod].total_count); ++ return -1; ++ } ++ ++ msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx; ++ if (msg_id != BFA_LOG_GET_MSG_ID(msg)) { ++ bfa_log_info[mod]. ++ cbfn ++ (log_mod, msg_id, ++ "%s%s log: inconsistent msg id %u array msg id %u\n", ++ BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], ++ msg_id, BFA_LOG_GET_MSG_ID(msg)); ++ return -1; ++ } ++ ++ log_level = log_mod ? log_mod->log_level[mod] : bfa_log_info[mod].level; ++ if ((BFA_LOG_GET_SEVERITY(msg) > log_level) && ++ (msg->attributes != BFA_LOG_ATTR_NONE)) ++ return 0; ++ ++ va_start(ap, msg_id); ++ bfa_os_vsprintf(buf, BFA_LOG_GET_MSG_FMT_STRING(msg), ap); ++ va_end(ap); ++ ++ if (log_mod) ++ log_mod->cbfn(log_mod, msg_id, "%s[%s]%s%s %s: %s\n", ++ BFA_LOG_CAT_NAME, log_mod->instance_info, ++ bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)], ++ (msg->attributes & BFA_LOG_ATTR_AUDIT) ++ ? " (audit) " : "", msg->msg_value, buf); ++ else ++ bfa_log_info[mod].cbfn(log_mod, msg_id, "%s%s%s %s: %s\n", ++ BFA_LOG_CAT_NAME, ++ bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)], ++ (msg->attributes & BFA_LOG_ATTR_AUDIT) ? ++ " (audit) " : "", msg->msg_value, buf); ++ ++ return 0; ++} ++ +diff --git a/drivers/scsi/bfa/bfa_log_module.c b/drivers/scsi/bfa/bfa_log_module.c +new file mode 100644 +index 0000000..5c154d3 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_log_module.c +@@ -0,0 +1,451 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct bfa_log_msgdef_s bfa_log_msg_array[] = { ++ ++ ++/* messages define for BFA_AEN_CAT_ADAPTER Module */ ++{BFA_AEN_ADAPTER_ADD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ADAPTER_ADD", ++ "New adapter found: SN = %s, base port WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_ADAPTER_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_ADAPTER_REMOVE", ++ "Adapter removed: SN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_AUDIT Module */ ++{BFA_AEN_AUDIT_AUTH_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_ENABLE", ++ "Authentication enabled for base port: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_AUDIT_AUTH_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_DISABLE", ++ "Authentication disabled for base port: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_ETHPORT Module */ ++{BFA_AEN_ETHPORT_LINKUP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ETHPORT_LINKUP", ++ "Base port ethernet linkup: mac = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_ETHPORT_LINKDOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ETHPORT_LINKDOWN", ++ "Base port ethernet linkdown: mac = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_ETHPORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ETHPORT_ENABLE", ++ "Base port ethernet interface enabled: mac = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_ETHPORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ETHPORT_DISABLE", ++ "Base port ethernet interface disabled: mac = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_IOC Module */ ++{BFA_AEN_IOC_HBGOOD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_IOC_HBGOOD", ++ "Heart Beat of IOC %d is good.", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_IOC_HBFAIL, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_CRITICAL, ++ "BFA_AEN_IOC_HBFAIL", ++ "Heart Beat of IOC %d has failed.", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_IOC_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_IOC_ENABLE", ++ "IOC %d is enabled.", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_IOC_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_IOC_DISABLE", ++ "IOC %d is disabled.", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_IOC_FWMISMATCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_CRITICAL, "BFA_AEN_IOC_FWMISMATCH", ++ "Running firmware version is incompatible with the driver version.", ++ (0), 0}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_ITNIM Module */ ++{BFA_AEN_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ITNIM_ONLINE", ++ "Target (WWN = %s) is online for initiator (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_ITNIM_OFFLINE", ++ "Target (WWN = %s) offlined by initiator (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_ITNIM_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_ERROR, "BFA_AEN_ITNIM_DISCONNECT", ++ "Target (WWN = %s) connectivity lost for initiator (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_LPORT Module */ ++{BFA_AEN_LPORT_NEW, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_LPORT_NEW", ++ "New logical port created: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_DELETE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_LPORT_DELETE", ++ "Logical port deleted: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_LPORT_ONLINE", ++ "Logical port online: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_LPORT_OFFLINE", ++ "Logical port taken offline: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_ERROR, "BFA_AEN_LPORT_DISCONNECT", ++ "Logical port lost fabric connectivity: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_NEW_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_LPORT_NEW_PROP", ++ "New virtual port created using proprietary interface: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_DELETE_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_PROP", ++ "Virtual port deleted using proprietary interface: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_NEW_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "BFA_AEN_LPORT_NEW_STANDARD", ++ "New virtual port created using standard interface: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_DELETE_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_STANDARD", ++ "Virtual port deleted using standard interface: WWN = %s, Role = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_LPORT_NPIV_DUP_WWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_DUP_WWN", ++ "Virtual port login failed. Duplicate WWN = %s reported by fabric.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_LPORT_NPIV_FABRIC_MAX, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_FABRIC_MAX", ++ "Virtual port (WWN = %s) login failed. Max NPIV ports already exist in" ++ " fabric/fport.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_LPORT_NPIV_UNKNOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_UNKNOWN", ++ "Virtual port (WWN = %s) login failed.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_PORT Module */ ++{BFA_AEN_PORT_ONLINE, BFA_LOG_ATTR_NONE, BFA_LOG_INFO, "BFA_AEN_PORT_ONLINE", ++ "Base port online: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING, ++ "BFA_AEN_PORT_OFFLINE", ++ "Base port offline: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_RLIR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_PORT_RLIR", ++ "RLIR event not supported.", ++ (0), 0}, ++ ++{BFA_AEN_PORT_SFP_INSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_PORT_SFP_INSERT", ++ "New SFP found: WWN/MAC = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_SFP_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_REMOVE", ++ "SFP removed: WWN/MAC = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_SFP_POM, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING, ++ "BFA_AEN_PORT_SFP_POM", ++ "SFP POM level to %s: WWN/MAC = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_PORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_PORT_ENABLE", ++ "Base port enabled: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_PORT_DISABLE", ++ "Base port disabled: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_AUTH_ON, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_PORT_AUTH_ON", ++ "Authentication successful for base port: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_AUTH_OFF, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR, ++ "BFA_AEN_PORT_AUTH_OFF", ++ "Authentication unsuccessful for base port: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR, ++ "BFA_AEN_PORT_DISCONNECT", ++ "Base port (WWN = %s) lost fabric connectivity.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_QOS_NEG, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING, ++ "BFA_AEN_PORT_QOS_NEG", ++ "QOS negotiation failed for base port: WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_FABRIC_NAME_CHANGE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_PORT_FABRIC_NAME_CHANGE", ++ "Base port WWN = %s, Fabric WWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_PORT_SFP_ACCESS_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_ACCESS_ERROR", ++ "SFP access error: WWN/MAC = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_AEN_PORT_SFP_UNSUPPORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_UNSUPPORT", ++ "Unsupported SFP found: WWN/MAC = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++ ++ ++ ++/* messages define for BFA_AEN_CAT_RPORT Module */ ++{BFA_AEN_RPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_RPORT_ONLINE", ++ "Remote port (WWN = %s) online for logical port (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_RPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_RPORT_OFFLINE", ++ "Remote port (WWN = %s) offlined by logical port (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_RPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_ERROR, "BFA_AEN_RPORT_DISCONNECT", ++ "Remote port (WWN = %s) connectivity lost for logical port (WWN = %s).", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2}, ++ ++{BFA_AEN_RPORT_QOS_PRIO, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_RPORT_QOS_PRIO", ++ "QOS priority changed to %s: RPWWN = %s and LPWWN = %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3}, ++ ++{BFA_AEN_RPORT_QOS_FLOWID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "BFA_AEN_RPORT_QOS_FLOWID", ++ "QOS flow ID changed to %d: RPWWN = %s and LPWWN = %s.", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3}, ++ ++ ++ ++ ++/* messages define for FCS Module */ ++{BFA_LOG_FCS_FABRIC_NOSWITCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "FCS_FABRIC_NOSWITCH", ++ "No switched fabric presence is detected.", ++ (0), 0}, ++ ++{BFA_LOG_FCS_FABRIC_ISOLATED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "FCS_FABRIC_ISOLATED", ++ "Port is isolated due to VF_ID mismatch. PWWN: %s, Port VF_ID: %04x and" ++ " switch port VF_ID: %04x.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_X << BFA_LOG_ARG1) | ++ (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3}, ++ ++ ++ ++ ++/* messages define for HAL Module */ ++{BFA_LOG_HAL_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR, ++ "HAL_ASSERT", ++ "Assertion failure: %s:%d: %s", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3}, ++ ++{BFA_LOG_HAL_HEARTBEAT_FAILURE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_CRITICAL, "HAL_HEARTBEAT_FAILURE", ++ "Firmware heartbeat failure at %d", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_HAL_FCPIM_PARM_INVALID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "HAL_FCPIM_PARM_INVALID", ++ "Driver configuration %s value %d is invalid. Value should be within" ++ " %d and %d.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) | ++ (BFA_LOG_D << BFA_LOG_ARG2) | (BFA_LOG_D << BFA_LOG_ARG3) | 0), 4}, ++ ++{BFA_LOG_HAL_SM_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR, ++ "HAL_SM_ASSERT", ++ "SM Assertion failure: %s:%d: event = %d", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) | ++ (BFA_LOG_D << BFA_LOG_ARG2) | 0), 3}, ++ ++ ++ ++ ++/* messages define for LINUX Module */ ++{BFA_LOG_LINUX_DEVICE_CLAIMED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_DEVICE_CLAIMED", ++ "bfa device at %s claimed.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_HASH_INIT_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_HASH_INIT_FAILED", ++ "Hash table initialization failure for the port %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_SYSFS_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_SYSFS_FAILED", ++ "sysfs file creation failure for the port %s.", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_MEM_ALLOC_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_MEM_ALLOC_FAILED", ++ "Memory allocation failed: %s. ", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED, ++ BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "LINUX_DRIVER_REGISTRATION_FAILED", ++ "%s. ", ++ ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_ITNIM_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "LINUX_ITNIM_FREE", ++ "scsi%d: FCID: %s WWPN: %s", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3}, ++ ++{BFA_LOG_LINUX_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_ITNIM_ONLINE", ++ "Target: %d:0:%d FCID: %s WWPN: %s", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4}, ++ ++{BFA_LOG_LINUX_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_ITNIM_OFFLINE", ++ "Target: %d:0:%d FCID: %s WWPN: %s", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) | ++ (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4}, ++ ++{BFA_LOG_LINUX_SCSI_HOST_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_SCSI_HOST_FREE", ++ "Free scsi%d", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1}, ++ ++{BFA_LOG_LINUX_SCSI_ABORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO, ++ "LINUX_SCSI_ABORT", ++ "scsi%d: abort cmnd %p, iotag %x", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) | ++ (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3}, ++ ++{BFA_LOG_LINUX_SCSI_ABORT_COMP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "LINUX_SCSI_ABORT_COMP", ++ "scsi%d: complete abort 0x%p, iotag 0x%x", ++ ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) | ++ (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3}, ++ ++ ++ ++ ++/* messages define for WDRV Module */ ++{BFA_LOG_WDRV_IOC_INIT_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_IOC_INIT_ERROR", ++ "IOC initialization has failed.", ++ (0), 0}, ++ ++{BFA_LOG_WDRV_IOC_INTERNAL_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_IOC_INTERNAL_ERROR", ++ "IOC internal error. ", ++ (0), 0}, ++ ++{BFA_LOG_WDRV_IOC_START_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_IOC_START_ERROR", ++ "IOC could not be started. ", ++ (0), 0}, ++ ++{BFA_LOG_WDRV_IOC_STOP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_IOC_STOP_ERROR", ++ "IOC could not be stopped. ", ++ (0), 0}, ++ ++{BFA_LOG_WDRV_INSUFFICIENT_RESOURCES, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_INSUFFICIENT_RESOURCES", ++ "Insufficient memory. ", ++ (0), 0}, ++ ++{BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, ++ BFA_LOG_INFO, "WDRV_BASE_ADDRESS_MAP_ERROR", ++ "Unable to map the IOC onto the system address space. ", ++ (0), 0}, ++ ++ ++{0, 0, 0, "", "", 0, 0}, ++}; +diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c +new file mode 100644 +index 0000000..9844b45 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_lps.c +@@ -0,0 +1,782 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, LPS); ++BFA_MODULE(lps); ++ ++#define BFA_LPS_MIN_LPORTS (1) ++#define BFA_LPS_MAX_LPORTS (256) ++ ++/** ++ * forward declarations ++ */ ++static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, ++ u32 *dm_len); ++static void bfa_lps_attach(struct bfa_s *bfa, void *bfad, ++ struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, ++ struct bfa_pcidev_s *pcidev); ++static void bfa_lps_initdone(struct bfa_s *bfa); ++static void bfa_lps_detach(struct bfa_s *bfa); ++static void bfa_lps_start(struct bfa_s *bfa); ++static void bfa_lps_stop(struct bfa_s *bfa); ++static void bfa_lps_iocdisable(struct bfa_s *bfa); ++static void bfa_lps_login_rsp(struct bfa_s *bfa, ++ struct bfi_lps_login_rsp_s *rsp); ++static void bfa_lps_logout_rsp(struct bfa_s *bfa, ++ struct bfi_lps_logout_rsp_s *rsp); ++static void bfa_lps_reqq_resume(void *lps_arg); ++static void bfa_lps_free(struct bfa_lps_s *lps); ++static void bfa_lps_send_login(struct bfa_lps_s *lps); ++static void bfa_lps_send_logout(struct bfa_lps_s *lps); ++static void bfa_lps_login_comp(struct bfa_lps_s *lps); ++static void bfa_lps_logout_comp(struct bfa_lps_s *lps); ++ ++ ++/** ++ * lps_pvt BFA LPS private functions ++ */ ++ ++enum bfa_lps_event { ++ BFA_LPS_SM_LOGIN = 1, /* login request from user */ ++ BFA_LPS_SM_LOGOUT = 2, /* logout request from user */ ++ BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */ ++ BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ ++ BFA_LPS_SM_DELETE = 5, /* lps delete from user */ ++ BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ ++}; ++ ++static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); ++static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event); ++static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, ++ enum bfa_lps_event event); ++static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event); ++static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event); ++static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, ++ enum bfa_lps_event event); ++ ++/** ++ * Init state -- no login ++ */ ++static void ++bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_LOGIN: ++ if (bfa_reqq_full(lps->bfa, lps->reqq)) { ++ bfa_sm_set_state(lps, bfa_lps_sm_loginwait); ++ bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); ++ } else { ++ bfa_sm_set_state(lps, bfa_lps_sm_login); ++ bfa_lps_send_login(lps); ++ } ++ break; ++ ++ case BFA_LPS_SM_LOGOUT: ++ bfa_lps_logout_comp(lps); ++ break; ++ ++ case BFA_LPS_SM_DELETE: ++ bfa_lps_free(lps); ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ break; ++ ++ case BFA_LPS_SM_FWRSP: ++ /* Could happen when fabric detects loopback and discards ++ * the lps request. Fw will eventually sent out the timeout ++ * Just ignore ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * login is in progress -- awaiting response from firmware ++ */ ++static void ++bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_FWRSP: ++ if (lps->status == BFA_STATUS_OK) ++ bfa_sm_set_state(lps, bfa_lps_sm_online); ++ else ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ bfa_lps_login_comp(lps); ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * login pending - awaiting space in request queue ++ */ ++static void ++bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_RESUME: ++ bfa_sm_set_state(lps, bfa_lps_sm_login); ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ bfa_reqq_wcancel(&lps->wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * login complete ++ */ ++static void ++bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_LOGOUT: ++ if (bfa_reqq_full(lps->bfa, lps->reqq)) { ++ bfa_sm_set_state(lps, bfa_lps_sm_logowait); ++ bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe); ++ } else { ++ bfa_sm_set_state(lps, bfa_lps_sm_logout); ++ bfa_lps_send_logout(lps); ++ } ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ case BFA_LPS_SM_DELETE: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * logout in progress - awaiting firmware response ++ */ ++static void ++bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_FWRSP: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ bfa_lps_logout_comp(lps); ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * logout pending -- awaiting space in request queue ++ */ ++static void ++bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event) ++{ ++ bfa_trc(lps->bfa, lps->lp_tag); ++ bfa_trc(lps->bfa, event); ++ ++ switch (event) { ++ case BFA_LPS_SM_RESUME: ++ bfa_sm_set_state(lps, bfa_lps_sm_logout); ++ bfa_lps_send_logout(lps); ++ break; ++ ++ case BFA_LPS_SM_OFFLINE: ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ bfa_reqq_wcancel(&lps->wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * lps_pvt BFA LPS private functions ++ */ ++ ++/** ++ * return memory requirement ++ */ ++static void ++bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) ++{ ++ if (cfg->drvcfg.min_cfg) ++ *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS; ++ else ++ *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS; ++} ++ ++/** ++ * bfa module attach at initialization time ++ */ ++static void ++bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps; ++ int i; ++ ++ bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s)); ++ mod->num_lps = BFA_LPS_MAX_LPORTS; ++ if (cfg->drvcfg.min_cfg) ++ mod->num_lps = BFA_LPS_MIN_LPORTS; ++ else ++ mod->num_lps = BFA_LPS_MAX_LPORTS; ++ mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo); ++ ++ bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s); ++ ++ INIT_LIST_HEAD(&mod->lps_free_q); ++ INIT_LIST_HEAD(&mod->lps_active_q); ++ ++ for (i = 0; i < mod->num_lps; i++, lps++) { ++ lps->bfa = bfa; ++ lps->lp_tag = (u8) i; ++ lps->reqq = BFA_REQQ_LPS; ++ bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps); ++ list_add_tail(&lps->qe, &mod->lps_free_q); ++ } ++} ++ ++static void ++bfa_lps_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_lps_detach(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_lps_start(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_lps_stop(struct bfa_s *bfa) ++{ ++} ++ ++/** ++ * IOC in disabled state -- consider all lps offline ++ */ ++static void ++bfa_lps_iocdisable(struct bfa_s *bfa) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &mod->lps_active_q) { ++ lps = (struct bfa_lps_s *) qe; ++ bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); ++ } ++} ++ ++/** ++ * Firmware login response ++ */ ++static void ++bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps; ++ ++ bfa_assert(rsp->lp_tag < mod->num_lps); ++ lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); ++ ++ lps->status = rsp->status; ++ switch (rsp->status) { ++ case BFA_STATUS_OK: ++ lps->fport = rsp->f_port; ++ lps->npiv_en = rsp->npiv_en; ++ lps->lp_pid = rsp->lp_pid; ++ lps->pr_bbcred = bfa_os_ntohs(rsp->bb_credit); ++ lps->pr_pwwn = rsp->port_name; ++ lps->pr_nwwn = rsp->node_name; ++ lps->auth_req = rsp->auth_req; ++ lps->lp_mac = rsp->lp_mac; ++ lps->brcd_switch = rsp->brcd_switch; ++ lps->fcf_mac = rsp->fcf_mac; ++ ++ break; ++ ++ case BFA_STATUS_FABRIC_RJT: ++ lps->lsrjt_rsn = rsp->lsrjt_rsn; ++ lps->lsrjt_expl = rsp->lsrjt_expl; ++ ++ break; ++ ++ case BFA_STATUS_EPROTOCOL: ++ lps->ext_status = rsp->ext_status; ++ ++ break; ++ ++ default: ++ /* Nothing to do with other status */ ++ break; ++ } ++ ++ bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); ++} ++ ++/** ++ * Firmware logout response ++ */ ++static void ++bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps; ++ ++ bfa_assert(rsp->lp_tag < mod->num_lps); ++ lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag); ++ ++ bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP); ++} ++ ++/** ++ * Space is available in request queue, resume queueing request to firmware. ++ */ ++static void ++bfa_lps_reqq_resume(void *lps_arg) ++{ ++ struct bfa_lps_s *lps = lps_arg; ++ ++ bfa_sm_send_event(lps, BFA_LPS_SM_RESUME); ++} ++ ++/** ++ * lps is freed -- triggered by vport delete ++ */ ++static void ++bfa_lps_free(struct bfa_lps_s *lps) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa); ++ ++ list_del(&lps->qe); ++ list_add_tail(&lps->qe, &mod->lps_free_q); ++} ++ ++/** ++ * send login request to firmware ++ */ ++static void ++bfa_lps_send_login(struct bfa_lps_s *lps) ++{ ++ struct bfi_lps_login_req_s *m; ++ ++ m = bfa_reqq_next(lps->bfa, lps->reqq); ++ bfa_assert(m); ++ ++ bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ, ++ bfa_lpuid(lps->bfa)); ++ ++ m->lp_tag = lps->lp_tag; ++ m->alpa = lps->alpa; ++ m->pdu_size = bfa_os_htons(lps->pdusz); ++ m->pwwn = lps->pwwn; ++ m->nwwn = lps->nwwn; ++ m->fdisc = lps->fdisc; ++ m->auth_en = lps->auth_en; ++ ++ bfa_reqq_produce(lps->bfa, lps->reqq); ++} ++ ++/** ++ * send logout request to firmware ++ */ ++static void ++bfa_lps_send_logout(struct bfa_lps_s *lps) ++{ ++ struct bfi_lps_logout_req_s *m; ++ ++ m = bfa_reqq_next(lps->bfa, lps->reqq); ++ bfa_assert(m); ++ ++ bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ, ++ bfa_lpuid(lps->bfa)); ++ ++ m->lp_tag = lps->lp_tag; ++ m->port_name = lps->pwwn; ++ bfa_reqq_produce(lps->bfa, lps->reqq); ++} ++ ++/** ++ * Indirect login completion handler for non-fcs ++ */ ++static void ++bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete) ++{ ++ struct bfa_lps_s *lps = arg; ++ ++ if (!complete) ++ return; ++ ++ if (lps->fdisc) ++ bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); ++ else ++ bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); ++} ++ ++/** ++ * Login completion handler -- direct call for fcs, queue for others ++ */ ++static void ++bfa_lps_login_comp(struct bfa_lps_s *lps) ++{ ++ if (!lps->bfa->fcs) { ++ bfa_cb_queue(lps->bfa, &lps->hcb_qe, ++ bfa_lps_login_comp_cb, lps); ++ return; ++ } ++ ++ if (lps->fdisc) ++ bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status); ++ else ++ bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status); ++} ++ ++/** ++ * Indirect logout completion handler for non-fcs ++ */ ++static void ++bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete) ++{ ++ struct bfa_lps_s *lps = arg; ++ ++ if (!complete) ++ return; ++ ++ if (lps->fdisc) ++ bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); ++ else ++ bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); ++} ++ ++/** ++ * Logout completion handler -- direct call for fcs, queue for others ++ */ ++static void ++bfa_lps_logout_comp(struct bfa_lps_s *lps) ++{ ++ if (!lps->bfa->fcs) { ++ bfa_cb_queue(lps->bfa, &lps->hcb_qe, ++ bfa_lps_logout_comp_cb, lps); ++ return; ++ } ++ if (lps->fdisc) ++ bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg); ++ else ++ bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); ++} ++ ++ ++ ++/** ++ * lps_public BFA LPS public functions ++ */ ++ ++/** ++ * Allocate a lport srvice tag. ++ */ ++struct bfa_lps_s * ++bfa_lps_alloc(struct bfa_s *bfa) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps = NULL; ++ ++ bfa_q_deq(&mod->lps_free_q, &lps); ++ ++ if (lps == NULL) ++ return NULL; ++ ++ list_add_tail(&lps->qe, &mod->lps_active_q); ++ ++ bfa_sm_set_state(lps, bfa_lps_sm_init); ++ return lps; ++} ++ ++/** ++ * Free lport service tag. This can be called anytime after an alloc. ++ * No need to wait for any pending login/logout completions. ++ */ ++void ++bfa_lps_delete(struct bfa_lps_s *lps) ++{ ++ bfa_sm_send_event(lps, BFA_LPS_SM_DELETE); ++} ++ ++/** ++ * Initiate a lport login. ++ */ ++void ++bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, ++ wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en) ++{ ++ lps->uarg = uarg; ++ lps->alpa = alpa; ++ lps->pdusz = pdusz; ++ lps->pwwn = pwwn; ++ lps->nwwn = nwwn; ++ lps->fdisc = BFA_FALSE; ++ lps->auth_en = auth_en; ++ bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); ++} ++ ++/** ++ * Initiate a lport fdisc login. ++ */ ++void ++bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, ++ wwn_t nwwn) ++{ ++ lps->uarg = uarg; ++ lps->alpa = 0; ++ lps->pdusz = pdusz; ++ lps->pwwn = pwwn; ++ lps->nwwn = nwwn; ++ lps->fdisc = BFA_TRUE; ++ lps->auth_en = BFA_FALSE; ++ bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN); ++} ++ ++/** ++ * Initiate a lport logout (flogi). ++ */ ++void ++bfa_lps_flogo(struct bfa_lps_s *lps) ++{ ++ bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); ++} ++ ++/** ++ * Initiate a lport FDSIC logout. ++ */ ++void ++bfa_lps_fdisclogo(struct bfa_lps_s *lps) ++{ ++ bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT); ++} ++ ++/** ++ * Discard a pending login request -- should be called only for ++ * link down handling. ++ */ ++void ++bfa_lps_discard(struct bfa_lps_s *lps) ++{ ++ bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE); ++} ++ ++/** ++ * Return lport services tag ++ */ ++u8 ++bfa_lps_get_tag(struct bfa_lps_s *lps) ++{ ++ return lps->lp_tag; ++} ++ ++/** ++ * Return lport services tag given the pid ++ */ ++u8 ++bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid) ++{ ++ struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); ++ struct bfa_lps_s *lps; ++ int i; ++ ++ for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) { ++ if (lps->lp_pid == pid) ++ return lps->lp_tag; ++ } ++ ++ /* Return base port tag anyway */ ++ return 0; ++} ++ ++/** ++ * return if fabric login indicates support for NPIV ++ */ ++bfa_boolean_t ++bfa_lps_is_npiv_en(struct bfa_lps_s *lps) ++{ ++ return lps->npiv_en; ++} ++ ++/** ++ * Return TRUE if attached to F-Port, else return FALSE ++ */ ++bfa_boolean_t ++bfa_lps_is_fport(struct bfa_lps_s *lps) ++{ ++ return lps->fport; ++} ++ ++/** ++ * Return TRUE if attached to a Brocade Fabric ++ */ ++bfa_boolean_t ++bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps) ++{ ++ return lps->brcd_switch; ++} ++/** ++ * return TRUE if authentication is required ++ */ ++bfa_boolean_t ++bfa_lps_is_authreq(struct bfa_lps_s *lps) ++{ ++ return lps->auth_req; ++} ++ ++bfa_eproto_status_t ++bfa_lps_get_extstatus(struct bfa_lps_s *lps) ++{ ++ return lps->ext_status; ++} ++ ++/** ++ * return port id assigned to the lport ++ */ ++u32 ++bfa_lps_get_pid(struct bfa_lps_s *lps) ++{ ++ return lps->lp_pid; ++} ++ ++/** ++ * Return bb_credit assigned in FLOGI response ++ */ ++u16 ++bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps) ++{ ++ return lps->pr_bbcred; ++} ++ ++/** ++ * Return peer port name ++ */ ++wwn_t ++bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps) ++{ ++ return lps->pr_pwwn; ++} ++ ++/** ++ * Return peer node name ++ */ ++wwn_t ++bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps) ++{ ++ return lps->pr_nwwn; ++} ++ ++/** ++ * return reason code if login request is rejected ++ */ ++u8 ++bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps) ++{ ++ return lps->lsrjt_rsn; ++} ++ ++/** ++ * return explanation code if login request is rejected ++ */ ++u8 ++bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps) ++{ ++ return lps->lsrjt_expl; ++} ++ ++ ++/** ++ * LPS firmware message class handler. ++ */ ++void ++bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ union bfi_lps_i2h_msg_u msg; ++ ++ bfa_trc(bfa, m->mhdr.msg_id); ++ msg.msg = m; ++ ++ switch (m->mhdr.msg_id) { ++ case BFI_LPS_H2I_LOGIN_RSP: ++ bfa_lps_login_rsp(bfa, msg.login_rsp); ++ break; ++ ++ case BFI_LPS_H2I_LOGOUT_RSP: ++ bfa_lps_logout_rsp(bfa, msg.logout_rsp); ++ break; ++ ++ default: ++ bfa_trc(bfa, m->mhdr.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_lps_priv.h b/drivers/scsi/bfa/bfa_lps_priv.h +new file mode 100644 +index 0000000..d16c6ce +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_lps_priv.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_LPS_PRIV_H__ ++#define __BFA_LPS_PRIV_H__ ++ ++#include ++ ++struct bfa_lps_mod_s { ++ struct list_head lps_free_q; ++ struct list_head lps_active_q; ++ struct bfa_lps_s *lps_arr; ++ int num_lps; ++}; ++ ++#define BFA_LPS_MOD(__bfa) (&(__bfa)->modules.lps_mod) ++#define BFA_LPS_FROM_TAG(__mod, __tag) (&(__mod)->lps_arr[__tag]) ++ ++/* ++ * external functions ++ */ ++void bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++ ++#endif /* __BFA_LPS_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c +new file mode 100644 +index 0000000..32eda8e +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_module.c +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++ ++/** ++ * BFA module list terminated by NULL ++ */ ++struct bfa_module_s *hal_mods[] = { ++ &hal_mod_sgpg, ++ &hal_mod_pport, ++ &hal_mod_fcxp, ++ &hal_mod_lps, ++ &hal_mod_uf, ++ &hal_mod_rport, ++ &hal_mod_fcpim, ++#ifdef BFA_CFG_PBIND ++ &hal_mod_pbind, ++#endif ++ NULL ++}; ++ ++/** ++ * Message handlers for various modules. ++ */ ++bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = { ++ bfa_isr_unhandled, /* NONE */ ++ bfa_isr_unhandled, /* BFI_MC_IOC */ ++ bfa_isr_unhandled, /* BFI_MC_DIAG */ ++ bfa_isr_unhandled, /* BFI_MC_FLASH */ ++ bfa_isr_unhandled, /* BFI_MC_CEE */ ++ bfa_pport_isr, /* BFI_MC_PORT */ ++ bfa_isr_unhandled, /* BFI_MC_IOCFC */ ++ bfa_isr_unhandled, /* BFI_MC_LL */ ++ bfa_uf_isr, /* BFI_MC_UF */ ++ bfa_fcxp_isr, /* BFI_MC_FCXP */ ++ bfa_lps_isr, /* BFI_MC_LPS */ ++ bfa_rport_isr, /* BFI_MC_RPORT */ ++ bfa_itnim_isr, /* BFI_MC_ITNIM */ ++ bfa_isr_unhandled, /* BFI_MC_IOIM_READ */ ++ bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */ ++ bfa_isr_unhandled, /* BFI_MC_IOIM_IO */ ++ bfa_ioim_isr, /* BFI_MC_IOIM */ ++ bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */ ++ bfa_tskim_isr, /* BFI_MC_TSKIM */ ++ bfa_isr_unhandled, /* BFI_MC_SBOOT */ ++ bfa_isr_unhandled, /* BFI_MC_IPFC */ ++ bfa_isr_unhandled, /* BFI_MC_PORT */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++ bfa_isr_unhandled, /* --------- */ ++}; ++ ++/** ++ * Message handlers for mailbox command classes ++ */ ++bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = { ++ NULL, ++ NULL, /* BFI_MC_IOC */ ++ NULL, /* BFI_MC_DIAG */ ++ NULL, /* BFI_MC_FLASH */ ++ NULL, /* BFI_MC_CEE */ ++ NULL, /* BFI_MC_PORT */ ++ bfa_iocfc_isr, /* BFI_MC_IOCFC */ ++ NULL, ++}; ++ +diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h +new file mode 100644 +index 0000000..96f7053 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_modules_priv.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_MODULES_PRIV_H__ ++#define __BFA_MODULES_PRIV_H__ ++ ++#include "bfa_uf_priv.h" ++#include "bfa_port_priv.h" ++#include "bfa_rport_priv.h" ++#include "bfa_fcxp_priv.h" ++#include "bfa_lps_priv.h" ++#include "bfa_fcpim_priv.h" ++#include ++#include ++ ++ ++struct bfa_modules_s { ++ struct bfa_pport_s pport; /* physical port module */ ++ struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */ ++ struct bfa_lps_mod_s lps_mod; /* fcxp module */ ++ struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */ ++ struct bfa_rport_mod_s rport_mod; /* remote port module */ ++ struct bfa_fcpim_mod_s fcpim_mod; /* FCP initiator module */ ++ struct bfa_sgpg_mod_s sgpg_mod; /* SG page module */ ++ struct bfa_cee_s cee; /* CEE Module */ ++ struct bfa_port_s port; /* Physical port module */ ++}; ++ ++#endif /* __BFA_MODULES_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_os_inc.h b/drivers/scsi/bfa/bfa_os_inc.h +new file mode 100644 +index 0000000..10a89f7 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_os_inc.h +@@ -0,0 +1,222 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * Contains declarations all OS Specific files needed for BFA layer ++ */ ++ ++#ifndef __BFA_OS_INC_H__ ++#define __BFA_OS_INC_H__ ++ ++#ifndef __KERNEL__ ++#include ++#else ++#include ++ ++#include ++#include ++ ++#include ++#define SET_MODULE_VERSION(VER) ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define BFA_ERR KERN_ERR ++#define BFA_WARNING KERN_WARNING ++#define BFA_NOTICE KERN_NOTICE ++#define BFA_INFO KERN_INFO ++#define BFA_DEBUG KERN_DEBUG ++ ++#define LOG_BFAD_INIT 0x00000001 ++#define LOG_FCP_IO 0x00000002 ++ ++#ifdef DEBUG ++#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...) \ ++ BFA_LOG(bfad, level, mask, fmt, ## arg) ++#define BFA_DEV_TRACE(bfad, level, fmt, arg...) \ ++ BFA_DEV_PRINTF(bfad, level, fmt, ## arg) ++#define BFA_TRACE(level, fmt, arg...) \ ++ BFA_PRINTF(level, fmt, ## arg) ++#else ++#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...) ++#define BFA_DEV_TRACE(bfad, level, fmt, arg...) ++#define BFA_TRACE(level, fmt, arg...) ++#endif ++ ++#define BFA_ASSERT(p) do { \ ++ if (!(p)) { \ ++ printk(KERN_ERR "assert(%s) failed at %s:%d\n", \ ++ #p, __FILE__, __LINE__); \ ++ BUG(); \ ++ } \ ++} while (0) ++ ++ ++#define BFA_LOG(bfad, level, mask, fmt, arg...) \ ++do { \ ++ if (((mask) & (((struct bfad_s *)(bfad))-> \ ++ cfg_data[cfg_log_mask])) || (level[1] <= '3')) \ ++ dev_printk(level, &(((struct bfad_s *) \ ++ (bfad))->pcidev->dev), fmt, ##arg); \ ++} while (0) ++ ++#ifndef BFA_DEV_PRINTF ++#define BFA_DEV_PRINTF(bfad, level, fmt, arg...) \ ++ dev_printk(level, &(((struct bfad_s *) \ ++ (bfad))->pcidev->dev), fmt, ##arg); ++#endif ++ ++#define BFA_PRINTF(level, fmt, arg...) \ ++ printk(level fmt, ##arg); ++ ++int bfa_os_MWB(void *); ++ ++#define bfa_os_mmiowb() mmiowb() ++ ++#define bfa_swap_3b(_x) \ ++ ((((_x) & 0xff) << 16) | \ ++ ((_x) & 0x00ff00) | \ ++ (((_x) & 0xff0000) >> 16)) ++ ++#define bfa_swap_8b(_x) \ ++ ((((_x) & 0xff00000000000000ull) >> 56) \ ++ | (((_x) & 0x00ff000000000000ull) >> 40) \ ++ | (((_x) & 0x0000ff0000000000ull) >> 24) \ ++ | (((_x) & 0x000000ff00000000ull) >> 8) \ ++ | (((_x) & 0x00000000ff000000ull) << 8) \ ++ | (((_x) & 0x0000000000ff0000ull) << 24) \ ++ | (((_x) & 0x000000000000ff00ull) << 40) \ ++ | (((_x) & 0x00000000000000ffull) << 56)) ++ ++#define bfa_os_swap32(_x) \ ++ ((((_x) & 0xff) << 24) | \ ++ (((_x) & 0x0000ff00) << 8) | \ ++ (((_x) & 0x00ff0000) >> 8) | \ ++ (((_x) & 0xff000000) >> 24)) ++ ++ ++#ifndef __BIGENDIAN ++#define bfa_os_htons(_x) ((u16)((((_x) & 0xff00) >> 8) | \ ++ (((_x) & 0x00ff) << 8))) ++ ++#define bfa_os_htonl(_x) bfa_os_swap32(_x) ++#define bfa_os_htonll(_x) bfa_swap_8b(_x) ++#define bfa_os_hton3b(_x) bfa_swap_3b(_x) ++ ++#define bfa_os_wtole(_x) (_x) ++ ++#else ++ ++#define bfa_os_htons(_x) (_x) ++#define bfa_os_htonl(_x) (_x) ++#define bfa_os_hton3b(_x) (_x) ++#define bfa_os_htonll(_x) (_x) ++#define bfa_os_wtole(_x) bfa_os_swap32(_x) ++ ++#endif ++ ++#define bfa_os_ntohs(_x) bfa_os_htons(_x) ++#define bfa_os_ntohl(_x) bfa_os_htonl(_x) ++#define bfa_os_ntohll(_x) bfa_os_htonll(_x) ++#define bfa_os_ntoh3b(_x) bfa_os_hton3b(_x) ++ ++#define bfa_os_u32(__pa64) ((__pa64) >> 32) ++ ++#define bfa_os_memset memset ++#define bfa_os_memcpy memcpy ++#define bfa_os_udelay udelay ++#define bfa_os_vsprintf vsprintf ++ ++#define bfa_os_assign(__t, __s) __t = __s ++ ++#define bfa_os_addr_t char __iomem * ++#define bfa_os_panic() ++ ++#define bfa_os_reg_read(_raddr) bfa_os_wtole(readl(_raddr)) ++#define bfa_os_reg_write(_raddr, _val) writel(bfa_os_wtole((_val)), (_raddr)) ++#define bfa_os_mem_read(_raddr, _off) \ ++ bfa_os_ntohl(readl(((_raddr) + (_off)))) ++#define bfa_os_mem_write(_raddr, _off, _val) \ ++ writel(bfa_os_htonl((_val)), ((_raddr) + (_off))) ++ ++#define BFA_TRC_TS(_trcm) \ ++ ({ \ ++ struct timeval tv; \ ++ \ ++ do_gettimeofday(&tv); \ ++ (tv.tv_sec*1000000+tv.tv_usec); \ ++ }) ++ ++struct bfa_log_mod_s; ++void bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id, ++ const char *fmt, ...); ++#endif ++ ++#define boolean_t int ++ ++/** ++ * For current time stamp, OS API will fill-in ++ */ ++struct bfa_timeval_s { ++ u32 tv_sec; /* seconds */ ++ u32 tv_usec; /* microseconds */ ++}; ++ ++void bfa_os_gettimeofday(struct bfa_timeval_s *tv); ++ ++static inline void ++wwn2str(char *wwn_str, u64 wwn) ++{ ++ union { ++ u64 wwn; ++ u8 byte[8]; ++ } w; ++ ++ w.wwn = wwn; ++ sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0], ++ w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5], ++ w.byte[6], w.byte[7]); ++} ++ ++static inline void ++fcid2str(char *fcid_str, u32 fcid) ++{ ++ union { ++ u32 fcid; ++ u8 byte[4]; ++ } f; ++ ++ f.fcid = fcid; ++ sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]); ++} ++ ++#endif /* __BFA_OS_INC_H__ */ +diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c +new file mode 100644 +index 0000000..cab1902 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_port.c +@@ -0,0 +1,460 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(CNA, PORT); ++ ++#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) ++#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc) ++ ++static void ++bfa_port_stats_swap(struct bfa_port_s *port, union bfa_pport_stats_u *stats) ++{ ++ u32 *dip = (u32 *) stats; ++ u32 t0, t1; ++ int i; ++ ++ for (i = 0; i < sizeof(union bfa_pport_stats_u) / sizeof(u32); ++ i += 2) { ++ t0 = dip[i]; ++ t1 = dip[i + 1]; ++#ifdef __BIGENDIAN ++ dip[i] = bfa_os_ntohl(t0); ++ dip[i + 1] = bfa_os_ntohl(t1); ++#else ++ dip[i] = bfa_os_ntohl(t1); ++ dip[i + 1] = bfa_os_ntohl(t0); ++#endif ++ } ++ ++ /** todo ++ * QoS stats r also swapped as 64bit; that structure also ++ * has to use 64 bit counters ++ */ ++} ++ ++/** ++ * bfa_port_enable_isr() ++ * ++ * ++ * @param[in] port - Pointer to the port module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status) ++{ ++ bfa_assert(0); ++} ++ ++/** ++ * bfa_port_disable_isr() ++ * ++ * ++ * @param[in] port - Pointer to the port module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status) ++{ ++ bfa_assert(0); ++} ++ ++/** ++ * bfa_port_get_stats_isr() ++ * ++ * ++ * @param[in] port - Pointer to the Port module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status) ++{ ++ port->stats_status = status; ++ port->stats_busy = BFA_FALSE; ++ ++ if (status == BFA_STATUS_OK) { ++ memcpy(port->stats, port->stats_dma.kva, ++ sizeof(union bfa_pport_stats_u)); ++ bfa_port_stats_swap(port, port->stats); ++ } ++ ++ if (port->stats_cbfn) { ++ port->stats_cbfn(port->stats_cbarg, status); ++ port->stats_cbfn = NULL; ++ } ++} ++ ++/** ++ * bfa_port_clear_stats_isr() ++ * ++ * ++ * @param[in] port - Pointer to the Port module ++ * status - Return status from the f/w ++ * ++ * @return void ++ */ ++static void ++bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status) ++{ ++ port->stats_status = status; ++ port->stats_busy = BFA_FALSE; ++ ++ if (port->stats_cbfn) { ++ port->stats_cbfn(port->stats_cbarg, status); ++ port->stats_cbfn = NULL; ++ } ++} ++ ++/** ++ * bfa_port_isr() ++ * ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return void ++ */ ++static void ++bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m) ++{ ++ struct bfa_port_s *port = (struct bfa_port_s *)cbarg; ++ union bfi_port_i2h_msg_u *i2hmsg; ++ ++ i2hmsg = (union bfi_port_i2h_msg_u *)m; ++ bfa_trc(port, m->mh.msg_id); ++ ++ switch (m->mh.msg_id) { ++ case BFI_PORT_I2H_ENABLE_RSP: ++ if (port->endis_pending == BFA_FALSE) ++ break; ++ bfa_port_enable_isr(port, i2hmsg->enable_rsp.status); ++ break; ++ ++ case BFI_PORT_I2H_DISABLE_RSP: ++ if (port->endis_pending == BFA_FALSE) ++ break; ++ bfa_port_disable_isr(port, i2hmsg->disable_rsp.status); ++ break; ++ ++ case BFI_PORT_I2H_GET_STATS_RSP: ++ /* ++ * Stats busy flag is still set? (may be cmd timed out) ++ */ ++ if (port->stats_busy == BFA_FALSE) ++ break; ++ bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status); ++ break; ++ ++ case BFI_PORT_I2H_CLEAR_STATS_RSP: ++ if (port->stats_busy == BFA_FALSE) ++ break; ++ bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * bfa_port_meminfo() ++ * ++ * ++ * @param[in] void ++ * ++ * @return Size of DMA region ++ */ ++u32 ++bfa_port_meminfo(void) ++{ ++ return BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), BFA_DMA_ALIGN_SZ); ++} ++ ++/** ++ * bfa_port_mem_claim() ++ * ++ * ++ * @param[in] port Port module pointer ++ * dma_kva Kernel Virtual Address of Port DMA Memory ++ * dma_pa Physical Address of Port DMA Memory ++ * ++ * @return void ++ */ ++void ++bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa) ++{ ++ port->stats_dma.kva = dma_kva; ++ port->stats_dma.pa = dma_pa; ++} ++ ++/** ++ * bfa_port_enable() ++ * ++ * Send the Port enable request to the f/w ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return Status ++ */ ++bfa_status_t ++bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, ++ void *cbarg) ++{ ++ struct bfi_port_generic_req_s *m; ++ ++ /** todo Not implemented */ ++ bfa_assert(0); ++ ++ if (!bfa_ioc_is_operational(port->ioc)) { ++ bfa_trc(port, BFA_STATUS_IOC_FAILURE); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ ++ if (port->endis_pending) { ++ bfa_trc(port, BFA_STATUS_DEVBUSY); ++ return BFA_STATUS_DEVBUSY; ++ } ++ ++ m = (struct bfi_port_generic_req_s *)port->endis_mb.msg; ++ ++ port->msgtag++; ++ port->endis_cbfn = cbfn; ++ port->endis_cbarg = cbarg; ++ port->endis_pending = BFA_TRUE; ++ ++ bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ, ++ bfa_ioc_portid(port->ioc)); ++ bfa_ioc_mbox_queue(port->ioc, &port->endis_mb); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_port_disable() ++ * ++ * Send the Port disable request to the f/w ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return Status ++ */ ++bfa_status_t ++bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn, ++ void *cbarg) ++{ ++ struct bfi_port_generic_req_s *m; ++ ++ /** todo Not implemented */ ++ bfa_assert(0); ++ ++ if (!bfa_ioc_is_operational(port->ioc)) { ++ bfa_trc(port, BFA_STATUS_IOC_FAILURE); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ ++ if (port->endis_pending) { ++ bfa_trc(port, BFA_STATUS_DEVBUSY); ++ return BFA_STATUS_DEVBUSY; ++ } ++ ++ m = (struct bfi_port_generic_req_s *)port->endis_mb.msg; ++ ++ port->msgtag++; ++ port->endis_cbfn = cbfn; ++ port->endis_cbarg = cbarg; ++ port->endis_pending = BFA_TRUE; ++ ++ bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ, ++ bfa_ioc_portid(port->ioc)); ++ bfa_ioc_mbox_queue(port->ioc, &port->endis_mb); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_port_get_stats() ++ * ++ * Send the request to the f/w to fetch Port statistics. ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return Status ++ */ ++bfa_status_t ++bfa_port_get_stats(struct bfa_port_s *port, union bfa_pport_stats_u *stats, ++ bfa_port_stats_cbfn_t cbfn, void *cbarg) ++{ ++ struct bfi_port_get_stats_req_s *m; ++ ++ if (!bfa_ioc_is_operational(port->ioc)) { ++ bfa_trc(port, BFA_STATUS_IOC_FAILURE); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ ++ if (port->stats_busy) { ++ bfa_trc(port, BFA_STATUS_DEVBUSY); ++ return BFA_STATUS_DEVBUSY; ++ } ++ ++ m = (struct bfi_port_get_stats_req_s *)port->stats_mb.msg; ++ ++ port->stats = stats; ++ port->stats_cbfn = cbfn; ++ port->stats_cbarg = cbarg; ++ port->stats_busy = BFA_TRUE; ++ bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa); ++ ++ bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ, ++ bfa_ioc_portid(port->ioc)); ++ bfa_ioc_mbox_queue(port->ioc, &port->stats_mb); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_port_clear_stats() ++ * ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return Status ++ */ ++bfa_status_t ++bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn, ++ void *cbarg) ++{ ++ struct bfi_port_generic_req_s *m; ++ ++ if (!bfa_ioc_is_operational(port->ioc)) { ++ bfa_trc(port, BFA_STATUS_IOC_FAILURE); ++ return BFA_STATUS_IOC_FAILURE; ++ } ++ ++ if (port->stats_busy) { ++ bfa_trc(port, BFA_STATUS_DEVBUSY); ++ return BFA_STATUS_DEVBUSY; ++ } ++ ++ m = (struct bfi_port_generic_req_s *)port->stats_mb.msg; ++ ++ port->stats_cbfn = cbfn; ++ port->stats_cbarg = cbarg; ++ port->stats_busy = BFA_TRUE; ++ ++ bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ, ++ bfa_ioc_portid(port->ioc)); ++ bfa_ioc_mbox_queue(port->ioc, &port->stats_mb); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * bfa_port_hbfail() ++ * ++ * ++ * @param[in] Pointer to the Port module data structure. ++ * ++ * @return void ++ */ ++void ++bfa_port_hbfail(void *arg) ++{ ++ struct bfa_port_s *port = (struct bfa_port_s *)arg; ++ ++ /* ++ * Fail any pending get_stats/clear_stats requests ++ */ ++ if (port->stats_busy) { ++ if (port->stats_cbfn) ++ port->stats_cbfn(port->dev, BFA_STATUS_FAILED); ++ port->stats_cbfn = NULL; ++ port->stats_busy = BFA_FALSE; ++ } ++ ++ /* ++ * Clear any enable/disable is pending ++ */ ++ if (port->endis_pending) { ++ if (port->endis_cbfn) ++ port->endis_cbfn(port->dev, BFA_STATUS_FAILED); ++ port->endis_cbfn = NULL; ++ port->endis_pending = BFA_FALSE; ++ } ++} ++ ++/** ++ * bfa_port_attach() ++ * ++ * ++ * @param[in] port - Pointer to the Port module data structure ++ * ioc - Pointer to the ioc module data structure ++ * dev - Pointer to the device driver module data structure ++ * The device driver specific mbox ISR functions have ++ * this pointer as one of the parameters. ++ * trcmod - ++ * logmod - ++ * ++ * @return void ++ */ ++void ++bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void *dev, ++ struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod) ++{ ++ bfa_assert(port); ++ ++ port->dev = dev; ++ port->ioc = ioc; ++ port->trcmod = trcmod; ++ port->logmod = logmod; ++ ++ port->stats_busy = port->endis_pending = BFA_FALSE; ++ port->stats_cbfn = port->endis_cbfn = NULL; ++ ++ bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port); ++ bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port); ++ bfa_ioc_hbfail_register(port->ioc, &port->hbfail); ++ ++ bfa_trc(port, 0); ++} ++ ++/** ++ * bfa_port_detach() ++ * ++ * ++ * @param[in] port - Pointer to the Port module data structure ++ * ++ * @return void ++ */ ++void ++bfa_port_detach(struct bfa_port_s *port) ++{ ++ bfa_trc(port, 0); ++} +diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h +new file mode 100644 +index 0000000..4b97e27 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_port_priv.h +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_PORT_PRIV_H__ ++#define __BFA_PORT_PRIV_H__ ++ ++#include ++#include ++#include "bfa_intr_priv.h" ++ ++/** ++ * BFA physical port data structure ++ */ ++struct bfa_pport_s { ++ struct bfa_s *bfa; /* parent BFA instance */ ++ bfa_sm_t sm; /* port state machine */ ++ wwn_t nwwn; /* node wwn of physical port */ ++ wwn_t pwwn; /* port wwn of physical oprt */ ++ enum bfa_pport_speed speed_sup; ++ /* supported speeds */ ++ enum bfa_pport_speed speed; /* current speed */ ++ enum bfa_pport_topology topology; /* current topology */ ++ u8 myalpa; /* my ALPA in LOOP topology */ ++ u8 rsvd[3]; ++ struct bfa_pport_cfg_s cfg; /* current port configuration */ ++ struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ ++ struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ ++ struct bfa_reqq_wait_s reqq_wait; ++ /* to wait for room in reqq */ ++ struct bfa_reqq_wait_s svcreq_wait; ++ /* to wait for room in reqq */ ++ struct bfa_reqq_wait_s stats_reqq_wait; ++ /* to wait for room in reqq (stats) */ ++ void *event_cbarg; ++ void (*event_cbfn) (void *cbarg, ++ bfa_pport_event_t event); ++ union { ++ union bfi_pport_i2h_msg_u i2hmsg; ++ } event_arg; ++ void *bfad; /* BFA driver handle */ ++ struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ ++ enum bfa_pport_linkstate hcb_event; ++ /* link event for callback */ ++ u32 msgtag; /* fimrware msg tag for reply */ ++ u8 *stats_kva; ++ u64 stats_pa; ++ union bfa_pport_stats_u *stats; /* pport stats */ ++ u32 mypid : 24; ++ u32 rsvd_b : 8; ++ struct bfa_timer_s timer; /* timer */ ++ union bfa_pport_stats_u *stats_ret; ++ /* driver stats location */ ++ bfa_status_t stats_status; ++ /* stats/statsclr status */ ++ bfa_boolean_t stats_busy; ++ /* outstanding stats/statsclr */ ++ bfa_boolean_t stats_qfull; ++ bfa_boolean_t diag_busy; ++ /* diag busy status */ ++ bfa_boolean_t beacon; ++ /* port beacon status */ ++ bfa_boolean_t link_e2e_beacon; ++ /* link beacon status */ ++ bfa_cb_pport_t stats_cbfn; ++ /* driver callback function */ ++ void *stats_cbarg; ++ /* *!< user callback arg */ ++}; ++ ++#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport) ++ ++/* ++ * public functions ++ */ ++void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++#endif /* __BFA_PORT_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h +new file mode 100644 +index 0000000..0747a6b +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_priv.h +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_PRIV_H__ ++#define __BFA_PRIV_H__ ++ ++#include "bfa_iocfc.h" ++#include "bfa_intr_priv.h" ++#include "bfa_trcmod_priv.h" ++#include "bfa_modules_priv.h" ++#include "bfa_fwimg_priv.h" ++#include ++#include ++ ++/** ++ * Macro to define a new BFA module ++ */ ++#define BFA_MODULE(__mod) \ ++ static void bfa_ ## __mod ## _meminfo( \ ++ struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, \ ++ u32 *dm_len); \ ++ static void bfa_ ## __mod ## _attach(struct bfa_s *bfa, \ ++ void *bfad, struct bfa_iocfc_cfg_s *cfg, \ ++ struct bfa_meminfo_s *meminfo, \ ++ struct bfa_pcidev_s *pcidev); \ ++ static void bfa_ ## __mod ## _initdone(struct bfa_s *bfa); \ ++ static void bfa_ ## __mod ## _detach(struct bfa_s *bfa); \ ++ static void bfa_ ## __mod ## _start(struct bfa_s *bfa); \ ++ static void bfa_ ## __mod ## _stop(struct bfa_s *bfa); \ ++ static void bfa_ ## __mod ## _iocdisable(struct bfa_s *bfa); \ ++ \ ++ extern struct bfa_module_s hal_mod_ ## __mod; \ ++ struct bfa_module_s hal_mod_ ## __mod = { \ ++ bfa_ ## __mod ## _meminfo, \ ++ bfa_ ## __mod ## _attach, \ ++ bfa_ ## __mod ## _initdone, \ ++ bfa_ ## __mod ## _detach, \ ++ bfa_ ## __mod ## _start, \ ++ bfa_ ## __mod ## _stop, \ ++ bfa_ ## __mod ## _iocdisable, \ ++ } ++ ++#define BFA_CACHELINE_SZ (256) ++ ++/** ++ * Structure used to interact between different BFA sub modules ++ * ++ * Each sub module needs to implement only the entry points relevant to it (and ++ * can leave entry points as NULL) ++ */ ++struct bfa_module_s { ++ void (*meminfo) (struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len); ++ void (*attach) (struct bfa_s *bfa, void *bfad, ++ struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, ++ struct bfa_pcidev_s *pcidev); ++ void (*initdone) (struct bfa_s *bfa); ++ void (*detach) (struct bfa_s *bfa); ++ void (*start) (struct bfa_s *bfa); ++ void (*stop) (struct bfa_s *bfa); ++ void (*iocdisable) (struct bfa_s *bfa); ++}; ++ ++extern struct bfa_module_s *hal_mods[]; ++ ++struct bfa_s { ++ void *bfad; /* BFA driver instance */ ++ struct bfa_aen_s *aen; /* AEN module */ ++ struct bfa_plog_s *plog; /* portlog buffer */ ++ struct bfa_log_mod_s *logm; /* driver logging modulen */ ++ struct bfa_trc_mod_s *trcmod; /* driver tracing */ ++ struct bfa_ioc_s ioc; /* IOC module */ ++ struct bfa_iocfc_s iocfc; /* IOCFC module */ ++ struct bfa_timer_mod_s timer_mod; /* timer module */ ++ struct bfa_modules_s modules; /* BFA modules */ ++ struct list_head comp_q; /* pending completions */ ++ bfa_boolean_t rme_process; /* RME processing enabled */ ++ struct list_head reqq_waitq[BFI_IOC_MAX_CQS]; ++ bfa_boolean_t fcs; /* FCS is attached to BFA */ ++ struct bfa_msix_s msix; ++}; ++ ++extern bfa_isr_func_t bfa_isrs[BFI_MC_MAX]; ++extern bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[]; ++extern bfa_boolean_t bfa_auto_recover; ++extern struct bfa_module_s hal_mod_flash; ++extern struct bfa_module_s hal_mod_fcdiag; ++extern struct bfa_module_s hal_mod_sgpg; ++extern struct bfa_module_s hal_mod_pport; ++extern struct bfa_module_s hal_mod_fcxp; ++extern struct bfa_module_s hal_mod_lps; ++extern struct bfa_module_s hal_mod_uf; ++extern struct bfa_module_s hal_mod_rport; ++extern struct bfa_module_s hal_mod_fcpim; ++extern struct bfa_module_s hal_mod_pbind; ++ ++#endif /* __BFA_PRIV_H__ */ ++ +diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c +new file mode 100644 +index 0000000..16da77a +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_rport.c +@@ -0,0 +1,911 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "bfa_intr_priv.h" ++ ++BFA_TRC_FILE(HAL, RPORT); ++BFA_MODULE(rport); ++ ++#define bfa_rport_offline_cb(__rp) do { \ ++ if ((__rp)->bfa->fcs) \ ++ bfa_cb_rport_offline((__rp)->rport_drv); \ ++ else { \ ++ bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ ++ __bfa_cb_rport_offline, (__rp)); \ ++ } \ ++} while (0) ++ ++#define bfa_rport_online_cb(__rp) do { \ ++ if ((__rp)->bfa->fcs) \ ++ bfa_cb_rport_online((__rp)->rport_drv); \ ++ else { \ ++ bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \ ++ __bfa_cb_rport_online, (__rp)); \ ++ } \ ++} while (0) ++ ++/* ++ * forward declarations ++ */ ++static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod); ++static void bfa_rport_free(struct bfa_rport_s *rport); ++static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp); ++static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp); ++static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp); ++static void __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete); ++ ++/** ++ * bfa_rport_sm BFA rport state machine ++ */ ++ ++ ++enum bfa_rport_event { ++ BFA_RPORT_SM_CREATE = 1, /* rport create event */ ++ BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */ ++ BFA_RPORT_SM_ONLINE = 3, /* rport is online */ ++ BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */ ++ BFA_RPORT_SM_FWRSP = 5, /* firmware response */ ++ BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */ ++ BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */ ++ BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */ ++ BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */ ++}; ++ ++static void bfa_rport_sm_uninit(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_created(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_online(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_offline(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_deleting(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, ++ enum bfa_rport_event event); ++ ++/** ++ * Beginning state, only online event expected. ++ */ ++static void ++bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_CREATE: ++ bfa_stats(rp, sm_un_cr); ++ bfa_sm_set_state(rp, bfa_rport_sm_created); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_un_unexp); ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_ONLINE: ++ bfa_stats(rp, sm_cr_on); ++ if (bfa_rport_send_fwcreate(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_cr_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_cr_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_cr_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Waiting for rport create response from firmware. ++ */ ++static void ++bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_FWRSP: ++ bfa_stats(rp, sm_fwc_rsp); ++ bfa_sm_set_state(rp, bfa_rport_sm_online); ++ bfa_rport_online_cb(rp); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_fwc_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); ++ break; ++ ++ case BFA_RPORT_SM_OFFLINE: ++ bfa_stats(rp, sm_fwc_off); ++ bfa_sm_set_state(rp, bfa_rport_sm_offline_pending); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_fwc_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_fwc_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Request queue is full, awaiting queue resume to send create request. ++ */ ++static void ++bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_QRESUME: ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); ++ bfa_rport_send_fwcreate(rp); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_fwc_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_reqq_wcancel(&rp->reqq_wait); ++ bfa_rport_free(rp); ++ break; ++ ++ case BFA_RPORT_SM_OFFLINE: ++ bfa_stats(rp, sm_fwc_off); ++ bfa_sm_set_state(rp, bfa_rport_sm_offline); ++ bfa_reqq_wcancel(&rp->reqq_wait); ++ bfa_rport_offline_cb(rp); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_fwc_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ bfa_reqq_wcancel(&rp->reqq_wait); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_fwc_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Online state - normal parking state. ++ */ ++static void ++bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ struct bfi_rport_qos_scn_s *qos_scn; ++ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_OFFLINE: ++ bfa_stats(rp, sm_on_off); ++ if (bfa_rport_send_fwdelete(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_on_del); ++ if (bfa_rport_send_fwdelete(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_on_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ break; ++ ++ case BFA_RPORT_SM_SET_SPEED: ++ bfa_rport_send_fwspeed(rp); ++ break; ++ ++ case BFA_RPORT_SM_QOS_SCN: ++ qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg; ++ rp->qos_attr = qos_scn->new_qos_attr; ++ bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id); ++ bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id); ++ bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority); ++ bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority); ++ ++ qos_scn->old_qos_attr.qos_flow_id = ++ bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id); ++ qos_scn->new_qos_attr.qos_flow_id = ++ bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id); ++ qos_scn->old_qos_attr.qos_priority = ++ bfa_os_ntohl(qos_scn->old_qos_attr.qos_priority); ++ qos_scn->new_qos_attr.qos_priority = ++ bfa_os_ntohl(qos_scn->new_qos_attr.qos_priority); ++ ++ if (qos_scn->old_qos_attr.qos_flow_id != ++ qos_scn->new_qos_attr.qos_flow_id) ++ bfa_cb_rport_qos_scn_flowid(rp->rport_drv, ++ qos_scn->old_qos_attr, ++ qos_scn->new_qos_attr); ++ if (qos_scn->old_qos_attr.qos_priority != ++ qos_scn->new_qos_attr.qos_priority) ++ bfa_cb_rport_qos_scn_prio(rp->rport_drv, ++ qos_scn->old_qos_attr, ++ qos_scn->new_qos_attr); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_on_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Firmware rport is being deleted - awaiting f/w response. ++ */ ++static void ++bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_FWRSP: ++ bfa_stats(rp, sm_fwd_rsp); ++ bfa_sm_set_state(rp, bfa_rport_sm_offline); ++ bfa_rport_offline_cb(rp); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_fwd_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_fwd_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ bfa_rport_offline_cb(rp); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_fwd_unexp); ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_QRESUME: ++ bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); ++ bfa_rport_send_fwdelete(rp); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_fwd_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_fwd_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ bfa_reqq_wcancel(&rp->reqq_wait); ++ bfa_rport_offline_cb(rp); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_fwd_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Offline state. ++ */ ++static void ++bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_off_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ case BFA_RPORT_SM_ONLINE: ++ bfa_stats(rp, sm_off_on); ++ if (bfa_rport_send_fwcreate(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_off_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_off_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is deleted, waiting for firmware response to delete. ++ */ ++static void ++bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_FWRSP: ++ bfa_stats(rp, sm_del_fwrsp); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_del_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_QRESUME: ++ bfa_stats(rp, sm_del_fwrsp); ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting); ++ bfa_rport_send_fwdelete(rp); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_del_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_reqq_wcancel(&rp->reqq_wait); ++ bfa_rport_free(rp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Waiting for rport create response from firmware. A delete is pending. ++ */ ++static void ++bfa_rport_sm_delete_pending(struct bfa_rport_s *rp, ++ enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_FWRSP: ++ bfa_stats(rp, sm_delp_fwrsp); ++ if (bfa_rport_send_fwdelete(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_delp_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_delp_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Waiting for rport create response from firmware. Rport offline is pending. ++ */ ++static void ++bfa_rport_sm_offline_pending(struct bfa_rport_s *rp, ++ enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_FWRSP: ++ bfa_stats(rp, sm_offp_fwrsp); ++ if (bfa_rport_send_fwdelete(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_fwdelete); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_offp_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_delete_pending); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ bfa_stats(rp, sm_offp_hwf); ++ bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); ++ break; ++ ++ default: ++ bfa_stats(rp, sm_offp_unexp); ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * IOC h/w failed. ++ */ ++static void ++bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event) ++{ ++ bfa_trc(rp->bfa, rp->rport_tag); ++ bfa_trc(rp->bfa, event); ++ ++ switch (event) { ++ case BFA_RPORT_SM_OFFLINE: ++ bfa_stats(rp, sm_iocd_off); ++ bfa_rport_offline_cb(rp); ++ break; ++ ++ case BFA_RPORT_SM_DELETE: ++ bfa_stats(rp, sm_iocd_del); ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ bfa_rport_free(rp); ++ break; ++ ++ case BFA_RPORT_SM_ONLINE: ++ bfa_stats(rp, sm_iocd_on); ++ if (bfa_rport_send_fwcreate(rp)) ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate); ++ else ++ bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull); ++ break; ++ ++ case BFA_RPORT_SM_HWFAIL: ++ break; ++ ++ default: ++ bfa_stats(rp, sm_iocd_unexp); ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_rport_private BFA rport private functions ++ */ ++ ++static void ++__bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_rport_s *rp = cbarg; ++ ++ if (complete) ++ bfa_cb_rport_online(rp->rport_drv); ++} ++ ++static void ++__bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_rport_s *rp = cbarg; ++ ++ if (complete) ++ bfa_cb_rport_offline(rp->rport_drv); ++} ++ ++static void ++bfa_rport_qresume(void *cbarg) ++{ ++ struct bfa_rport_s *rp = cbarg; ++ ++ bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME); ++} ++ ++static void ++bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len) ++{ ++ if (cfg->fwcfg.num_rports < BFA_RPORT_MIN) ++ cfg->fwcfg.num_rports = BFA_RPORT_MIN; ++ ++ *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s); ++} ++ ++static void ++bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); ++ struct bfa_rport_s *rp; ++ u16 i; ++ ++ INIT_LIST_HEAD(&mod->rp_free_q); ++ INIT_LIST_HEAD(&mod->rp_active_q); ++ ++ rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo); ++ mod->rps_list = rp; ++ mod->num_rports = cfg->fwcfg.num_rports; ++ ++ bfa_assert(mod->num_rports ++ && !(mod->num_rports & (mod->num_rports - 1))); ++ ++ for (i = 0; i < mod->num_rports; i++, rp++) { ++ bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s)); ++ rp->bfa = bfa; ++ rp->rport_tag = i; ++ bfa_sm_set_state(rp, bfa_rport_sm_uninit); ++ ++ /** ++ * - is unused ++ */ ++ if (i) ++ list_add_tail(&rp->qe, &mod->rp_free_q); ++ ++ bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp); ++ } ++ ++ /** ++ * consume memory ++ */ ++ bfa_meminfo_kva(meminfo) = (u8 *) rp; ++} ++ ++static void ++bfa_rport_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_rport_detach(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_rport_start(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_rport_stop(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_rport_iocdisable(struct bfa_s *bfa) ++{ ++ struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa); ++ struct bfa_rport_s *rport; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &mod->rp_active_q) { ++ rport = (struct bfa_rport_s *) qe; ++ bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL); ++ } ++} ++ ++static struct bfa_rport_s * ++bfa_rport_alloc(struct bfa_rport_mod_s *mod) ++{ ++ struct bfa_rport_s *rport; ++ ++ bfa_q_deq(&mod->rp_free_q, &rport); ++ if (rport) ++ list_add_tail(&rport->qe, &mod->rp_active_q); ++ ++ return (rport); ++} ++ ++static void ++bfa_rport_free(struct bfa_rport_s *rport) ++{ ++ struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa); ++ ++ bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport)); ++ list_del(&rport->qe); ++ list_add_tail(&rport->qe, &mod->rp_free_q); ++} ++ ++static bfa_boolean_t ++bfa_rport_send_fwcreate(struct bfa_rport_s *rp) ++{ ++ struct bfi_rport_create_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); ++ if (!m) { ++ bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ, ++ bfa_lpuid(rp->bfa)); ++ m->bfa_handle = rp->rport_tag; ++ m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz); ++ m->pid = rp->rport_info.pid; ++ m->lp_tag = rp->rport_info.lp_tag; ++ m->local_pid = rp->rport_info.local_pid; ++ m->fc_class = rp->rport_info.fc_class; ++ m->vf_en = rp->rport_info.vf_en; ++ m->vf_id = rp->rport_info.vf_id; ++ m->cisc = rp->rport_info.cisc; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); ++ return BFA_TRUE; ++} ++ ++static bfa_boolean_t ++bfa_rport_send_fwdelete(struct bfa_rport_s *rp) ++{ ++ struct bfi_rport_delete_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); ++ if (!m) { ++ bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ, ++ bfa_lpuid(rp->bfa)); ++ m->fw_handle = rp->fw_handle; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); ++ return BFA_TRUE; ++} ++ ++static bfa_boolean_t ++bfa_rport_send_fwspeed(struct bfa_rport_s *rp) ++{ ++ struct bfa_rport_speed_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT); ++ if (!m) { ++ bfa_trc(rp->bfa, rp->rport_info.speed); ++ return BFA_FALSE; ++ } ++ ++ bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ, ++ bfa_lpuid(rp->bfa)); ++ m->fw_handle = rp->fw_handle; ++ m->speed = (u8)rp->rport_info.speed; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT); ++ return BFA_TRUE; ++} ++ ++ ++ ++/** ++ * bfa_rport_public ++ */ ++ ++/** ++ * Rport interrupt processing. ++ */ ++void ++bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ union bfi_rport_i2h_msg_u msg; ++ struct bfa_rport_s *rp; ++ ++ bfa_trc(bfa, m->mhdr.msg_id); ++ ++ msg.msg = m; ++ ++ switch (m->mhdr.msg_id) { ++ case BFI_RPORT_I2H_CREATE_RSP: ++ rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle); ++ rp->fw_handle = msg.create_rsp->fw_handle; ++ rp->qos_attr = msg.create_rsp->qos_attr; ++ bfa_assert(msg.create_rsp->status == BFA_STATUS_OK); ++ bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); ++ break; ++ ++ case BFI_RPORT_I2H_DELETE_RSP: ++ rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle); ++ bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK); ++ bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP); ++ break; ++ ++ case BFI_RPORT_I2H_QOS_SCN: ++ rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle); ++ rp->event_arg.fw_msg = msg.qos_scn_evt; ++ bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN); ++ break; ++ ++ default: ++ bfa_trc(bfa, m->mhdr.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_rport_api ++ */ ++ ++struct bfa_rport_s * ++bfa_rport_create(struct bfa_s *bfa, void *rport_drv) ++{ ++ struct bfa_rport_s *rp; ++ ++ rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa)); ++ ++ if (rp == NULL) ++ return (NULL); ++ ++ rp->bfa = bfa; ++ rp->rport_drv = rport_drv; ++ bfa_rport_clear_stats(rp); ++ ++ bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit)); ++ bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE); ++ ++ return (rp); ++} ++ ++void ++bfa_rport_delete(struct bfa_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE); ++} ++ ++void ++bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info) ++{ ++ bfa_assert(rport_info->max_frmsz != 0); ++ ++ /** ++ * Some JBODs are seen to be not setting PDU size correctly in PLOGI ++ * responses. Default to minimum size. ++ */ ++ if (rport_info->max_frmsz == 0) { ++ bfa_trc(rport->bfa, rport->rport_tag); ++ rport_info->max_frmsz = FC_MIN_PDUSZ; ++ } ++ ++ bfa_os_assign(rport->rport_info, *rport_info); ++ bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE); ++} ++ ++void ++bfa_rport_offline(struct bfa_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE); ++} ++ ++void ++bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed) ++{ ++ bfa_assert(speed != 0); ++ bfa_assert(speed != BFA_PPORT_SPEED_AUTO); ++ ++ rport->rport_info.speed = speed; ++ bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); ++} ++ ++void ++bfa_rport_get_stats(struct bfa_rport_s *rport, ++ struct bfa_rport_hal_stats_s *stats) ++{ ++ *stats = rport->stats; ++} ++ ++void ++bfa_rport_get_qos_attr(struct bfa_rport_s *rport, ++ struct bfa_rport_qos_attr_s *qos_attr) ++{ ++ qos_attr->qos_priority = bfa_os_ntohl(rport->qos_attr.qos_priority); ++ qos_attr->qos_flow_id = bfa_os_ntohl(rport->qos_attr.qos_flow_id); ++ ++} ++ ++void ++bfa_rport_clear_stats(struct bfa_rport_s *rport) ++{ ++ bfa_os_memset(&rport->stats, 0, sizeof(rport->stats)); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_rport_priv.h b/drivers/scsi/bfa/bfa_rport_priv.h +new file mode 100644 +index 0000000..6490ce2 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_rport_priv.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_RPORT_PRIV_H__ ++#define __BFA_RPORT_PRIV_H__ ++ ++#include ++ ++#define BFA_RPORT_MIN 4 ++ ++struct bfa_rport_mod_s { ++ struct bfa_rport_s *rps_list; /* list of rports */ ++ struct list_head rp_free_q; /* free bfa_rports */ ++ struct list_head rp_active_q; /* free bfa_rports */ ++ u16 num_rports; /* number of rports */ ++}; ++ ++#define BFA_RPORT_MOD(__bfa) (&(__bfa)->modules.rport_mod) ++ ++/** ++ * Convert rport tag to RPORT ++ */ ++#define BFA_RPORT_FROM_TAG(__bfa, _tag) \ ++ (BFA_RPORT_MOD(__bfa)->rps_list + \ ++ ((_tag) & (BFA_RPORT_MOD(__bfa)->num_rports - 1))) ++ ++/* ++ * external functions ++ */ ++void bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++#endif /* __BFA_RPORT_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_sgpg.c b/drivers/scsi/bfa/bfa_sgpg.c +new file mode 100644 +index 0000000..279d8f9 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_sgpg.c +@@ -0,0 +1,231 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++ ++BFA_TRC_FILE(HAL, SGPG); ++BFA_MODULE(sgpg); ++ ++/** ++ * bfa_sgpg_mod BFA SGPG Mode module ++ */ ++ ++/** ++ * Compute and return memory needed by FCP(im) module. ++ */ ++static void ++bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, ++ u32 *dm_len) ++{ ++ if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN) ++ cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN; ++ ++ *km_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfa_sgpg_s); ++ *dm_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfi_sgpg_s); ++} ++ ++ ++static void ++bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *minfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); ++ int i; ++ struct bfa_sgpg_s *hsgpg; ++ struct bfi_sgpg_s *sgpg; ++ u64 align_len; ++ ++ union { ++ u64 pa; ++ union bfi_addr_u addr; ++ } sgpg_pa; ++ ++ INIT_LIST_HEAD(&mod->sgpg_q); ++ INIT_LIST_HEAD(&mod->sgpg_wait_q); ++ ++ bfa_trc(bfa, cfg->drvcfg.num_sgpgs); ++ ++ mod->num_sgpgs = cfg->drvcfg.num_sgpgs; ++ mod->sgpg_arr_pa = bfa_meminfo_dma_phys(minfo); ++ align_len = (BFA_SGPG_ROUNDUP(mod->sgpg_arr_pa) - mod->sgpg_arr_pa); ++ mod->sgpg_arr_pa += align_len; ++ mod->hsgpg_arr = (struct bfa_sgpg_s *) (bfa_meminfo_kva(minfo) + ++ align_len); ++ mod->sgpg_arr = (struct bfi_sgpg_s *) (bfa_meminfo_dma_virt(minfo) + ++ align_len); ++ ++ hsgpg = mod->hsgpg_arr; ++ sgpg = mod->sgpg_arr; ++ sgpg_pa.pa = mod->sgpg_arr_pa; ++ mod->free_sgpgs = mod->num_sgpgs; ++ ++ bfa_assert(!(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1))); ++ ++ for (i = 0; i < mod->num_sgpgs; i++) { ++ bfa_os_memset(hsgpg, 0, sizeof(*hsgpg)); ++ bfa_os_memset(sgpg, 0, sizeof(*sgpg)); ++ ++ hsgpg->sgpg = sgpg; ++ hsgpg->sgpg_pa = sgpg_pa.addr; ++ list_add_tail(&hsgpg->qe, &mod->sgpg_q); ++ ++ hsgpg++; ++ sgpg++; ++ sgpg_pa.pa += sizeof(struct bfi_sgpg_s); ++ } ++ ++ bfa_meminfo_kva(minfo) = (u8 *) hsgpg; ++ bfa_meminfo_dma_virt(minfo) = (u8 *) sgpg; ++ bfa_meminfo_dma_phys(minfo) = sgpg_pa.pa; ++} ++ ++static void ++bfa_sgpg_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_sgpg_detach(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_sgpg_start(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_sgpg_stop(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_sgpg_iocdisable(struct bfa_s *bfa) ++{ ++} ++ ++ ++ ++/** ++ * bfa_sgpg_public BFA SGPG public functions ++ */ ++ ++bfa_status_t ++bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs) ++{ ++ struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); ++ struct bfa_sgpg_s *hsgpg; ++ int i; ++ ++ bfa_trc_fp(bfa, nsgpgs); ++ ++ if (mod->free_sgpgs < nsgpgs) ++ return BFA_STATUS_ENOMEM; ++ ++ for (i = 0; i < nsgpgs; i++) { ++ bfa_q_deq(&mod->sgpg_q, &hsgpg); ++ bfa_assert(hsgpg); ++ list_add_tail(&hsgpg->qe, sgpg_q); ++ } ++ ++ mod->free_sgpgs -= nsgpgs; ++ return BFA_STATUS_OK; ++} ++ ++void ++bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg) ++{ ++ struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); ++ struct bfa_sgpg_wqe_s *wqe; ++ ++ bfa_trc_fp(bfa, nsgpg); ++ ++ mod->free_sgpgs += nsgpg; ++ bfa_assert(mod->free_sgpgs <= mod->num_sgpgs); ++ ++ list_splice_tail_init(sgpg_q, &mod->sgpg_q); ++ ++ if (list_empty(&mod->sgpg_wait_q)) ++ return; ++ ++ /** ++ * satisfy as many waiting requests as possible ++ */ ++ do { ++ wqe = bfa_q_first(&mod->sgpg_wait_q); ++ if (mod->free_sgpgs < wqe->nsgpg) ++ nsgpg = mod->free_sgpgs; ++ else ++ nsgpg = wqe->nsgpg; ++ bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg); ++ wqe->nsgpg -= nsgpg; ++ if (wqe->nsgpg == 0) { ++ list_del(&wqe->qe); ++ wqe->cbfn(wqe->cbarg); ++ } ++ } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q)); ++} ++ ++void ++bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg) ++{ ++ struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); ++ ++ bfa_assert(nsgpg > 0); ++ bfa_assert(nsgpg > mod->free_sgpgs); ++ ++ wqe->nsgpg_total = wqe->nsgpg = nsgpg; ++ ++ /** ++ * allocate any left to this one first ++ */ ++ if (mod->free_sgpgs) { ++ /** ++ * no one else is waiting for SGPG ++ */ ++ bfa_assert(list_empty(&mod->sgpg_wait_q)); ++ list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q); ++ wqe->nsgpg -= mod->free_sgpgs; ++ mod->free_sgpgs = 0; ++ } ++ ++ list_add_tail(&wqe->qe, &mod->sgpg_wait_q); ++} ++ ++void ++bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe) ++{ ++ struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa); ++ ++ bfa_assert(bfa_q_is_on_q(&mod->sgpg_wait_q, wqe)); ++ list_del(&wqe->qe); ++ ++ if (wqe->nsgpg_total != wqe->nsgpg) ++ bfa_sgpg_mfree(bfa, &wqe->sgpg_q, ++ wqe->nsgpg_total - wqe->nsgpg); ++} ++ ++void ++bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg), ++ void *cbarg) ++{ ++ INIT_LIST_HEAD(&wqe->sgpg_q); ++ wqe->cbfn = cbfn; ++ wqe->cbarg = cbarg; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_sgpg_priv.h b/drivers/scsi/bfa/bfa_sgpg_priv.h +new file mode 100644 +index 0000000..9c2a8cb +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_sgpg_priv.h +@@ -0,0 +1,79 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * hal_sgpg.h BFA SG page module ++ */ ++ ++#ifndef __BFA_SGPG_PRIV_H__ ++#define __BFA_SGPG_PRIV_H__ ++ ++#include ++ ++#define BFA_SGPG_MIN (16) ++ ++/** ++ * Alignment macro for SG page allocation ++ */ ++#define BFA_SGPG_ROUNDUP(_l) (((_l) + (sizeof(struct bfi_sgpg_s) - 1)) \ ++ & ~(sizeof(struct bfi_sgpg_s) - 1)) ++ ++struct bfa_sgpg_wqe_s { ++ struct list_head qe; /* queue sg page element */ ++ int nsgpg; /* pages to be allocated */ ++ int nsgpg_total; /* total pages required */ ++ void (*cbfn) (void *cbarg); ++ /* callback function */ ++ void *cbarg; /* callback arg */ ++ struct list_head sgpg_q; /* queue of alloced sgpgs */ ++}; ++ ++struct bfa_sgpg_s { ++ struct list_head qe; /* queue sg page element */ ++ struct bfi_sgpg_s *sgpg; /* va of SG page */ ++ union bfi_addr_u sgpg_pa;/* pa of SG page */ ++}; ++ ++/** ++ * Given number of SG elements, BFA_SGPG_NPAGE() returns the number of ++ * SG pages required. ++ */ ++#define BFA_SGPG_NPAGE(_nsges) (((_nsges) / BFI_SGPG_DATA_SGES) + 1) ++ ++struct bfa_sgpg_mod_s { ++ struct bfa_s *bfa; ++ int num_sgpgs; /* number of SG pages */ ++ int free_sgpgs; /* number of free SG pages */ ++ struct bfa_sgpg_s *hsgpg_arr; /* BFA SG page array */ ++ struct bfi_sgpg_s *sgpg_arr; /* actual SG page array */ ++ u64 sgpg_arr_pa; /* SG page array DMA addr */ ++ struct list_head sgpg_q; /* queue of free SG pages */ ++ struct list_head sgpg_wait_q; /* wait queue for SG pages */ ++}; ++#define BFA_SGPG_MOD(__bfa) (&(__bfa)->modules.sgpg_mod) ++ ++bfa_status_t bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, ++ int nsgpgs); ++void bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, ++ int nsgpgs); ++void bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, ++ void (*cbfn) (void *cbarg), void *cbarg); ++void bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, ++ int nsgpgs); ++void bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe); ++ ++#endif /* __BFA_SGPG_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_sm.c b/drivers/scsi/bfa/bfa_sm.c +new file mode 100644 +index 0000000..5420f4f +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_sm.c +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfasm.c BFA State machine utility functions ++ */ ++ ++#include ++ ++/** ++ * cs_sm_api ++ */ ++ ++int ++bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm) ++{ ++ int i = 0; ++ ++ while (smt[i].sm && smt[i].sm != sm) ++ i++; ++ return smt[i].state; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_timer.c b/drivers/scsi/bfa/bfa_timer.c +new file mode 100644 +index 0000000..cb76481 +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_timer.c +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++void ++bfa_timer_init(struct bfa_timer_mod_s *mod) ++{ ++ INIT_LIST_HEAD(&mod->timer_q); ++} ++ ++void ++bfa_timer_beat(struct bfa_timer_mod_s *mod) ++{ ++ struct list_head *qh = &mod->timer_q; ++ struct list_head *qe, *qe_next; ++ struct bfa_timer_s *elem; ++ struct list_head timedout_q; ++ ++ INIT_LIST_HEAD(&timedout_q); ++ ++ qe = bfa_q_next(qh); ++ ++ while (qe != qh) { ++ qe_next = bfa_q_next(qe); ++ ++ elem = (struct bfa_timer_s *) qe; ++ if (elem->timeout <= BFA_TIMER_FREQ) { ++ elem->timeout = 0; ++ list_del(&elem->qe); ++ list_add_tail(&elem->qe, &timedout_q); ++ } else { ++ elem->timeout -= BFA_TIMER_FREQ; ++ } ++ ++ qe = qe_next; /* go to next elem */ ++ } ++ ++ /* ++ * Pop all the timeout entries ++ */ ++ while (!list_empty(&timedout_q)) { ++ bfa_q_deq(&timedout_q, &elem); ++ elem->timercb(elem->arg); ++ } ++} ++ ++/** ++ * Should be called with lock protection ++ */ ++void ++bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer, ++ void (*timercb) (void *), void *arg, unsigned int timeout) ++{ ++ ++ bfa_assert(timercb != NULL); ++ bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer)); ++ ++ timer->timeout = timeout; ++ timer->timercb = timercb; ++ timer->arg = arg; ++ ++ list_add_tail(&timer->qe, &mod->timer_q); ++} ++ ++/** ++ * Should be called with lock protection ++ */ ++void ++bfa_timer_stop(struct bfa_timer_s *timer) ++{ ++ bfa_assert(!list_empty(&timer->qe)); ++ ++ list_del(&timer->qe); ++} +diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h +new file mode 100644 +index 0000000..b3562dc +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_trcmod_priv.h +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * hal_trcmod.h BFA trace modules ++ */ ++ ++#ifndef __BFA_TRCMOD_PRIV_H__ ++#define __BFA_TRCMOD_PRIV_H__ ++ ++#include ++ ++/* ++ * !!! Only append to the enums defined here to avoid any versioning ++ * !!! needed between trace utility and driver version ++ */ ++enum { ++ BFA_TRC_HAL_IOC = 1, ++ BFA_TRC_HAL_INTR = 2, ++ BFA_TRC_HAL_FCXP = 3, ++ BFA_TRC_HAL_UF = 4, ++ BFA_TRC_HAL_DIAG = 5, ++ BFA_TRC_HAL_RPORT = 6, ++ BFA_TRC_HAL_FCPIM = 7, ++ BFA_TRC_HAL_IOIM = 8, ++ BFA_TRC_HAL_TSKIM = 9, ++ BFA_TRC_HAL_ITNIM = 10, ++ BFA_TRC_HAL_PPORT = 11, ++ BFA_TRC_HAL_SGPG = 12, ++ BFA_TRC_HAL_FLASH = 13, ++ BFA_TRC_HAL_DEBUG = 14, ++ BFA_TRC_HAL_WWN = 15, ++ BFA_TRC_HAL_FLASH_RAW = 16, ++ BFA_TRC_HAL_SBOOT = 17, ++ BFA_TRC_HAL_SBOOT_IO = 18, ++ BFA_TRC_HAL_SBOOT_INTR = 19, ++ BFA_TRC_HAL_SBTEST = 20, ++ BFA_TRC_HAL_IPFC = 21, ++ BFA_TRC_HAL_IOCFC = 22, ++ BFA_TRC_HAL_FCPTM = 23, ++ BFA_TRC_HAL_IOTM = 24, ++ BFA_TRC_HAL_TSKTM = 25, ++ BFA_TRC_HAL_TIN = 26, ++ BFA_TRC_HAL_LPS = 27, ++ BFA_TRC_HAL_FCDIAG = 28, ++ BFA_TRC_HAL_PBIND = 29, ++ BFA_TRC_HAL_IOCFC_CT = 30, ++ BFA_TRC_HAL_IOCFC_CB = 31, ++ BFA_TRC_HAL_IOCFC_Q = 32, ++}; ++ ++#endif /* __BFA_TRCMOD_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c +new file mode 100644 +index 0000000..010d40d +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_tskim.c +@@ -0,0 +1,689 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++ ++BFA_TRC_FILE(HAL, TSKIM); ++ ++/** ++ * task management completion handling ++ */ ++#define bfa_tskim_qcomp(__tskim, __cbfn) do { \ ++ bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim)); \ ++ bfa_tskim_notify_comp(__tskim); \ ++} while (0) ++ ++#define bfa_tskim_notify_comp(__tskim) do { \ ++ if ((__tskim)->notify) \ ++ bfa_itnim_tskdone((__tskim)->itnim); \ ++} while (0) ++ ++/* ++ * forward declarations ++ */ ++static void __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete); ++static void __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete); ++static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim, ++ lun_t lun); ++static void bfa_tskim_gather_ios(struct bfa_tskim_s *tskim); ++static void bfa_tskim_cleanp_comp(void *tskim_cbarg); ++static void bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim); ++static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim); ++static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim); ++static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim); ++ ++/** ++ * bfa_tskim_sm ++ */ ++ ++enum bfa_tskim_event { ++ BFA_TSKIM_SM_START = 1, /* TM command start */ ++ BFA_TSKIM_SM_DONE = 2, /* TM completion */ ++ BFA_TSKIM_SM_QRESUME = 3, /* resume after qfull */ ++ BFA_TSKIM_SM_HWFAIL = 5, /* IOC h/w failure event */ ++ BFA_TSKIM_SM_HCB = 6, /* BFA callback completion */ ++ BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */ ++ BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */ ++ BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */ ++}; ++ ++static void bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_active(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++static void bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event); ++ ++/** ++ * Task management command beginning state. ++ */ ++static void ++bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_START: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_active); ++ bfa_tskim_gather_ios(tskim); ++ ++ /** ++ * If device is offline, do not send TM on wire. Just cleanup ++ * any pending IO requests and complete TM request. ++ */ ++ if (!bfa_itnim_is_online(tskim->itnim)) { ++ bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); ++ tskim->tsk_status = BFI_TSKIM_STS_OK; ++ bfa_tskim_cleanup_ios(tskim); ++ return; ++ } ++ ++ if (!bfa_tskim_send(tskim)) { ++ bfa_sm_set_state(tskim, bfa_tskim_sm_qfull); ++ bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq, ++ &tskim->reqq_wait); ++ } ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * brief ++ * TM command is active, awaiting completion from firmware to ++ * cleanup IO requests in TM scope. ++ */ ++static void ++bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_DONE: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); ++ bfa_tskim_cleanup_ios(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_CLEANUP: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup); ++ if (!bfa_tskim_send_abort(tskim)) { ++ bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull); ++ bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq, ++ &tskim->reqq_wait); ++ } ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_tskim_iocdisable_ios(tskim); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * An active TM is being cleaned up since ITN is offline. Awaiting cleanup ++ * completion event from firmware. ++ */ ++static void ++bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_DONE: ++ /** ++ * Ignore and wait for ABORT completion from firmware. ++ */ ++ break; ++ ++ case BFA_TSKIM_SM_CLEANUP_DONE: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); ++ bfa_tskim_cleanup_ios(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_tskim_iocdisable_ios(tskim); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_IOS_DONE: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done); ++ break; ++ ++ case BFA_TSKIM_SM_CLEANUP: ++ /** ++ * Ignore, TM command completed on wire. ++ * Notify TM conmpletion on IO cleanup completion. ++ */ ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_tskim_iocdisable_ios(tskim); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Task management command is waiting for room in request CQ ++ */ ++static void ++bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_QRESUME: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_active); ++ bfa_tskim_send(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_CLEANUP: ++ /** ++ * No need to send TM on wire since ITN is offline. ++ */ ++ bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); ++ bfa_reqq_wcancel(&tskim->reqq_wait); ++ bfa_tskim_cleanup_ios(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_reqq_wcancel(&tskim->reqq_wait); ++ bfa_tskim_iocdisable_ios(tskim); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Task management command is active, awaiting for room in request CQ ++ * to send clean up request. ++ */ ++static void ++bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, ++ enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_DONE: ++ bfa_reqq_wcancel(&tskim->reqq_wait); ++ /** ++ * ++ * Fall through !!! ++ */ ++ ++ case BFA_TSKIM_SM_QRESUME: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup); ++ bfa_tskim_send_abort(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); ++ bfa_reqq_wcancel(&tskim->reqq_wait); ++ bfa_tskim_iocdisable_ios(tskim); ++ bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * BFA callback is pending ++ */ ++static void ++bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) ++{ ++ bfa_trc(tskim->bfa, event); ++ ++ switch (event) { ++ case BFA_TSKIM_SM_HCB: ++ bfa_sm_set_state(tskim, bfa_tskim_sm_uninit); ++ bfa_tskim_free(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_CLEANUP: ++ bfa_tskim_notify_comp(tskim); ++ break; ++ ++ case BFA_TSKIM_SM_HWFAIL: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * bfa_tskim_private ++ */ ++ ++static void ++__bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_tskim_s *tskim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB); ++ return; ++ } ++ ++ bfa_stats(tskim->itnim, tm_success); ++ bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status); ++} ++ ++static void ++__bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_tskim_s *tskim = cbarg; ++ ++ if (!complete) { ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB); ++ return; ++ } ++ ++ bfa_stats(tskim->itnim, tm_failures); ++ bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, ++ BFI_TSKIM_STS_FAILED); ++} ++ ++static bfa_boolean_t ++bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun) ++{ ++ switch (tskim->tm_cmnd) { ++ case FCP_TM_TARGET_RESET: ++ return BFA_TRUE; ++ ++ case FCP_TM_ABORT_TASK_SET: ++ case FCP_TM_CLEAR_TASK_SET: ++ case FCP_TM_LUN_RESET: ++ case FCP_TM_CLEAR_ACA: ++ return (tskim->lun == lun); ++ ++ default: ++ bfa_assert(0); ++ } ++ ++ return BFA_FALSE; ++} ++ ++/** ++ * Gather affected IO requests and task management commands. ++ */ ++static void ++bfa_tskim_gather_ios(struct bfa_tskim_s *tskim) ++{ ++ struct bfa_itnim_s *itnim = tskim->itnim; ++ struct bfa_ioim_s *ioim; ++ struct list_head *qe, *qen; ++ ++ INIT_LIST_HEAD(&tskim->io_q); ++ ++ /** ++ * Gather any active IO requests first. ++ */ ++ list_for_each_safe(qe, qen, &itnim->io_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ if (bfa_tskim_match_scope ++ (tskim, bfa_cb_ioim_get_lun(ioim->dio))) { ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &tskim->io_q); ++ } ++ } ++ ++ /** ++ * Failback any pending IO requests immediately. ++ */ ++ list_for_each_safe(qe, qen, &itnim->pending_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ if (bfa_tskim_match_scope ++ (tskim, bfa_cb_ioim_get_lun(ioim->dio))) { ++ list_del(&ioim->qe); ++ list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); ++ bfa_ioim_tov(ioim); ++ } ++ } ++} ++ ++/** ++ * IO cleanup completion ++ */ ++static void ++bfa_tskim_cleanp_comp(void *tskim_cbarg) ++{ ++ struct bfa_tskim_s *tskim = tskim_cbarg; ++ ++ bfa_stats(tskim->itnim, tm_io_comps); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE); ++} ++ ++/** ++ * Gather affected IO requests and task management commands. ++ */ ++static void ++bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim) ++{ ++ struct bfa_ioim_s *ioim; ++ struct list_head *qe, *qen; ++ ++ bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim); ++ ++ list_for_each_safe(qe, qen, &tskim->io_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ bfa_wc_up(&tskim->wc); ++ bfa_ioim_cleanup_tm(ioim, tskim); ++ } ++ ++ bfa_wc_wait(&tskim->wc); ++} ++ ++/** ++ * Send task management request to firmware. ++ */ ++static bfa_boolean_t ++bfa_tskim_send(struct bfa_tskim_s *tskim) ++{ ++ struct bfa_itnim_s *itnim = tskim->itnim; ++ struct bfi_tskim_req_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(tskim->bfa, itnim->reqq); ++ if (!m) ++ return BFA_FALSE; ++ ++ /** ++ * build i/o request message next ++ */ ++ bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ, ++ bfa_lpuid(tskim->bfa)); ++ ++ m->tsk_tag = bfa_os_htons(tskim->tsk_tag); ++ m->itn_fhdl = tskim->itnim->rport->fw_handle; ++ m->t_secs = tskim->tsecs; ++ m->lun = tskim->lun; ++ m->tm_flags = tskim->tm_cmnd; ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(tskim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++/** ++ * Send abort request to cleanup an active TM to firmware. ++ */ ++static bfa_boolean_t ++bfa_tskim_send_abort(struct bfa_tskim_s *tskim) ++{ ++ struct bfa_itnim_s *itnim = tskim->itnim; ++ struct bfi_tskim_abortreq_s *m; ++ ++ /** ++ * check for room in queue to send request now ++ */ ++ m = bfa_reqq_next(tskim->bfa, itnim->reqq); ++ if (!m) ++ return BFA_FALSE; ++ ++ /** ++ * build i/o request message next ++ */ ++ bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ, ++ bfa_lpuid(tskim->bfa)); ++ ++ m->tsk_tag = bfa_os_htons(tskim->tsk_tag); ++ ++ /** ++ * queue I/O message to firmware ++ */ ++ bfa_reqq_produce(tskim->bfa, itnim->reqq); ++ return BFA_TRUE; ++} ++ ++/** ++ * Call to resume task management cmnd waiting for room in request queue. ++ */ ++static void ++bfa_tskim_qresume(void *cbarg) ++{ ++ struct bfa_tskim_s *tskim = cbarg; ++ ++ bfa_fcpim_stats(tskim->fcpim, qresumes); ++ bfa_stats(tskim->itnim, tm_qresumes); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME); ++} ++ ++/** ++ * Cleanup IOs associated with a task mangement command on IOC failures. ++ */ ++static void ++bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim) ++{ ++ struct bfa_ioim_s *ioim; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &tskim->io_q) { ++ ioim = (struct bfa_ioim_s *) qe; ++ bfa_ioim_iocdisable(ioim); ++ } ++} ++ ++ ++ ++/** ++ * bfa_tskim_friend ++ */ ++ ++/** ++ * Notification on completions from related ioim. ++ */ ++void ++bfa_tskim_iodone(struct bfa_tskim_s *tskim) ++{ ++ bfa_wc_down(&tskim->wc); ++} ++ ++/** ++ * Handle IOC h/w failure notification from itnim. ++ */ ++void ++bfa_tskim_iocdisable(struct bfa_tskim_s *tskim) ++{ ++ tskim->notify = BFA_FALSE; ++ bfa_stats(tskim->itnim, tm_iocdowns); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL); ++} ++ ++/** ++ * Cleanup TM command and associated IOs as part of ITNIM offline. ++ */ ++void ++bfa_tskim_cleanup(struct bfa_tskim_s *tskim) ++{ ++ tskim->notify = BFA_TRUE; ++ bfa_stats(tskim->itnim, tm_cleanups); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP); ++} ++ ++/** ++ * Memory allocation and initialization. ++ */ ++void ++bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo) ++{ ++ struct bfa_tskim_s *tskim; ++ u16 i; ++ ++ INIT_LIST_HEAD(&fcpim->tskim_free_q); ++ ++ tskim = (struct bfa_tskim_s *) bfa_meminfo_kva(minfo); ++ fcpim->tskim_arr = tskim; ++ ++ for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) { ++ /* ++ * initialize TSKIM ++ */ ++ bfa_os_memset(tskim, 0, sizeof(struct bfa_tskim_s)); ++ tskim->tsk_tag = i; ++ tskim->bfa = fcpim->bfa; ++ tskim->fcpim = fcpim; ++ tskim->notify = BFA_FALSE; ++ bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume, ++ tskim); ++ bfa_sm_set_state(tskim, bfa_tskim_sm_uninit); ++ ++ list_add_tail(&tskim->qe, &fcpim->tskim_free_q); ++ } ++ ++ bfa_meminfo_kva(minfo) = (u8 *) tskim; ++} ++ ++void ++bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim) ++{ ++ /** ++ * @todo ++ */ ++} ++ ++void ++bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m; ++ struct bfa_tskim_s *tskim; ++ u16 tsk_tag = bfa_os_ntohs(rsp->tsk_tag); ++ ++ tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag); ++ bfa_assert(tskim->tsk_tag == tsk_tag); ++ ++ tskim->tsk_status = rsp->tsk_status; ++ ++ /** ++ * Firmware sends BFI_TSKIM_STS_ABORTED status for abort ++ * requests. All other statuses are for normal completions. ++ */ ++ if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) { ++ bfa_stats(tskim->itnim, tm_cleanup_comps); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE); ++ } else { ++ bfa_stats(tskim->itnim, tm_fw_rsps); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE); ++ } ++} ++ ++ ++ ++/** ++ * bfa_tskim_api ++ */ ++ ++ ++struct bfa_tskim_s * ++bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk) ++{ ++ struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); ++ struct bfa_tskim_s *tskim; ++ ++ bfa_q_deq(&fcpim->tskim_free_q, &tskim); ++ ++ if (!tskim) ++ bfa_fcpim_stats(fcpim, no_tskims); ++ else ++ tskim->dtsk = dtsk; ++ ++ return tskim; ++} ++ ++void ++bfa_tskim_free(struct bfa_tskim_s *tskim) ++{ ++ bfa_assert(bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe)); ++ list_del(&tskim->qe); ++ list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q); ++} ++ ++/** ++ * Start a task management command. ++ * ++ * @param[in] tskim BFA task management command instance ++ * @param[in] itnim i-t nexus for the task management command ++ * @param[in] lun lun, if applicable ++ * @param[in] tm_cmnd Task management command code. ++ * @param[in] t_secs Timeout in seconds ++ * ++ * @return None. ++ */ ++void ++bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun, ++ enum fcp_tm_cmnd tm_cmnd, u8 tsecs) ++{ ++ tskim->itnim = itnim; ++ tskim->lun = lun; ++ tskim->tm_cmnd = tm_cmnd; ++ tskim->tsecs = tsecs; ++ tskim->notify = BFA_FALSE; ++ bfa_stats(itnim, tm_cmnds); ++ ++ list_add_tail(&tskim->qe, &itnim->tsk_q); ++ bfa_sm_send_event(tskim, BFA_TSKIM_SM_START); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_uf.c b/drivers/scsi/bfa/bfa_uf.c +new file mode 100644 +index 0000000..ff5f9de +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_uf.c +@@ -0,0 +1,345 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_uf.c BFA unsolicited frame receive implementation ++ */ ++ ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(HAL, UF); ++BFA_MODULE(uf); ++ ++/* ++ ***************************************************************************** ++ * Internal functions ++ ***************************************************************************** ++ */ ++static void ++__bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete) ++{ ++ struct bfa_uf_s *uf = cbarg; ++ struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa); ++ ++ if (complete) ++ ufm->ufrecv(ufm->cbarg, uf); ++} ++ ++static void ++claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) ++{ ++ u32 uf_pb_tot_sz; ++ ++ ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi); ++ ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi); ++ uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs), ++ BFA_DMA_ALIGN_SZ); ++ ++ bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz; ++ bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz; ++ ++ bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz); ++} ++ ++static void ++claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) ++{ ++ struct bfi_uf_buf_post_s *uf_bp_msg; ++ struct bfi_sge_s *sge; ++ union bfi_addr_u sga_zero = { {0} }; ++ u16 i; ++ u16 buf_len; ++ ++ ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi); ++ uf_bp_msg = ufm->uf_buf_posts; ++ ++ for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs; ++ i++, uf_bp_msg++) { ++ bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s)); ++ ++ uf_bp_msg->buf_tag = i; ++ buf_len = sizeof(struct bfa_uf_buf_s); ++ uf_bp_msg->buf_len = bfa_os_htons(buf_len); ++ bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST, ++ bfa_lpuid(ufm->bfa)); ++ ++ sge = uf_bp_msg->sge; ++ sge[0].sg_len = buf_len; ++ sge[0].flags = BFI_SGE_DATA_LAST; ++ bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i)); ++ bfa_sge_to_be(sge); ++ ++ sge[1].sg_len = buf_len; ++ sge[1].flags = BFI_SGE_PGDLEN; ++ sge[1].sga = sga_zero; ++ bfa_sge_to_be(&sge[1]); ++ } ++ ++ /** ++ * advance pointer beyond consumed memory ++ */ ++ bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg; ++} ++ ++static void ++claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) ++{ ++ u16 i; ++ struct bfa_uf_s *uf; ++ ++ /* ++ * Claim block of memory for UF list ++ */ ++ ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi); ++ ++ /* ++ * Initialize UFs and queue it in UF free queue ++ */ ++ for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) { ++ bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s)); ++ uf->bfa = ufm->bfa; ++ uf->uf_tag = i; ++ uf->pb_len = sizeof(struct bfa_uf_buf_s); ++ uf->buf_kva = (void *)&ufm->uf_pbs_kva[i]; ++ uf->buf_pa = ufm_pbs_pa(ufm, i); ++ list_add_tail(&uf->qe, &ufm->uf_free_q); ++ } ++ ++ /** ++ * advance memory pointer ++ */ ++ bfa_meminfo_kva(mi) = (u8 *) uf; ++} ++ ++static void ++uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi) ++{ ++ claim_uf_pbs(ufm, mi); ++ claim_ufs(ufm, mi); ++ claim_uf_post_msgs(ufm, mi); ++} ++ ++static void ++bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len) ++{ ++ u32 num_ufs = cfg->fwcfg.num_uf_bufs; ++ ++ /* ++ * dma-able memory for UF posted bufs ++ */ ++ *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs), ++ BFA_DMA_ALIGN_SZ); ++ ++ /* ++ * kernel Virtual memory for UFs and UF buf post msg copies ++ */ ++ *ndm_len += sizeof(struct bfa_uf_s) * num_ufs; ++ *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs; ++} ++ ++static void ++bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev) ++{ ++ struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); ++ ++ bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s)); ++ ufm->bfa = bfa; ++ ufm->num_ufs = cfg->fwcfg.num_uf_bufs; ++ INIT_LIST_HEAD(&ufm->uf_free_q); ++ INIT_LIST_HEAD(&ufm->uf_posted_q); ++ ++ uf_mem_claim(ufm, meminfo); ++} ++ ++static void ++bfa_uf_initdone(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_uf_detach(struct bfa_s *bfa) ++{ ++} ++ ++static struct bfa_uf_s * ++bfa_uf_get(struct bfa_uf_mod_s *uf_mod) ++{ ++ struct bfa_uf_s *uf; ++ ++ bfa_q_deq(&uf_mod->uf_free_q, &uf); ++ return (uf); ++} ++ ++static void ++bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf) ++{ ++ list_add_tail(&uf->qe, &uf_mod->uf_free_q); ++} ++ ++static bfa_status_t ++bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf) ++{ ++ struct bfi_uf_buf_post_s *uf_post_msg; ++ ++ uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP); ++ if (!uf_post_msg) ++ return BFA_STATUS_FAILED; ++ ++ bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag], ++ sizeof(struct bfi_uf_buf_post_s)); ++ bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP); ++ ++ bfa_trc(ufm->bfa, uf->uf_tag); ++ ++ list_add_tail(&uf->qe, &ufm->uf_posted_q); ++ return BFA_STATUS_OK; ++} ++ ++static void ++bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod) ++{ ++ struct bfa_uf_s *uf; ++ ++ while ((uf = bfa_uf_get(uf_mod)) != NULL) { ++ if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK) ++ break; ++ } ++} ++ ++static void ++uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m) ++{ ++ struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); ++ u16 uf_tag = m->buf_tag; ++ struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag]; ++ struct bfa_uf_s *uf = &ufm->uf_list[uf_tag]; ++ u8 *buf = &uf_buf->d[0]; ++ struct fchs_s *fchs; ++ ++ m->frm_len = bfa_os_ntohs(m->frm_len); ++ m->xfr_len = bfa_os_ntohs(m->xfr_len); ++ ++ fchs = (struct fchs_s *) uf_buf; ++ ++ list_del(&uf->qe); /* dequeue from posted queue */ ++ ++ uf->data_ptr = buf; ++ uf->data_len = m->xfr_len; ++ ++ bfa_assert(uf->data_len >= sizeof(struct fchs_s)); ++ ++ if (uf->data_len == sizeof(struct fchs_s)) { ++ bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX, ++ uf->data_len, (struct fchs_s *) buf); ++ } else { ++ u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s))); ++ bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF, ++ BFA_PL_EID_RX, uf->data_len, ++ (struct fchs_s *) buf, pld_w0); ++ } ++ ++ bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf); ++} ++ ++static void ++bfa_uf_stop(struct bfa_s *bfa) ++{ ++} ++ ++static void ++bfa_uf_iocdisable(struct bfa_s *bfa) ++{ ++ struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); ++ struct bfa_uf_s *uf; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &ufm->uf_posted_q) { ++ uf = (struct bfa_uf_s *) qe; ++ list_del(&uf->qe); ++ bfa_uf_put(ufm, uf); ++ } ++} ++ ++static void ++bfa_uf_start(struct bfa_s *bfa) ++{ ++ bfa_uf_post_all(BFA_UF_MOD(bfa)); ++} ++ ++ ++ ++/** ++ * bfa_uf_api ++ */ ++ ++/** ++ * Register handler for all unsolicted recieve frames. ++ * ++ * @param[in] bfa BFA instance ++ * @param[in] ufrecv receive handler function ++ * @param[in] cbarg receive handler arg ++ */ ++void ++bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg) ++{ ++ struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa); ++ ++ ufm->ufrecv = ufrecv; ++ ufm->cbarg = cbarg; ++} ++ ++/** ++ * Free an unsolicited frame back to BFA. ++ * ++ * @param[in] uf unsolicited frame to be freed ++ * ++ * @return None ++ */ ++void ++bfa_uf_free(struct bfa_uf_s *uf) ++{ ++ bfa_uf_put(BFA_UF_MOD(uf->bfa), uf); ++ bfa_uf_post_all(BFA_UF_MOD(uf->bfa)); ++} ++ ++ ++ ++/** ++ * uf_pub BFA uf module public functions ++ */ ++ ++void ++bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg) ++{ ++ bfa_trc(bfa, msg->mhdr.msg_id); ++ ++ switch (msg->mhdr.msg_id) { ++ case BFI_UF_I2H_FRM_RCVD: ++ uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg); ++ break; ++ ++ default: ++ bfa_trc(bfa, msg->mhdr.msg_id); ++ bfa_assert(0); ++ } ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfa_uf_priv.h b/drivers/scsi/bfa/bfa_uf_priv.h +new file mode 100644 +index 0000000..bcb490f +--- /dev/null ++++ b/drivers/scsi/bfa/bfa_uf_priv.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_UF_PRIV_H__ ++#define __BFA_UF_PRIV_H__ ++ ++#include ++#include ++#include ++ ++#define BFA_UF_MIN (4) ++ ++struct bfa_uf_mod_s { ++ struct bfa_s *bfa; /* back pointer to BFA */ ++ struct bfa_uf_s *uf_list; /* array of UFs */ ++ u16 num_ufs; /* num unsolicited rx frames */ ++ struct list_head uf_free_q; /* free UFs */ ++ struct list_head uf_posted_q; /* UFs posted to IOC */ ++ struct bfa_uf_buf_s *uf_pbs_kva; /* list UF bufs request pld */ ++ u64 uf_pbs_pa; /* phy addr for UF bufs */ ++ struct bfi_uf_buf_post_s *uf_buf_posts; ++ /* pre-built UF post msgs */ ++ bfa_cb_uf_recv_t ufrecv; /* uf recv handler function */ ++ void *cbarg; /* uf receive handler arg */ ++}; ++ ++#define BFA_UF_MOD(__bfa) (&(__bfa)->modules.uf_mod) ++ ++#define ufm_pbs_pa(_ufmod, _uftag) \ ++ ((_ufmod)->uf_pbs_pa + sizeof(struct bfa_uf_buf_s) * (_uftag)) ++ ++void bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg); ++ ++#endif /* __BFA_UF_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c +new file mode 100644 +index 0000000..6f2be5a +--- /dev/null ++++ b/drivers/scsi/bfa/bfad.c +@@ -0,0 +1,1182 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfad.c Linux driver PCI interface module. ++ */ ++ ++#include ++#include "bfad_drv.h" ++#include "bfad_im.h" ++#include "bfad_tm.h" ++#include "bfad_ipfc.h" ++#include "bfad_trcmod.h" ++#include ++#include ++#include ++#include ++ ++BFA_TRC_FILE(LDRV, BFAD); ++static DEFINE_MUTEX(bfad_mutex); ++LIST_HEAD(bfad_list); ++static int bfad_inst; ++int bfad_supported_fc4s; ++ ++static char *host_name; ++static char *os_name; ++static char *os_patch; ++static int num_rports; ++static int num_ios; ++static int num_tms; ++static int num_fcxps; ++static int num_ufbufs; ++static int reqq_size; ++static int rspq_size; ++static int num_sgpgs; ++static int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; ++static int bfa_io_max_sge = BFAD_IO_MAX_SGE; ++static int log_level = BFA_LOG_WARNING; ++static int ioc_auto_recover = BFA_TRUE; ++static int ipfc_enable = BFA_FALSE; ++static int ipfc_mtu = -1; ++int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; ++int bfa_linkup_delay = -1; ++ ++module_param(os_name, charp, S_IRUGO | S_IWUSR); ++module_param(os_patch, charp, S_IRUGO | S_IWUSR); ++module_param(host_name, charp, S_IRUGO | S_IWUSR); ++module_param(num_rports, int, S_IRUGO | S_IWUSR); ++module_param(num_ios, int, S_IRUGO | S_IWUSR); ++module_param(num_tms, int, S_IRUGO | S_IWUSR); ++module_param(num_fcxps, int, S_IRUGO | S_IWUSR); ++module_param(num_ufbufs, int, S_IRUGO | S_IWUSR); ++module_param(reqq_size, int, S_IRUGO | S_IWUSR); ++module_param(rspq_size, int, S_IRUGO | S_IWUSR); ++module_param(num_sgpgs, int, S_IRUGO | S_IWUSR); ++module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR); ++module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR); ++module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); ++module_param(log_level, int, S_IRUGO | S_IWUSR); ++module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); ++module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); ++module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); ++module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); ++ ++/* ++ * Stores the module parm num_sgpgs value; ++ * used to reset for bfad next instance. ++ */ ++static int num_sgpgs_parm; ++ ++static bfa_status_t ++bfad_fc4_probe(struct bfad_s *bfad) ++{ ++ int rc; ++ ++ rc = bfad_im_probe(bfad); ++ if (rc != BFA_STATUS_OK) ++ goto ext; ++ ++ bfad_tm_probe(bfad); ++ ++ if (ipfc_enable) ++ bfad_ipfc_probe(bfad); ++ext: ++ return rc; ++} ++ ++static void ++bfad_fc4_probe_undo(struct bfad_s *bfad) ++{ ++ bfad_im_probe_undo(bfad); ++ bfad_tm_probe_undo(bfad); ++ if (ipfc_enable) ++ bfad_ipfc_probe_undo(bfad); ++} ++ ++static void ++bfad_fc4_probe_post(struct bfad_s *bfad) ++{ ++ if (bfad->im) ++ bfad_im_probe_post(bfad->im); ++ ++ bfad_tm_probe_post(bfad); ++ if (ipfc_enable) ++ bfad_ipfc_probe_post(bfad); ++} ++ ++static bfa_status_t ++bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles) ++{ ++ int rc = BFA_STATUS_FAILED; ++ ++ if (roles & BFA_PORT_ROLE_FCP_IM) ++ rc = bfad_im_port_new(bfad, port); ++ if (rc != BFA_STATUS_OK) ++ goto ext; ++ ++ if (roles & BFA_PORT_ROLE_FCP_TM) ++ rc = bfad_tm_port_new(bfad, port); ++ if (rc != BFA_STATUS_OK) ++ goto ext; ++ ++ if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) ++ rc = bfad_ipfc_port_new(bfad, port, port->pvb_type); ++ext: ++ return rc; ++} ++ ++static void ++bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles) ++{ ++ if (roles & BFA_PORT_ROLE_FCP_IM) ++ bfad_im_port_delete(bfad, port); ++ ++ if (roles & BFA_PORT_ROLE_FCP_TM) ++ bfad_tm_port_delete(bfad, port); ++ ++ if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) ++ bfad_ipfc_port_delete(bfad, port); ++} ++ ++/** ++ * BFA callbacks ++ */ ++void ++bfad_hcb_comp(void *arg, bfa_status_t status) ++{ ++ struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg; ++ ++ fcomp->status = status; ++ complete(&fcomp->comp); ++} ++ ++/** ++ * bfa_init callback ++ */ ++void ++bfa_cb_init(void *drv, bfa_status_t init_status) ++{ ++ struct bfad_s *bfad = drv; ++ ++ if (init_status == BFA_STATUS_OK) ++ bfad->bfad_flags |= BFAD_HAL_INIT_DONE; ++ ++ complete(&bfad->comp); ++} ++ ++ ++ ++/** ++ * BFA_FCS callbacks ++ */ ++static struct bfad_port_s * ++bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv, ++ struct bfad_vport_s *vp_drv) ++{ ++ return ((vp_drv) ? (&(vp_drv)->drv_port) ++ : ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport))); ++} ++ ++struct bfad_port_s * ++bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port, ++ enum bfa_port_role roles, struct bfad_vf_s *vf_drv, ++ struct bfad_vport_s *vp_drv) ++{ ++ bfa_status_t rc; ++ struct bfad_port_s *port_drv; ++ ++ if (!vp_drv && !vf_drv) { ++ port_drv = &bfad->pport; ++ port_drv->pvb_type = BFAD_PORT_PHYS_BASE; ++ } else if (!vp_drv && vf_drv) { ++ port_drv = &vf_drv->base_port; ++ port_drv->pvb_type = BFAD_PORT_VF_BASE; ++ } else if (vp_drv && !vf_drv) { ++ port_drv = &vp_drv->drv_port; ++ port_drv->pvb_type = BFAD_PORT_PHYS_VPORT; ++ } else { ++ port_drv = &vp_drv->drv_port; ++ port_drv->pvb_type = BFAD_PORT_VF_VPORT; ++ } ++ ++ port_drv->fcs_port = port; ++ port_drv->roles = roles; ++ rc = bfad_fc4_port_new(bfad, port_drv, roles); ++ if (rc != BFA_STATUS_OK) { ++ bfad_fc4_port_delete(bfad, port_drv, roles); ++ port_drv = NULL; ++ } ++ ++ return port_drv; ++} ++ ++void ++bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) ++{ ++ struct bfad_port_s *port_drv; ++ ++ /* ++ * this will be only called from rmmod context ++ */ ++ if (vp_drv && !vp_drv->comp_del) { ++ port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); ++ bfa_trc(bfad, roles); ++ bfad_fc4_port_delete(bfad, port_drv, roles); ++ } ++} ++ ++void ++bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) ++{ ++ struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); ++ ++ if (roles & BFA_PORT_ROLE_FCP_IM) ++ bfad_im_port_online(bfad, port_drv); ++ ++ if (roles & BFA_PORT_ROLE_FCP_TM) ++ bfad_tm_port_online(bfad, port_drv); ++ ++ if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) ++ bfad_ipfc_port_online(bfad, port_drv); ++ ++ bfad->bfad_flags |= BFAD_PORT_ONLINE; ++} ++ ++void ++bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) ++{ ++ struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); ++ ++ if (roles & BFA_PORT_ROLE_FCP_IM) ++ bfad_im_port_offline(bfad, port_drv); ++ ++ if (roles & BFA_PORT_ROLE_FCP_TM) ++ bfad_tm_port_offline(bfad, port_drv); ++ ++ if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) ++ bfad_ipfc_port_offline(bfad, port_drv); ++} ++ ++void ++bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv) ++{ ++ if (vport_drv->comp_del) { ++ complete(vport_drv->comp_del); ++ return; ++ } ++ ++ kfree(vport_drv); ++} ++ ++/** ++ * FCS RPORT alloc callback, after successful PLOGI by FCS ++ */ ++bfa_status_t ++bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport, ++ struct bfad_rport_s **rport_drv) ++{ ++ bfa_status_t rc = BFA_STATUS_OK; ++ ++ *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC); ++ if (*rport_drv == NULL) { ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ ++ *rport = &(*rport_drv)->fcs_rport; ++ ++ext: ++ return rc; ++} ++ ++ ++ ++void ++bfad_hal_mem_release(struct bfad_s *bfad) ++{ ++ int i; ++ struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; ++ struct bfa_mem_elem_s *meminfo_elem; ++ ++ for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { ++ meminfo_elem = &hal_meminfo->meminfo[i]; ++ if (meminfo_elem->kva != NULL) { ++ switch (meminfo_elem->mem_type) { ++ case BFA_MEM_TYPE_KVA: ++ vfree(meminfo_elem->kva); ++ break; ++ case BFA_MEM_TYPE_DMA: ++ dma_free_coherent(&bfad->pcidev->dev, ++ meminfo_elem->mem_len, ++ meminfo_elem->kva, ++ (dma_addr_t) meminfo_elem->dma); ++ break; ++ default: ++ bfa_assert(0); ++ break; ++ } ++ } ++ } ++ ++ memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s)); ++} ++ ++void ++bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg) ++{ ++ if (num_rports > 0) ++ bfa_cfg->fwcfg.num_rports = num_rports; ++ if (num_ios > 0) ++ bfa_cfg->fwcfg.num_ioim_reqs = num_ios; ++ if (num_tms > 0) ++ bfa_cfg->fwcfg.num_tskim_reqs = num_tms; ++ if (num_fcxps > 0) ++ bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps; ++ if (num_ufbufs > 0) ++ bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs; ++ if (reqq_size > 0) ++ bfa_cfg->drvcfg.num_reqq_elems = reqq_size; ++ if (rspq_size > 0) ++ bfa_cfg->drvcfg.num_rspq_elems = rspq_size; ++ if (num_sgpgs > 0) ++ bfa_cfg->drvcfg.num_sgpgs = num_sgpgs; ++ ++ /* ++ * populate the hal values back to the driver for sysfs use. ++ * otherwise, the default values will be shown as 0 in sysfs ++ */ ++ num_rports = bfa_cfg->fwcfg.num_rports; ++ num_ios = bfa_cfg->fwcfg.num_ioim_reqs; ++ num_tms = bfa_cfg->fwcfg.num_tskim_reqs; ++ num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs; ++ num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs; ++ reqq_size = bfa_cfg->drvcfg.num_reqq_elems; ++ rspq_size = bfa_cfg->drvcfg.num_rspq_elems; ++ num_sgpgs = bfa_cfg->drvcfg.num_sgpgs; ++} ++ ++bfa_status_t ++bfad_hal_mem_alloc(struct bfad_s *bfad) ++{ ++ struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; ++ struct bfa_mem_elem_s *meminfo_elem; ++ bfa_status_t rc = BFA_STATUS_OK; ++ dma_addr_t phys_addr; ++ int retry_count = 0; ++ int reset_value = 1; ++ int min_num_sgpgs = 512; ++ void *kva; ++ int i; ++ ++ bfa_cfg_get_default(&bfad->ioc_cfg); ++ ++retry: ++ bfad_update_hal_cfg(&bfad->ioc_cfg); ++ bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs; ++ bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo); ++ ++ for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { ++ meminfo_elem = &hal_meminfo->meminfo[i]; ++ switch (meminfo_elem->mem_type) { ++ case BFA_MEM_TYPE_KVA: ++ kva = vmalloc(meminfo_elem->mem_len); ++ if (kva == NULL) { ++ bfad_hal_mem_release(bfad); ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ memset(kva, 0, meminfo_elem->mem_len); ++ meminfo_elem->kva = kva; ++ break; ++ case BFA_MEM_TYPE_DMA: ++ kva = dma_alloc_coherent(&bfad->pcidev->dev, ++ meminfo_elem->mem_len, ++ &phys_addr, GFP_KERNEL); ++ if (kva == NULL) { ++ bfad_hal_mem_release(bfad); ++ /* ++ * If we cannot allocate with default ++ * num_sgpages try with half the value. ++ */ ++ if (num_sgpgs > min_num_sgpgs) { ++ printk(KERN_INFO "bfad[%d]: memory" ++ " allocation failed with" ++ " num_sgpgs: %d\n", ++ bfad->inst_no, num_sgpgs); ++ nextLowerInt(&num_sgpgs); ++ printk(KERN_INFO "bfad[%d]: trying to" ++ " allocate memory with" ++ " num_sgpgs: %d\n", ++ bfad->inst_no, num_sgpgs); ++ retry_count++; ++ goto retry; ++ } else { ++ if (num_sgpgs_parm > 0) ++ num_sgpgs = num_sgpgs_parm; ++ else { ++ reset_value = ++ (1 << retry_count); ++ num_sgpgs *= reset_value; ++ } ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ } ++ ++ if (num_sgpgs_parm > 0) ++ num_sgpgs = num_sgpgs_parm; ++ else { ++ reset_value = (1 << retry_count); ++ num_sgpgs *= reset_value; ++ } ++ ++ memset(kva, 0, meminfo_elem->mem_len); ++ meminfo_elem->kva = kva; ++ meminfo_elem->dma = phys_addr; ++ break; ++ default: ++ break; ++ ++ } ++ } ++ext: ++ return rc; ++} ++ ++/** ++ * Create a vport under a vf. ++ */ ++bfa_status_t ++bfad_vport_create(struct bfad_s *bfad, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg) ++{ ++ struct bfad_vport_s *vport; ++ int rc = BFA_STATUS_OK; ++ unsigned long flags; ++ struct completion fcomp; ++ ++ vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL); ++ if (!vport) { ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ ++ vport->drv_port.bfad = bfad; ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id, ++ port_cfg, vport); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (rc != BFA_STATUS_OK) ++ goto ext_free_vport; ++ ++ if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) { ++ rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port); ++ if (rc != BFA_STATUS_OK) ++ goto ext_free_fcs_vport; ++ } ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_fcs_vport_start(&vport->fcs_vport); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ return BFA_STATUS_OK; ++ ++ext_free_fcs_vport: ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ vport->comp_del = &fcomp; ++ init_completion(vport->comp_del); ++ bfa_fcs_vport_delete(&vport->fcs_vport); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ wait_for_completion(vport->comp_del); ++ext_free_vport: ++ kfree(vport); ++ext: ++ return rc; ++} ++ ++/** ++ * Create a vf and its base vport implicitely. ++ */ ++bfa_status_t ++bfad_vf_create(struct bfad_s *bfad, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg) ++{ ++ struct bfad_vf_s *vf; ++ int rc = BFA_STATUS_OK; ++ ++ vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL); ++ if (!vf) { ++ rc = BFA_STATUS_FAILED; ++ goto ext; ++ } ++ ++ rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg, ++ vf); ++ if (rc != BFA_STATUS_OK) ++ kfree(vf); ++ext: ++ return rc; ++} ++ ++void ++bfad_bfa_tmo(unsigned long data) ++{ ++ struct bfad_s *bfad = (struct bfad_s *)data; ++ unsigned long flags; ++ struct list_head doneq; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ bfa_timer_tick(&bfad->bfa); ++ ++ bfa_comp_deq(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (!list_empty(&doneq)) { ++ bfa_comp_process(&bfad->bfa, &doneq); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_comp_free(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ } ++ ++ mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); ++} ++ ++void ++bfad_init_timer(struct bfad_s *bfad) ++{ ++ init_timer(&bfad->hal_tmo); ++ bfad->hal_tmo.function = bfad_bfa_tmo; ++ bfad->hal_tmo.data = (unsigned long)bfad; ++ ++ mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); ++} ++ ++int ++bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad) ++{ ++ unsigned long bar0_len; ++ int rc = -ENODEV; ++ ++ if (pci_enable_device(pdev)) { ++ BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev); ++ goto out; ++ } ++ ++ if (pci_request_regions(pdev, BFAD_DRIVER_NAME)) ++ goto out_disable_device; ++ ++ pci_set_master(pdev); ++ ++ ++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) ++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { ++ BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev); ++ goto out_release_region; ++ } ++ ++ bfad->pci_bar0_map = pci_resource_start(pdev, 0); ++ bar0_len = pci_resource_len(pdev, 0); ++ bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len); ++ ++ if (bfad->pci_bar0_kva == NULL) { ++ BFA_PRINTF(BFA_ERR, "Fail to map bar0\n"); ++ goto out_release_region; ++ } ++ ++ bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn); ++ bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn); ++ bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva; ++ bfad->hal_pcidev.device_id = pdev->device; ++ bfad->pci_name = pci_name(pdev); ++ ++ bfad->pci_attr.vendor_id = pdev->vendor; ++ bfad->pci_attr.device_id = pdev->device; ++ bfad->pci_attr.ssid = pdev->subsystem_device; ++ bfad->pci_attr.ssvid = pdev->subsystem_vendor; ++ bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn); ++ ++ bfad->pcidev = pdev; ++ return 0; ++ ++out_release_region: ++ pci_release_regions(pdev); ++out_disable_device: ++ pci_disable_device(pdev); ++out: ++ return rc; ++} ++ ++void ++bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad) ++{ ++#if defined(__ia64__) ++ pci_iounmap(pdev, bfad->pci_bar0_kva); ++#else ++ iounmap(bfad->pci_bar0_kva); ++#endif ++ pci_release_regions(pdev); ++ pci_disable_device(pdev); ++ pci_set_drvdata(pdev, NULL); ++} ++ ++void ++bfad_fcs_port_cfg(struct bfad_s *bfad) ++{ ++ struct bfa_port_cfg_s port_cfg; ++ struct bfa_pport_attr_s attr; ++ char symname[BFA_SYMNAME_MAXLEN]; ++ ++ sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); ++ memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); ++ bfa_pport_get_attr(&bfad->bfa, &attr); ++ port_cfg.nwwn = attr.nwwn; ++ port_cfg.pwwn = attr.pwwn; ++ ++ bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg); ++} ++ ++bfa_status_t ++bfad_drv_init(struct bfad_s *bfad) ++{ ++ bfa_status_t rc; ++ unsigned long flags; ++ struct bfa_fcs_driver_info_s driver_info; ++ int i; ++ ++ bfad->cfg_data.rport_del_timeout = rport_del_timeout; ++ bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; ++ bfad->cfg_data.io_max_sge = bfa_io_max_sge; ++ bfad->cfg_data.binding_method = FCP_PWWN_BINDING; ++ ++ rc = bfad_hal_mem_alloc(bfad); ++ if (rc != BFA_STATUS_OK) { ++ printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n", ++ bfad->inst_no); ++ printk(KERN_WARNING ++ "Not enough memory to attach all Brocade HBA ports," ++ " System may need more memory.\n"); ++ goto out_hal_mem_alloc_failure; ++ } ++ ++ bfa_init_log(&bfad->bfa, bfad->logmod); ++ bfa_init_trc(&bfad->bfa, bfad->trcmod); ++ bfa_init_aen(&bfad->bfa, bfad->aen); ++ INIT_LIST_HEAD(&bfad->file_q); ++ INIT_LIST_HEAD(&bfad->file_free_q); ++ for (i = 0; i < BFAD_AEN_MAX_APPS; i++) { ++ bfa_q_qe_init(&bfad->file_buf[i].qe); ++ list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q); ++ } ++ bfa_init_plog(&bfad->bfa, &bfad->plog_buf); ++ bfa_plog_init(&bfad->plog_buf); ++ bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, ++ 0, "Driver Attach"); ++ ++ bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo, ++ &bfad->hal_pcidev); ++ ++ init_completion(&bfad->comp); ++ ++ /* ++ * Enable Interrupt and wait bfa_init completion ++ */ ++ if (bfad_setup_intr(bfad)) { ++ printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n", ++ bfad->inst_no); ++ goto out_setup_intr_failure; ++ } ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_init(&bfad->bfa); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ /* ++ * Set up interrupt handler for each vectors ++ */ ++ if ((bfad->bfad_flags & BFAD_MSIX_ON) ++ && bfad_install_msix_handler(bfad)) { ++ printk(KERN_WARNING "%s: install_msix failed, bfad%d\n", ++ __FUNCTION__, bfad->inst_no); ++ } ++ ++ bfad_init_timer(bfad); ++ ++ wait_for_completion(&bfad->comp); ++ ++ memset(&driver_info, 0, sizeof(driver_info)); ++ strncpy(driver_info.version, BFAD_DRIVER_VERSION, ++ sizeof(driver_info.version) - 1); ++ if (host_name) ++ strncpy(driver_info.host_machine_name, host_name, ++ sizeof(driver_info.host_machine_name) - 1); ++ if (os_name) ++ strncpy(driver_info.host_os_name, os_name, ++ sizeof(driver_info.host_os_name) - 1); ++ if (os_patch) ++ strncpy(driver_info.host_os_patch, os_patch, ++ sizeof(driver_info.host_os_patch) - 1); ++ ++ strncpy(driver_info.os_device_name, bfad->pci_name, ++ sizeof(driver_info.os_device_name - 1)); ++ ++ /* ++ * FCS INIT ++ */ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); ++ bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); ++ bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); ++ bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); ++ bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ bfad->bfad_flags |= BFAD_DRV_INIT_DONE; ++ return BFA_STATUS_OK; ++ ++out_setup_intr_failure: ++ bfa_detach(&bfad->bfa); ++ bfad_hal_mem_release(bfad); ++out_hal_mem_alloc_failure: ++ return BFA_STATUS_FAILED; ++} ++ ++void ++bfad_drv_uninit(struct bfad_s *bfad) ++{ ++ del_timer_sync(&bfad->hal_tmo); ++ bfa_isr_disable(&bfad->bfa); ++ bfa_detach(&bfad->bfa); ++ bfad_remove_intr(bfad); ++ bfa_assert(list_empty(&bfad->file_q)); ++ bfad_hal_mem_release(bfad); ++} ++ ++void ++bfad_drv_start(struct bfad_s *bfad) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_start(&bfad->bfa); ++ bfa_fcs_start(&bfad->bfa_fcs); ++ bfad->bfad_flags |= BFAD_HAL_START_DONE; ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ bfad_fc4_probe_post(bfad); ++} ++ ++void ++bfad_drv_stop(struct bfad_s *bfad) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ init_completion(&bfad->comp); ++ bfad->pport.flags |= BFAD_PORT_DELETE; ++ bfa_fcs_exit(&bfad->bfa_fcs); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ wait_for_completion(&bfad->comp); ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ init_completion(&bfad->comp); ++ bfa_stop(&bfad->bfa); ++ bfad->bfad_flags &= ~BFAD_HAL_START_DONE; ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ wait_for_completion(&bfad->comp); ++} ++ ++bfa_status_t ++bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role) ++{ ++ int rc = BFA_STATUS_OK; ++ ++ /* ++ * Allocate scsi_host for the physical port ++ */ ++ if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM) ++ && (role & BFA_PORT_ROLE_FCP_IM)) { ++ if (bfad->pport.im_port == NULL) { ++ rc = BFA_STATUS_FAILED; ++ goto out; ++ } ++ ++ rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port); ++ if (rc != BFA_STATUS_OK) ++ goto out; ++ ++ bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM; ++ } ++ ++ bfad->bfad_flags |= BFAD_CFG_PPORT_DONE; ++ ++out: ++ return rc; ++} ++ ++void ++bfad_uncfg_pport(struct bfad_s *bfad) ++{ ++ if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) { ++ bfad_ipfc_port_delete(bfad, &bfad->pport); ++ bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC; ++ } ++ ++ if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM) ++ && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) { ++ bfad_im_scsi_host_free(bfad, bfad->pport.im_port); ++ bfad_im_port_clean(bfad->pport.im_port); ++ kfree(bfad->pport.im_port); ++ bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM; ++ } ++ ++ bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE; ++} ++ ++void ++bfad_drv_log_level_set(struct bfad_s *bfad) ++{ ++ if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX) ++ bfa_log_set_level_all(&bfad->log_data, log_level); ++} ++ ++ /* ++ * PCI_entry PCI driver entries * { ++ */ ++ ++/** ++ * PCI probe entry. ++ */ ++int ++bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) ++{ ++ struct bfad_s *bfad; ++ int error = -ENODEV, retval; ++ char buf[16]; ++ ++ /* ++ * For single port cards - only claim function 0 ++ */ ++ if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) ++ && (PCI_FUNC(pdev->devfn) != 0)) ++ return -ENODEV; ++ ++ BFA_TRACE(BFA_INFO, "bfad_pci_probe entry"); ++ ++ bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL); ++ if (!bfad) { ++ error = -ENOMEM; ++ goto out; ++ } ++ ++ bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL); ++ if (!bfad->trcmod) { ++ printk(KERN_WARNING "Error alloc trace buffer!\n"); ++ error = -ENOMEM; ++ goto out_alloc_trace_failure; ++ } ++ ++ /* ++ * LOG/TRACE INIT ++ */ ++ bfa_trc_init(bfad->trcmod); ++ bfa_trc(bfad, bfad_inst); ++ ++ bfad->logmod = &bfad->log_data; ++ sprintf(buf, "%d", bfad_inst); ++ bfa_log_init(bfad->logmod, buf, bfa_os_printf); ++ ++ bfad_drv_log_level_set(bfad); ++ ++ bfad->aen = &bfad->aen_buf; ++ ++ if (!(bfad_load_fwimg(pdev))) { ++ printk(KERN_WARNING "bfad_load_fwimg failure!\n"); ++ kfree(bfad->trcmod); ++ goto out_alloc_trace_failure; ++ } ++ ++ retval = bfad_pci_init(pdev, bfad); ++ if (retval) { ++ printk(KERN_WARNING "bfad_pci_init failure!\n"); ++ error = retval; ++ goto out_pci_init_failure; ++ } ++ ++ mutex_lock(&bfad_mutex); ++ bfad->inst_no = bfad_inst++; ++ list_add_tail(&bfad->list_entry, &bfad_list); ++ mutex_unlock(&bfad_mutex); ++ ++ spin_lock_init(&bfad->bfad_lock); ++ pci_set_drvdata(pdev, bfad); ++ ++ bfad->ref_count = 0; ++ bfad->pport.bfad = bfad; ++ ++ retval = bfad_drv_init(bfad); ++ if (retval != BFA_STATUS_OK) ++ goto out_drv_init_failure; ++ if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { ++ printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); ++ goto ok; ++ } ++ ++ /* ++ * PPORT FCS config ++ */ ++ bfad_fcs_port_cfg(bfad); ++ ++ retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); ++ if (retval != BFA_STATUS_OK) ++ goto out_cfg_pport_failure; ++ ++ /* ++ * BFAD level FC4 (IM/TM/IPFC) specific resource allocation ++ */ ++ retval = bfad_fc4_probe(bfad); ++ if (retval != BFA_STATUS_OK) { ++ printk(KERN_WARNING "bfad_fc4_probe failed\n"); ++ goto out_fc4_probe_failure; ++ } ++ ++ bfad_drv_start(bfad); ++ ++ /* ++ * If bfa_linkup_delay is set to -1 default; try to retrive the ++ * value using the bfad_os_get_linkup_delay(); else use the ++ * passed in module param value as the bfa_linkup_delay. ++ */ ++ if (bfa_linkup_delay < 0) { ++ bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); ++ bfad_os_rport_online_wait(bfad); ++ bfa_linkup_delay = -1; ++ } else { ++ bfad_os_rport_online_wait(bfad); ++ } ++ ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); ++ok: ++ return 0; ++ ++out_fc4_probe_failure: ++ bfad_fc4_probe_undo(bfad); ++ bfad_uncfg_pport(bfad); ++out_cfg_pport_failure: ++ bfad_drv_uninit(bfad); ++out_drv_init_failure: ++ mutex_lock(&bfad_mutex); ++ bfad_inst--; ++ list_del(&bfad->list_entry); ++ mutex_unlock(&bfad_mutex); ++ bfad_pci_uninit(pdev, bfad); ++out_pci_init_failure: ++ kfree(bfad->trcmod); ++out_alloc_trace_failure: ++ kfree(bfad); ++out: ++ return error; ++} ++ ++/** ++ * PCI remove entry. ++ */ ++void ++bfad_pci_remove(struct pci_dev *pdev) ++{ ++ struct bfad_s *bfad = pci_get_drvdata(pdev); ++ unsigned long flags; ++ ++ bfa_trc(bfad, bfad->inst_no); ++ ++ if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) ++ && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ init_completion(&bfad->comp); ++ bfa_stop(&bfad->bfa); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ wait_for_completion(&bfad->comp); ++ ++ bfad_remove_intr(bfad); ++ del_timer_sync(&bfad->hal_tmo); ++ goto hal_detach; ++ } else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) { ++ goto remove_sysfs; ++ } ++ ++ if (bfad->bfad_flags & BFAD_HAL_START_DONE) ++ bfad_drv_stop(bfad); ++ ++ bfad_remove_intr(bfad); ++ ++ del_timer_sync(&bfad->hal_tmo); ++ bfad_fc4_probe_undo(bfad); ++ ++ if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) ++ bfad_uncfg_pport(bfad); ++ ++hal_detach: ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_detach(&bfad->bfa); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ bfad_hal_mem_release(bfad); ++remove_sysfs: ++ ++ mutex_lock(&bfad_mutex); ++ bfad_inst--; ++ list_del(&bfad->list_entry); ++ mutex_unlock(&bfad_mutex); ++ bfad_pci_uninit(pdev, bfad); ++ ++ kfree(bfad->trcmod); ++ kfree(bfad); ++} ++ ++ ++static struct pci_device_id bfad_id_table[] = { ++ { ++ .vendor = BFA_PCI_VENDOR_ID_BROCADE, ++ .device = BFA_PCI_DEVICE_ID_FC_8G2P, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = BFA_PCI_VENDOR_ID_BROCADE, ++ .device = BFA_PCI_DEVICE_ID_FC_8G1P, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ }, ++ { ++ .vendor = BFA_PCI_VENDOR_ID_BROCADE, ++ .device = BFA_PCI_DEVICE_ID_CT, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .class = (PCI_CLASS_SERIAL_FIBER << 8), ++ .class_mask = ~0, ++ }, ++ ++ {0, 0}, ++}; ++ ++MODULE_DEVICE_TABLE(pci, bfad_id_table); ++ ++static struct pci_driver bfad_pci_driver = { ++ .name = BFAD_DRIVER_NAME, ++ .id_table = bfad_id_table, ++ .probe = bfad_pci_probe, ++ .remove = __devexit_p(bfad_pci_remove), ++}; ++ ++/** ++ * Linux driver module functions ++ */ ++bfa_status_t ++bfad_fc4_module_init(void) ++{ ++ int rc; ++ ++ rc = bfad_im_module_init(); ++ if (rc != BFA_STATUS_OK) ++ goto ext; ++ ++ bfad_tm_module_init(); ++ if (ipfc_enable) ++ bfad_ipfc_module_init(); ++ext: ++ return rc; ++} ++ ++void ++bfad_fc4_module_exit(void) ++{ ++ if (ipfc_enable) ++ bfad_ipfc_module_exit(); ++ bfad_tm_module_exit(); ++ bfad_im_module_exit(); ++} ++ ++/** ++ * Driver module init. ++ */ ++static int __init ++bfad_init(void) ++{ ++ int error = 0; ++ ++ printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n", ++ BFAD_DRIVER_VERSION); ++ ++ if (num_sgpgs > 0) ++ num_sgpgs_parm = num_sgpgs; ++ ++ error = bfad_fc4_module_init(); ++ if (error) { ++ error = -ENOMEM; ++ printk(KERN_WARNING "bfad_fc4_module_init failure\n"); ++ goto ext; ++ } ++ ++ if (!strcmp(FCPI_NAME, " fcpim")) ++ bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM; ++ if (!strcmp(FCPT_NAME, " fcptm")) ++ bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM; ++ if (!strcmp(IPFC_NAME, " ipfc")) ++ bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC; ++ ++ bfa_ioc_auto_recover(ioc_auto_recover); ++ bfa_fcs_rport_set_del_timeout(rport_del_timeout); ++ error = pci_register_driver(&bfad_pci_driver); ++ ++ if (error) { ++ printk(KERN_WARNING "bfad pci_register_driver failure\n"); ++ goto ext; ++ } ++ ++ return 0; ++ ++ext: ++ bfad_fc4_module_exit(); ++ return error; ++} ++ ++/** ++ * Driver module exit. ++ */ ++static void __exit ++bfad_exit(void) ++{ ++ pci_unregister_driver(&bfad_pci_driver); ++ bfad_fc4_module_exit(); ++ bfad_free_fwimg(); ++} ++ ++#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME ++ ++module_init(bfad_init); ++module_exit(bfad_exit); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME); ++MODULE_AUTHOR("Brocade Communications Systems, Inc."); ++MODULE_VERSION(BFAD_DRIVER_VERSION); ++ ++ +diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c +new file mode 100644 +index 0000000..9129ae3 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_attr.c +@@ -0,0 +1,649 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_attr.c Linux driver configuration interface module. ++ */ ++ ++#include "bfad_drv.h" ++#include "bfad_im.h" ++#include "bfad_trcmod.h" ++#include "bfad_attr.h" ++ ++/** ++ * FC_transport_template FC transport template ++ */ ++ ++/** ++ * FC transport template entry, get SCSI target port ID. ++ */ ++void ++bfad_im_get_starget_port_id(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost; ++ struct bfad_im_port_s *im_port; ++ struct bfad_s *bfad; ++ struct bfad_itnim_s *itnim = NULL; ++ u32 fc_id = -1; ++ unsigned long flags; ++ ++ shost = bfad_os_starget_to_shost(starget); ++ im_port = (struct bfad_im_port_s *) shost->hostdata[0]; ++ bfad = im_port->bfad; ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ itnim = bfad_os_get_itnim(im_port, starget->id); ++ if (itnim) ++ fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); ++ ++ fc_starget_port_id(starget) = fc_id; ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++/** ++ * FC transport template entry, get SCSI target nwwn. ++ */ ++void ++bfad_im_get_starget_node_name(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost; ++ struct bfad_im_port_s *im_port; ++ struct bfad_s *bfad; ++ struct bfad_itnim_s *itnim = NULL; ++ u64 node_name = 0; ++ unsigned long flags; ++ ++ shost = bfad_os_starget_to_shost(starget); ++ im_port = (struct bfad_im_port_s *) shost->hostdata[0]; ++ bfad = im_port->bfad; ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ itnim = bfad_os_get_itnim(im_port, starget->id); ++ if (itnim) ++ node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim); ++ ++ fc_starget_node_name(starget) = bfa_os_htonll(node_name); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++/** ++ * FC transport template entry, get SCSI target pwwn. ++ */ ++void ++bfad_im_get_starget_port_name(struct scsi_target *starget) ++{ ++ struct Scsi_Host *shost; ++ struct bfad_im_port_s *im_port; ++ struct bfad_s *bfad; ++ struct bfad_itnim_s *itnim = NULL; ++ u64 port_name = 0; ++ unsigned long flags; ++ ++ shost = bfad_os_starget_to_shost(starget); ++ im_port = (struct bfad_im_port_s *) shost->hostdata[0]; ++ bfad = im_port->bfad; ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ itnim = bfad_os_get_itnim(im_port, starget->id); ++ if (itnim) ++ port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); ++ ++ fc_starget_port_name(starget) = bfa_os_htonll(port_name); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++/** ++ * FC transport template entry, get SCSI host port ID. ++ */ ++void ++bfad_im_get_host_port_id(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_port_s *port = im_port->port; ++ ++ fc_host_port_id(shost) = ++ bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port)); ++} ++ ++ ++ ++ ++ ++struct Scsi_Host * ++bfad_os_starget_to_shost(struct scsi_target *starget) ++{ ++ return dev_to_shost(starget->dev.parent); ++} ++ ++/** ++ * FC transport template entry, get SCSI host port type. ++ */ ++static void ++bfad_im_get_host_port_type(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_pport_attr_s attr; ++ ++ bfa_pport_get_attr(&bfad->bfa, &attr); ++ ++ switch (attr.port_type) { ++ case BFA_PPORT_TYPE_NPORT: ++ fc_host_port_type(shost) = FC_PORTTYPE_NPORT; ++ break; ++ case BFA_PPORT_TYPE_NLPORT: ++ fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; ++ break; ++ case BFA_PPORT_TYPE_P2P: ++ fc_host_port_type(shost) = FC_PORTTYPE_PTP; ++ break; ++ case BFA_PPORT_TYPE_LPORT: ++ fc_host_port_type(shost) = FC_PORTTYPE_LPORT; ++ break; ++ default: ++ fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; ++ break; ++ } ++} ++ ++/** ++ * FC transport template entry, get SCSI host port state. ++ */ ++static void ++bfad_im_get_host_port_state(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_pport_attr_s attr; ++ ++ bfa_pport_get_attr(&bfad->bfa, &attr); ++ ++ switch (attr.port_state) { ++ case BFA_PPORT_ST_LINKDOWN: ++ fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; ++ break; ++ case BFA_PPORT_ST_LINKUP: ++ fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; ++ break; ++ case BFA_PPORT_ST_UNINIT: ++ case BFA_PPORT_ST_ENABLING_QWAIT: ++ case BFA_PPORT_ST_ENABLING: ++ case BFA_PPORT_ST_DISABLING_QWAIT: ++ case BFA_PPORT_ST_DISABLING: ++ case BFA_PPORT_ST_DISABLED: ++ case BFA_PPORT_ST_STOPPED: ++ case BFA_PPORT_ST_IOCDOWN: ++ default: ++ fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; ++ break; ++ } ++} ++ ++/** ++ * FC transport template entry, get SCSI host active fc4s. ++ */ ++static void ++bfad_im_get_host_active_fc4s(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_port_s *port = im_port->port; ++ ++ memset(fc_host_active_fc4s(shost), 0, ++ sizeof(fc_host_active_fc4s(shost))); ++ ++ if (port->supported_fc4s & ++ (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) ++ fc_host_active_fc4s(shost)[2] = 1; ++ ++ if (port->supported_fc4s & BFA_PORT_ROLE_FCP_IPFC) ++ fc_host_active_fc4s(shost)[3] = 0x20; ++ ++ fc_host_active_fc4s(shost)[7] = 1; ++} ++ ++/** ++ * FC transport template entry, get SCSI host link speed. ++ */ ++static void ++bfad_im_get_host_speed(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_pport_attr_s attr; ++ ++ bfa_pport_get_attr(&bfad->bfa, &attr); ++ switch (attr.speed) { ++ case BFA_PPORT_SPEED_8GBPS: ++ fc_host_speed(shost) = FC_PORTSPEED_8GBIT; ++ break; ++ case BFA_PPORT_SPEED_4GBPS: ++ fc_host_speed(shost) = FC_PORTSPEED_4GBIT; ++ break; ++ case BFA_PPORT_SPEED_2GBPS: ++ fc_host_speed(shost) = FC_PORTSPEED_2GBIT; ++ break; ++ case BFA_PPORT_SPEED_1GBPS: ++ fc_host_speed(shost) = FC_PORTSPEED_1GBIT; ++ break; ++ default: ++ fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; ++ break; ++ } ++} ++ ++/** ++ * FC transport template entry, get SCSI host port type. ++ */ ++static void ++bfad_im_get_host_fabric_name(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_port_s *port = im_port->port; ++ wwn_t fabric_nwwn = 0; ++ ++ fabric_nwwn = bfa_fcs_port_get_fabric_name(port->fcs_port); ++ ++ fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn); ++ ++} ++ ++/** ++ * FC transport template entry, get BFAD statistics. ++ */ ++static struct fc_host_statistics * ++bfad_im_get_stats(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfad_hal_comp fcomp; ++ struct fc_host_statistics *hstats; ++ bfa_status_t rc; ++ unsigned long flags; ++ ++ hstats = &bfad->link_stats; ++ init_completion(&fcomp.comp); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ memset(hstats, 0, sizeof(struct fc_host_statistics)); ++ rc = bfa_pport_get_stats(&bfad->bfa, ++ (union bfa_pport_stats_u *) hstats, ++ bfad_hcb_comp, &fcomp); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ if (rc != BFA_STATUS_OK) ++ return NULL; ++ ++ wait_for_completion(&fcomp.comp); ++ ++ return hstats; ++} ++ ++/** ++ * FC transport template entry, reset BFAD statistics. ++ */ ++static void ++bfad_im_reset_stats(struct Scsi_Host *shost) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfad_hal_comp fcomp; ++ unsigned long flags; ++ bfa_status_t rc; ++ ++ init_completion(&fcomp.comp); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (rc != BFA_STATUS_OK) ++ return; ++ ++ wait_for_completion(&fcomp.comp); ++ ++ return; ++} ++ ++/** ++ * FC transport template entry, get rport loss timeout. ++ */ ++static void ++bfad_im_get_rport_loss_tmo(struct fc_rport *rport) ++{ ++ struct bfad_itnim_data_s *itnim_data = rport->dd_data; ++ struct bfad_itnim_s *itnim = itnim_data->itnim; ++ struct bfad_s *bfad = itnim->im->bfad; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++/** ++ * FC transport template entry, set rport loss timeout. ++ */ ++static void ++bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout) ++{ ++ struct bfad_itnim_data_s *itnim_data = rport->dd_data; ++ struct bfad_itnim_s *itnim = itnim_data->itnim; ++ struct bfad_s *bfad = itnim->im->bfad; ++ unsigned long flags; ++ ++ if (timeout > 0) { ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_fcpim_path_tov_set(&bfad->bfa, timeout); ++ rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ } ++ ++} ++ ++struct fc_function_template bfad_im_fc_function_template = { ++ ++ /* Target dynamic attributes */ ++ .get_starget_port_id = bfad_im_get_starget_port_id, ++ .show_starget_port_id = 1, ++ .get_starget_node_name = bfad_im_get_starget_node_name, ++ .show_starget_node_name = 1, ++ .get_starget_port_name = bfad_im_get_starget_port_name, ++ .show_starget_port_name = 1, ++ ++ /* Host dynamic attribute */ ++ .get_host_port_id = bfad_im_get_host_port_id, ++ .show_host_port_id = 1, ++ ++ /* Host fixed attributes */ ++ .show_host_node_name = 1, ++ .show_host_port_name = 1, ++ .show_host_supported_classes = 1, ++ .show_host_supported_fc4s = 1, ++ .show_host_supported_speeds = 1, ++ .show_host_maxframe_size = 1, ++ ++ /* More host dynamic attributes */ ++ .show_host_port_type = 1, ++ .get_host_port_type = bfad_im_get_host_port_type, ++ .show_host_port_state = 1, ++ .get_host_port_state = bfad_im_get_host_port_state, ++ .show_host_active_fc4s = 1, ++ .get_host_active_fc4s = bfad_im_get_host_active_fc4s, ++ .show_host_speed = 1, ++ .get_host_speed = bfad_im_get_host_speed, ++ .show_host_fabric_name = 1, ++ .get_host_fabric_name = bfad_im_get_host_fabric_name, ++ ++ .show_host_symbolic_name = 1, ++ ++ /* Statistics */ ++ .get_fc_host_stats = bfad_im_get_stats, ++ .reset_fc_host_stats = bfad_im_reset_stats, ++ ++ /* Allocation length for host specific data */ ++ .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *), ++ ++ /* Remote port fixed attributes */ ++ .show_rport_maxframe_size = 1, ++ .show_rport_supported_classes = 1, ++ .show_rport_dev_loss_tmo = 1, ++ .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo, ++ .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo, ++}; ++ ++/** ++ * Scsi_Host_attrs SCSI host attributes ++ */ ++static ssize_t ++bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ++ ioc_attr.adapter_attr.serial_num); ++} ++ ++static ssize_t ++bfad_im_model_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model); ++} ++ ++static ssize_t ++bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ++ ioc_attr.adapter_attr.model_descr); ++} ++ ++static ssize_t ++bfad_im_node_name_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_port_s *port = im_port->port; ++ u64 nwwn; ++ ++ nwwn = bfa_fcs_port_get_nwwn(port->fcs_port); ++ return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn)); ++} ++ ++static ssize_t ++bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ ++ return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n", ++ ioc_attr.adapter_attr.model, ++ ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); ++} ++ ++static ssize_t ++bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver); ++} ++ ++static ssize_t ++bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); ++} ++ ++static ssize_t ++bfad_im_optionrom_version_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ++ ioc_attr.adapter_attr.optrom_ver); ++} ++ ++static ssize_t ++bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver); ++} ++ ++static ssize_t ++bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports); ++} ++ ++static ssize_t ++bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); ++} ++ ++static ssize_t ++bfad_im_num_of_discovered_ports_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_port_s *port = im_port->port; ++ struct bfad_s *bfad = im_port->bfad; ++ int nrports = 2048; ++ wwn_t *rports = NULL; ++ unsigned long flags; ++ ++ rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC); ++ if (rports == NULL) ++ return -ENOMEM; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ kfree(rports); ++ ++ return snprintf(buf, PAGE_SIZE, "%d\n", nrports); ++} ++ ++static DEVICE_ATTR(serial_number, S_IRUGO, ++ bfad_im_serial_num_show, NULL); ++static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL); ++static DEVICE_ATTR(model_description, S_IRUGO, ++ bfad_im_model_desc_show, NULL); ++static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL); ++static DEVICE_ATTR(symbolic_name, S_IRUGO, ++ bfad_im_symbolic_name_show, NULL); ++static DEVICE_ATTR(hardware_version, S_IRUGO, ++ bfad_im_hw_version_show, NULL); ++static DEVICE_ATTR(driver_version, S_IRUGO, ++ bfad_im_drv_version_show, NULL); ++static DEVICE_ATTR(option_rom_version, S_IRUGO, ++ bfad_im_optionrom_version_show, NULL); ++static DEVICE_ATTR(firmware_version, S_IRUGO, ++ bfad_im_fw_version_show, NULL); ++static DEVICE_ATTR(number_of_ports, S_IRUGO, ++ bfad_im_num_of_ports_show, NULL); ++static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL); ++static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO, ++ bfad_im_num_of_discovered_ports_show, NULL); ++ ++struct device_attribute *bfad_im_host_attrs[] = { ++ &dev_attr_serial_number, ++ &dev_attr_model, ++ &dev_attr_model_description, ++ &dev_attr_node_name, ++ &dev_attr_symbolic_name, ++ &dev_attr_hardware_version, ++ &dev_attr_driver_version, ++ &dev_attr_option_rom_version, ++ &dev_attr_firmware_version, ++ &dev_attr_number_of_ports, ++ &dev_attr_driver_name, ++ &dev_attr_number_of_discovered_ports, ++ NULL, ++}; ++ ++struct device_attribute *bfad_im_vport_attrs[] = { ++ &dev_attr_serial_number, ++ &dev_attr_model, ++ &dev_attr_model_description, ++ &dev_attr_node_name, ++ &dev_attr_symbolic_name, ++ &dev_attr_hardware_version, ++ &dev_attr_driver_version, ++ &dev_attr_option_rom_version, ++ &dev_attr_firmware_version, ++ &dev_attr_number_of_ports, ++ &dev_attr_driver_name, ++ &dev_attr_number_of_discovered_ports, ++ NULL, ++}; ++ ++ +diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h +new file mode 100644 +index 0000000..4d3312d +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_attr.h +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFAD_ATTR_H__ ++#define __BFAD_ATTR_H__ ++/** ++ * bfad_attr.h VMware driver configuration interface module. ++ */ ++ ++/** ++ * FC_transport_template FC transport template ++ */ ++ ++struct Scsi_Host* ++bfad_os_dev_to_shost(struct scsi_target *starget); ++ ++/** ++ * FC transport template entry, get SCSI target port ID. ++ */ ++void ++bfad_im_get_starget_port_id(struct scsi_target *starget); ++ ++/** ++ * FC transport template entry, get SCSI target nwwn. ++ */ ++void ++bfad_im_get_starget_node_name(struct scsi_target *starget); ++ ++/** ++ * FC transport template entry, get SCSI target pwwn. ++ */ ++void ++bfad_im_get_starget_port_name(struct scsi_target *starget); ++ ++/** ++ * FC transport template entry, get SCSI host port ID. ++ */ ++void ++bfad_im_get_host_port_id(struct Scsi_Host *shost); ++ ++/** ++ * FC transport template entry, issue a LIP. ++ */ ++int ++bfad_im_issue_fc_host_lip(struct Scsi_Host *shost); ++ ++struct Scsi_Host* ++bfad_os_starget_to_shost(struct scsi_target *starget); ++ ++ ++#endif /* __BFAD_ATTR_H__ */ +diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h +new file mode 100644 +index 0000000..172c81e +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_drv.h +@@ -0,0 +1,295 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * Contains base driver definitions. ++ */ ++ ++/** ++ * bfa_drv.h Linux driver data structures. ++ */ ++ ++#ifndef __BFAD_DRV_H__ ++#define __BFAD_DRV_H__ ++ ++#include "bfa_os_inc.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "aen/bfa_aen.h" ++#include ++ ++#define BFAD_DRIVER_NAME "bfa" ++#ifdef BFA_DRIVER_VERSION ++#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION ++#else ++#define BFAD_DRIVER_VERSION "2.0.0.0" ++#endif ++ ++ ++#define BFAD_IRQ_FLAGS IRQF_SHARED ++ ++/* ++ * BFAD flags ++ */ ++#define BFAD_MSIX_ON 0x00000001 ++#define BFAD_HAL_INIT_DONE 0x00000002 ++#define BFAD_DRV_INIT_DONE 0x00000004 ++#define BFAD_CFG_PPORT_DONE 0x00000008 ++#define BFAD_HAL_START_DONE 0x00000010 ++#define BFAD_PORT_ONLINE 0x00000020 ++#define BFAD_RPORT_ONLINE 0x00000040 ++ ++#define BFAD_PORT_DELETE 0x00000001 ++ ++/* ++ * BFAD related definition ++ */ ++#define SCSI_SCAN_DELAY HZ ++#define BFAD_STOP_TIMEOUT 30 ++#define BFAD_SUSPEND_TIMEOUT BFAD_STOP_TIMEOUT ++ ++/* ++ * BFAD configuration parameter default values ++ */ ++#define BFAD_LUN_QUEUE_DEPTH 32 ++#define BFAD_IO_MAX_SGE SG_ALL ++ ++#define bfad_isr_t irq_handler_t ++ ++#define MAX_MSIX_ENTRY 22 ++ ++struct bfad_msix_s { ++ struct bfad_s *bfad; ++ struct msix_entry msix; ++}; ++ ++enum bfad_port_pvb_type { ++ BFAD_PORT_PHYS_BASE = 0, ++ BFAD_PORT_PHYS_VPORT = 1, ++ BFAD_PORT_VF_BASE = 2, ++ BFAD_PORT_VF_VPORT = 3, ++}; ++ ++/* ++ * PORT data structure ++ */ ++struct bfad_port_s { ++ struct list_head list_entry; ++ struct bfad_s *bfad; ++ struct bfa_fcs_port_s *fcs_port; ++ u32 roles; ++ s32 flags; ++ u32 supported_fc4s; ++ u8 ipfc_flags; ++ enum bfad_port_pvb_type pvb_type; ++ struct bfad_im_port_s *im_port; /* IM specific data */ ++ struct bfad_tm_port_s *tm_port; /* TM specific data */ ++ struct bfad_ipfc_port_s *ipfc_port; /* IPFC specific data */ ++}; ++ ++/* ++ * VPORT data structure ++ */ ++struct bfad_vport_s { ++ struct bfad_port_s drv_port; ++ struct bfa_fcs_vport_s fcs_vport; ++ struct completion *comp_del; ++}; ++ ++/* ++ * VF data structure ++ */ ++struct bfad_vf_s { ++ bfa_fcs_vf_t fcs_vf; ++ struct bfad_port_s base_port; /* base port for vf */ ++ struct bfad_s *bfad; ++}; ++ ++struct bfad_cfg_param_s { ++ u32 rport_del_timeout; ++ u32 ioc_queue_depth; ++ u32 lun_queue_depth; ++ u32 io_max_sge; ++ u32 binding_method; ++}; ++ ++#define BFAD_AEN_MAX_APPS 8 ++struct bfad_aen_file_s { ++ struct list_head qe; ++ struct bfad_s *bfad; ++ s32 ri; ++ s32 app_id; ++}; ++ ++/* ++ * BFAD (PCI function) data structure ++ */ ++struct bfad_s { ++ struct list_head list_entry; ++ struct bfa_s bfa; ++ struct bfa_fcs_s bfa_fcs; ++ struct pci_dev *pcidev; ++ const char *pci_name; ++ struct bfa_pcidev_s hal_pcidev; ++ struct bfa_ioc_pci_attr_s pci_attr; ++ unsigned long pci_bar0_map; ++ void __iomem *pci_bar0_kva; ++ struct completion comp; ++ struct completion suspend; ++ struct completion disable_comp; ++ bfa_boolean_t disable_active; ++ struct bfad_port_s pport; /* physical port of the BFAD */ ++ struct bfa_meminfo_s meminfo; ++ struct bfa_iocfc_cfg_s ioc_cfg; ++ u32 inst_no; /* BFAD instance number */ ++ u32 bfad_flags; ++ spinlock_t bfad_lock; ++ struct bfad_cfg_param_s cfg_data; ++ struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY]; ++ int nvec; ++ char adapter_name[BFA_ADAPTER_SYM_NAME_LEN]; ++ char port_name[BFA_ADAPTER_SYM_NAME_LEN]; ++ struct timer_list hal_tmo; ++ unsigned long hs_start; ++ struct bfad_im_s *im; /* IM specific data */ ++ struct bfad_tm_s *tm; /* TM specific data */ ++ struct bfad_ipfc_s *ipfc; /* IPFC specific data */ ++ struct bfa_log_mod_s log_data; ++ struct bfa_trc_mod_s *trcmod; ++ struct bfa_log_mod_s *logmod; ++ struct bfa_aen_s *aen; ++ struct bfa_aen_s aen_buf; ++ struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS]; ++ struct list_head file_q; ++ struct list_head file_free_q; ++ struct bfa_plog_s plog_buf; ++ int ref_count; ++ bfa_boolean_t ipfc_enabled; ++ struct fc_host_statistics link_stats; ++ ++ struct kobject *bfa_kobj; ++ struct kobject *ioc_kobj; ++ struct kobject *pport_kobj; ++ struct kobject *lport_kobj; ++}; ++ ++/* ++ * RPORT data structure ++ */ ++struct bfad_rport_s { ++ struct bfa_fcs_rport_s fcs_rport; ++}; ++ ++struct bfad_buf_info { ++ void *virt; ++ dma_addr_t phys; ++ u32 size; ++}; ++ ++struct bfad_fcxp { ++ struct bfad_port_s *port; ++ struct bfa_rport_s *bfa_rport; ++ bfa_status_t req_status; ++ u16 tag; ++ u16 rsp_len; ++ u16 rsp_maxlen; ++ u8 use_ireqbuf; ++ u8 use_irspbuf; ++ u32 num_req_sgles; ++ u32 num_rsp_sgles; ++ struct fchs_s fchs; ++ void *reqbuf_info; ++ void *rspbuf_info; ++ struct bfa_sge_s *req_sge; ++ struct bfa_sge_s *rsp_sge; ++ fcxp_send_cb_t send_cbfn; ++ void *send_cbarg; ++ void *bfa_fcxp; ++ struct completion comp; ++}; ++ ++struct bfad_hal_comp { ++ bfa_status_t status; ++ struct completion comp; ++}; ++ ++/* ++ * Macro to obtain the immediate lower power ++ * of two for the integer. ++ */ ++#define nextLowerInt(x) \ ++do { \ ++ int j; \ ++ (*x)--; \ ++ for (j = 1; j < (sizeof(int) * 8); j <<= 1) \ ++ (*x) = (*x) | (*x) >> j; \ ++ (*x)++; \ ++ (*x) = (*x) >> 1; \ ++} while (0) ++ ++ ++bfa_status_t bfad_vport_create(struct bfad_s *bfad, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg); ++bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg); ++bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role); ++bfa_status_t bfad_drv_init(struct bfad_s *bfad); ++void bfad_drv_start(struct bfad_s *bfad); ++void bfad_uncfg_pport(struct bfad_s *bfad); ++void bfad_drv_stop(struct bfad_s *bfad); ++void bfad_remove_intr(struct bfad_s *bfad); ++void bfad_hal_mem_release(struct bfad_s *bfad); ++void bfad_hcb_comp(void *arg, bfa_status_t status); ++ ++int bfad_setup_intr(struct bfad_s *bfad); ++void bfad_remove_intr(struct bfad_s *bfad); ++ ++void bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg); ++bfa_status_t bfad_hal_mem_alloc(struct bfad_s *bfad); ++void bfad_bfa_tmo(unsigned long data); ++void bfad_init_timer(struct bfad_s *bfad); ++int bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad); ++void bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad); ++void bfad_fcs_port_cfg(struct bfad_s *bfad); ++void bfad_drv_uninit(struct bfad_s *bfad); ++void bfad_drv_log_level_set(struct bfad_s *bfad); ++bfa_status_t bfad_fc4_module_init(void); ++void bfad_fc4_module_exit(void); ++ ++void bfad_pci_remove(struct pci_dev *pdev); ++int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid); ++void bfad_os_rport_online_wait(struct bfad_s *bfad); ++int bfad_os_get_linkup_delay(struct bfad_s *bfad); ++int bfad_install_msix_handler(struct bfad_s *bfad); ++ ++extern struct idr bfad_im_port_index; ++extern struct list_head bfad_list; ++extern int bfa_lun_queue_depth; ++extern int bfad_supported_fc4s; ++extern int bfa_linkup_delay; ++ ++#endif /* __BFAD_DRV_H__ */ +diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c +new file mode 100644 +index 0000000..b2f6949 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_fwimg.c +@@ -0,0 +1,95 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfad_fwimg.c Linux driver PCI interface module. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++u32 bfi_image_ct_size; ++u32 bfi_image_cb_size; ++u32 *bfi_image_ct; ++u32 *bfi_image_cb; ++ ++ ++#define BFAD_FW_FILE_CT "ctfw.bin" ++#define BFAD_FW_FILE_CB "cbfw.bin" ++ ++u32 * ++bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, ++ u32 *bfi_image_size, char *fw_name) ++{ ++ const struct firmware *fw; ++ ++ if (request_firmware(&fw, fw_name, &pdev->dev)) { ++ printk(KERN_ALERT "Can't locate firmware %s\n", fw_name); ++ goto error; ++ } ++ ++ *bfi_image = vmalloc(fw->size); ++ if (NULL == *bfi_image) { ++ printk(KERN_ALERT "Fail to allocate buffer for fw image " ++ "size=%x!\n", (u32) fw->size); ++ goto error; ++ } ++ ++ memcpy(*bfi_image, fw->data, fw->size); ++ *bfi_image_size = fw->size/sizeof(u32); ++ ++ return(*bfi_image); ++ ++error: ++ return(NULL); ++} ++ ++u32 * ++bfad_get_firmware_buf(struct pci_dev *pdev) ++{ ++ if (pdev->device == BFA_PCI_DEVICE_ID_CT) { ++ if (bfi_image_ct_size == 0) ++ bfad_read_firmware(pdev, &bfi_image_ct, ++ &bfi_image_ct_size, BFAD_FW_FILE_CT); ++ return(bfi_image_ct); ++ } else { ++ if (bfi_image_cb_size == 0) ++ bfad_read_firmware(pdev, &bfi_image_cb, ++ &bfi_image_cb_size, BFAD_FW_FILE_CB); ++ return(bfi_image_cb); ++ } ++} ++ ++u32 * ++bfi_image_ct_get_chunk(u32 off) ++{ return (u32 *)(bfi_image_ct + off); } ++ ++u32 * ++bfi_image_cb_get_chunk(u32 off) ++{ return (u32 *)(bfi_image_cb + off); } ++ +diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c +new file mode 100644 +index 0000000..158c992 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_im.c +@@ -0,0 +1,1230 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfad_im.c Linux driver IM module. ++ */ ++ ++#include "bfad_drv.h" ++#include "bfad_im.h" ++#include "bfad_trcmod.h" ++#include "bfa_cb_ioim_macros.h" ++#include ++ ++BFA_TRC_FILE(LDRV, IM); ++ ++DEFINE_IDR(bfad_im_port_index); ++struct scsi_transport_template *bfad_im_scsi_transport_template; ++static void bfad_im_itnim_work_handler(struct work_struct *work); ++static int bfad_im_queuecommand(struct scsi_cmnd *cmnd, ++ void (*done)(struct scsi_cmnd *)); ++static int bfad_im_slave_alloc(struct scsi_device *sdev); ++ ++void ++bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio, ++ enum bfi_ioim_status io_status, u8 scsi_status, ++ int sns_len, u8 *sns_info, s32 residue) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ struct bfad_s *bfad = drv; ++ struct bfad_itnim_data_s *itnim_data; ++ struct bfad_itnim_s *itnim; ++ ++ switch (io_status) { ++ case BFI_IOIM_STS_OK: ++ bfa_trc(bfad, scsi_status); ++ cmnd->result = ScsiResult(DID_OK, scsi_status); ++ scsi_set_resid(cmnd, 0); ++ ++ if (sns_len > 0) { ++ bfa_trc(bfad, sns_len); ++ if (sns_len > SCSI_SENSE_BUFFERSIZE) ++ sns_len = SCSI_SENSE_BUFFERSIZE; ++ memcpy(cmnd->sense_buffer, sns_info, sns_len); ++ } ++ if (residue > 0) ++ scsi_set_resid(cmnd, residue); ++ break; ++ ++ case BFI_IOIM_STS_ABORTED: ++ case BFI_IOIM_STS_TIMEDOUT: ++ case BFI_IOIM_STS_PATHTOV: ++ default: ++ cmnd->result = ScsiResult(DID_ERROR, 0); ++ } ++ ++ /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */ ++ if (cmnd->device->host != NULL) ++ scsi_dma_unmap(cmnd); ++ ++ cmnd->host_scribble = NULL; ++ bfa_trc(bfad, cmnd->result); ++ ++ itnim_data = cmnd->device->hostdata; ++ if (itnim_data) { ++ itnim = itnim_data->itnim; ++ if (!cmnd->result && itnim && ++ (bfa_lun_queue_depth > cmnd->device->queue_depth)) { ++ /* Queue depth adjustment for good status completion */ ++ bfad_os_ramp_up_qdepth(itnim, cmnd->device); ++ } else if (cmnd->result == SAM_STAT_TASK_SET_FULL && itnim) { ++ /* qfull handling */ ++ bfad_os_handle_qfull(itnim, cmnd->device); ++ } ++ } ++ ++ cmnd->scsi_done(cmnd); ++} ++ ++void ++bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ struct bfad_itnim_data_s *itnim_data; ++ struct bfad_itnim_s *itnim; ++ ++ cmnd->result = ScsiResult(DID_OK, SCSI_STATUS_GOOD); ++ ++ /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */ ++ if (cmnd->device->host != NULL) ++ scsi_dma_unmap(cmnd); ++ ++ cmnd->host_scribble = NULL; ++ ++ /* Queue depth adjustment */ ++ if (bfa_lun_queue_depth > cmnd->device->queue_depth) { ++ itnim_data = cmnd->device->hostdata; ++ if (itnim_data) { ++ itnim = itnim_data->itnim; ++ if (itnim) ++ bfad_os_ramp_up_qdepth(itnim, cmnd->device); ++ } ++ } ++ ++ cmnd->scsi_done(cmnd); ++} ++ ++void ++bfa_cb_ioim_abort(void *drv, struct bfad_ioim_s *dio) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio; ++ struct bfad_s *bfad = drv; ++ ++ cmnd->result = ScsiResult(DID_ERROR, 0); ++ ++ /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */ ++ if (cmnd->device->host != NULL) ++ scsi_dma_unmap(cmnd); ++ ++ bfa_trc(bfad, cmnd->result); ++ cmnd->host_scribble = NULL; ++} ++ ++void ++bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, ++ enum bfi_tskim_status tsk_status) ++{ ++ struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk; ++ wait_queue_head_t *wq; ++ ++ cmnd->SCp.Status |= tsk_status << 1; ++ set_bit(IO_DONE_BIT, (unsigned long *)&cmnd->SCp.Status); ++ wq = (wait_queue_head_t *) cmnd->SCp.ptr; ++ cmnd->SCp.ptr = NULL; ++ ++ if (wq) ++ wake_up(wq); ++} ++ ++void ++bfa_cb_ioim_resfree(void *drv) ++{ ++} ++ ++/** ++ * Scsi_Host_template SCSI host template ++ */ ++/** ++ * Scsi_Host template entry, returns BFAD PCI info. ++ */ ++static const char * ++bfad_im_info(struct Scsi_Host *shost) ++{ ++ static char bfa_buf[256]; ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfa_ioc_attr_s ioc_attr; ++ struct bfad_s *bfad = im_port->bfad; ++ ++ memset(&ioc_attr, 0, sizeof(ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &ioc_attr); ++ ++ memset(bfa_buf, 0, sizeof(bfa_buf)); ++ snprintf(bfa_buf, sizeof(bfa_buf), ++ "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s", ++ ioc_attr.adapter_attr.model, bfad->pci_name, ++ BFAD_DRIVER_VERSION); ++ return bfa_buf; ++} ++ ++/** ++ * Scsi_Host template entry, aborts the specified SCSI command. ++ * ++ * Returns: SUCCESS or FAILED. ++ */ ++static int ++bfad_im_abort_handler(struct scsi_cmnd *cmnd) ++{ ++ struct Scsi_Host *shost = cmnd->device->host; ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_ioim_s *hal_io; ++ unsigned long flags; ++ u32 timeout; ++ int rc = FAILED; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ hal_io = (struct bfa_ioim_s *) cmnd->host_scribble; ++ if (!hal_io) { ++ /* IO has been completed, retrun success */ ++ rc = SUCCESS; ++ goto out; ++ } ++ if (hal_io->dio != (struct bfad_ioim_s *) cmnd) { ++ rc = FAILED; ++ goto out; ++ } ++ ++ bfa_trc(bfad, hal_io->iotag); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT, ++ im_port->shost->host_no, cmnd, hal_io->iotag); ++ bfa_ioim_abort(hal_io); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ /* Need to wait until the command get aborted */ ++ timeout = 10; ++ while ((struct bfa_ioim_s *) cmnd->host_scribble == hal_io) { ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout(timeout); ++ if (timeout < 4 * HZ) ++ timeout *= 2; ++ } ++ ++ cmnd->scsi_done(cmnd); ++ bfa_trc(bfad, hal_io->iotag); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT_COMP, ++ im_port->shost->host_no, cmnd, hal_io->iotag); ++ return SUCCESS; ++out: ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ return rc; ++} ++ ++static bfa_status_t ++bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, ++ struct bfad_itnim_s *itnim) ++{ ++ struct bfa_tskim_s *tskim; ++ struct bfa_itnim_s *bfa_itnim; ++ bfa_status_t rc = BFA_STATUS_OK; ++ ++ bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); ++ tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); ++ if (!tskim) { ++ BFA_DEV_PRINTF(bfad, BFA_ERR, ++ "target reset, fail to allocate tskim\n"); ++ rc = BFA_STATUS_FAILED; ++ goto out; ++ } ++ ++ /* ++ * Set host_scribble to NULL to avoid aborting a task command if ++ * happens. ++ */ ++ cmnd->host_scribble = NULL; ++ cmnd->SCp.Status = 0; ++ bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); ++ bfa_tskim_start(tskim, bfa_itnim, (lun_t)0, ++ FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO); ++out: ++ return rc; ++} ++ ++/** ++ * Scsi_Host template entry, resets a LUN and abort its all commands. ++ * ++ * Returns: SUCCESS or FAILED. ++ * ++ */ ++static int ++bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) ++{ ++ struct Scsi_Host *shost = cmnd->device->host; ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfa_tskim_s *tskim; ++ struct bfad_itnim_s *itnim; ++ struct bfa_itnim_s *bfa_itnim; ++ DECLARE_WAIT_QUEUE_HEAD(wq); ++ int rc = SUCCESS; ++ unsigned long flags; ++ enum bfi_tskim_status task_status; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ itnim = itnim_data->itnim; ++ if (!itnim) { ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ rc = FAILED; ++ goto out; ++ } ++ ++ tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); ++ if (!tskim) { ++ BFA_DEV_PRINTF(bfad, BFA_ERR, ++ "LUN reset, fail to allocate tskim"); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ rc = FAILED; ++ goto out; ++ } ++ ++ /** ++ * Set host_scribble to NULL to avoid aborting a task command ++ * if happens. ++ */ ++ cmnd->host_scribble = NULL; ++ cmnd->SCp.ptr = (char *)&wq; ++ cmnd->SCp.Status = 0; ++ bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); ++ bfa_tskim_start(tskim, bfa_itnim, ++ bfad_int_to_lun(cmnd->device->lun), ++ FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ wait_event(wq, test_bit(IO_DONE_BIT, ++ (unsigned long *)&cmnd->SCp.Status)); ++ ++ task_status = cmnd->SCp.Status >> 1; ++ if (task_status != BFI_TSKIM_STS_OK) { ++ BFA_DEV_PRINTF(bfad, BFA_ERR, "LUN reset failure, status: %d\n", ++ task_status); ++ rc = FAILED; ++ } ++ ++out: ++ return rc; ++} ++ ++/** ++ * Scsi_Host template entry, resets the bus and abort all commands. ++ */ ++static int ++bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd) ++{ ++ struct Scsi_Host *shost = cmnd->device->host; ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) shost->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfad_itnim_s *itnim; ++ unsigned long flags; ++ u32 i, rc, err_cnt = 0; ++ DECLARE_WAIT_QUEUE_HEAD(wq); ++ enum bfi_tskim_status task_status; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ for (i = 0; i < MAX_FCP_TARGET; i++) { ++ itnim = bfad_os_get_itnim(im_port, i); ++ if (itnim) { ++ cmnd->SCp.ptr = (char *)&wq; ++ rc = bfad_im_target_reset_send(bfad, cmnd, itnim); ++ if (rc != BFA_STATUS_OK) { ++ err_cnt++; ++ continue; ++ } ++ ++ /* wait target reset to complete */ ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ wait_event(wq, test_bit(IO_DONE_BIT, ++ (unsigned long *)&cmnd->SCp.Status)); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ task_status = cmnd->SCp.Status >> 1; ++ if (task_status != BFI_TSKIM_STS_OK) { ++ BFA_DEV_PRINTF(bfad, BFA_ERR, ++ "target reset failure," ++ " status: %d\n", task_status); ++ err_cnt++; ++ } ++ } ++ } ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (err_cnt) ++ return FAILED; ++ ++ return SUCCESS; ++} ++ ++/** ++ * Scsi_Host template entry slave_destroy. ++ */ ++static void ++bfad_im_slave_destroy(struct scsi_device *sdev) ++{ ++ sdev->hostdata = NULL; ++ return; ++} ++ ++/** ++ * BFA FCS itnim callbacks ++ */ ++ ++/** ++ * BFA FCS itnim alloc callback, after successful PRLI ++ * Context: Interrupt ++ */ ++void ++bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim, ++ struct bfad_itnim_s **itnim_drv) ++{ ++ *itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC); ++ if (*itnim_drv == NULL) ++ return; ++ ++ (*itnim_drv)->im = bfad->im; ++ *itnim = &(*itnim_drv)->fcs_itnim; ++ (*itnim_drv)->state = ITNIM_STATE_NONE; ++ ++ /* ++ * Initiaze the itnim_work ++ */ ++ INIT_WORK(&(*itnim_drv)->itnim_work, bfad_im_itnim_work_handler); ++ bfad->bfad_flags |= BFAD_RPORT_ONLINE; ++} ++ ++/** ++ * BFA FCS itnim free callback. ++ * Context: Interrupt. bfad_lock is held ++ */ ++void ++bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv) ++{ ++ struct bfad_port_s *port; ++ wwn_t wwpn; ++ u32 fcid; ++ char wwpn_str[32], fcid_str[16]; ++ ++ /* online to free state transtion should not happen */ ++ bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE); ++ ++ itnim_drv->queue_work = 1; ++ /* offline request is not yet done, use the same request to free */ ++ if (itnim_drv->state == ITNIM_STATE_OFFLINE_PENDING) ++ itnim_drv->queue_work = 0; ++ ++ itnim_drv->state = ITNIM_STATE_FREE; ++ port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); ++ itnim_drv->im_port = port->im_port; ++ wwpn = bfa_fcs_itnim_get_pwwn(&itnim_drv->fcs_itnim); ++ fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); ++ wwn2str(wwpn_str, wwpn); ++ fcid2str(fcid_str, fcid); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_FREE, ++ port->im_port->shost->host_no, ++ fcid_str, wwpn_str); ++ bfad_os_itnim_process(itnim_drv); ++} ++ ++/** ++ * BFA FCS itnim online callback. ++ * Context: Interrupt. bfad_lock is held ++ */ ++void ++bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv) ++{ ++ struct bfad_port_s *port; ++ ++ itnim_drv->bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim_drv->fcs_itnim); ++ port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); ++ itnim_drv->state = ITNIM_STATE_ONLINE; ++ itnim_drv->queue_work = 1; ++ itnim_drv->im_port = port->im_port; ++ bfad_os_itnim_process(itnim_drv); ++} ++ ++/** ++ * BFA FCS itnim offline callback. ++ * Context: Interrupt. bfad_lock is held ++ */ ++void ++bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv) ++{ ++ struct bfad_port_s *port; ++ struct bfad_s *bfad; ++ ++ port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim); ++ bfad = port->bfad; ++ if ((bfad->pport.flags & BFAD_PORT_DELETE) || ++ (port->flags & BFAD_PORT_DELETE)) { ++ itnim_drv->state = ITNIM_STATE_OFFLINE; ++ return; ++ } ++ itnim_drv->im_port = port->im_port; ++ itnim_drv->state = ITNIM_STATE_OFFLINE_PENDING; ++ itnim_drv->queue_work = 1; ++ bfad_os_itnim_process(itnim_drv); ++} ++ ++/** ++ * BFA FCS itnim timeout callback. ++ * Context: Interrupt. bfad_lock is held ++ */ ++void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim) ++{ ++ itnim->state = ITNIM_STATE_TIMEOUT; ++} ++ ++/** ++ * Path TOV processing begin notification -- dummy for linux ++ */ ++void ++bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim) ++{ ++} ++ ++ ++ ++/** ++ * Allocate a Scsi_Host for a port. ++ */ ++int ++bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port) ++{ ++ int error = 1; ++ ++ if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) { ++ printk(KERN_WARNING "idr_pre_get failure\n"); ++ goto out; ++ } ++ ++ error = idr_get_new(&bfad_im_port_index, im_port, ++ &im_port->idr_id); ++ if (error) { ++ printk(KERN_WARNING "idr_get_new failure\n"); ++ goto out; ++ } ++ ++ im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad); ++ if (!im_port->shost) { ++ error = 1; ++ goto out_free_idr; ++ } ++ ++ im_port->shost->hostdata[0] = (unsigned long)im_port; ++ im_port->shost->unique_id = im_port->idr_id; ++ im_port->shost->this_id = -1; ++ im_port->shost->max_id = MAX_FCP_TARGET; ++ im_port->shost->max_lun = MAX_FCP_LUN; ++ im_port->shost->max_cmd_len = 16; ++ im_port->shost->can_queue = bfad->cfg_data.ioc_queue_depth; ++ im_port->shost->transportt = bfad_im_scsi_transport_template; ++ ++ error = bfad_os_scsi_add_host(im_port->shost, im_port, bfad); ++ if (error) { ++ printk(KERN_WARNING "bfad_os_scsi_add_host failure %d\n", ++ error); ++ goto out_fc_rel; ++ } ++ ++ /* setup host fixed attribute if the lk supports */ ++ bfad_os_fc_host_init(im_port); ++ ++ return 0; ++ ++out_fc_rel: ++ scsi_host_put(im_port->shost); ++out_free_idr: ++ idr_remove(&bfad_im_port_index, im_port->idr_id); ++out: ++ return error; ++} ++ ++void ++bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) ++{ ++ unsigned long flags; ++ ++ bfa_trc(bfad, bfad->inst_no); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_HOST_FREE, ++ im_port->shost->host_no); ++ ++ fc_remove_host(im_port->shost); ++ ++ scsi_remove_host(im_port->shost); ++ scsi_host_put(im_port->shost); ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ idr_remove(&bfad_im_port_index, im_port->idr_id); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++static void ++bfad_im_port_delete_handler(struct work_struct *work) ++{ ++ struct bfad_im_port_s *im_port = ++ container_of(work, struct bfad_im_port_s, port_delete_work); ++ ++ bfad_im_scsi_host_free(im_port->bfad, im_port); ++ bfad_im_port_clean(im_port); ++ kfree(im_port); ++} ++ ++bfa_status_t ++bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port) ++{ ++ int rc = BFA_STATUS_OK; ++ struct bfad_im_port_s *im_port; ++ ++ im_port = kzalloc(sizeof(struct bfad_im_port_s), GFP_ATOMIC); ++ if (im_port == NULL) { ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ port->im_port = im_port; ++ im_port->port = port; ++ im_port->bfad = bfad; ++ ++ INIT_WORK(&im_port->port_delete_work, bfad_im_port_delete_handler); ++ INIT_LIST_HEAD(&im_port->itnim_mapped_list); ++ INIT_LIST_HEAD(&im_port->binding_list); ++ ++ext: ++ return rc; ++} ++ ++void ++bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port) ++{ ++ struct bfad_im_port_s *im_port = port->im_port; ++ ++ queue_work(bfad->im->drv_workq, ++ &im_port->port_delete_work); ++} ++ ++void ++bfad_im_port_clean(struct bfad_im_port_s *im_port) ++{ ++ struct bfad_fcp_binding *bp, *bp_new; ++ unsigned long flags; ++ struct bfad_s *bfad = im_port->bfad; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ list_for_each_entry_safe(bp, bp_new, &im_port->binding_list, ++ list_entry) { ++ list_del(&bp->list_entry); ++ kfree(bp); ++ } ++ ++ /* the itnim_mapped_list must be empty at this time */ ++ bfa_assert(list_empty(&im_port->itnim_mapped_list)); ++ ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++void ++bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port) ++{ ++} ++ ++void ++bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port) ++{ ++} ++ ++bfa_status_t ++bfad_im_probe(struct bfad_s *bfad) ++{ ++ struct bfad_im_s *im; ++ bfa_status_t rc = BFA_STATUS_OK; ++ ++ im = kzalloc(sizeof(struct bfad_im_s), GFP_KERNEL); ++ if (im == NULL) { ++ rc = BFA_STATUS_ENOMEM; ++ goto ext; ++ } ++ ++ bfad->im = im; ++ im->bfad = bfad; ++ ++ if (bfad_os_thread_workq(bfad) != BFA_STATUS_OK) { ++ kfree(im); ++ rc = BFA_STATUS_FAILED; ++ } ++ ++ext: ++ return rc; ++} ++ ++void ++bfad_im_probe_undo(struct bfad_s *bfad) ++{ ++ if (bfad->im) { ++ bfad_os_destroy_workq(bfad->im); ++ kfree(bfad->im); ++ bfad->im = NULL; ++ } ++} ++ ++ ++ ++ ++int ++bfad_os_scsi_add_host(struct Scsi_Host *shost, struct bfad_im_port_s *im_port, ++ struct bfad_s *bfad) ++{ ++ struct device *dev; ++ ++ if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE) ++ dev = &bfad->pcidev->dev; ++ else ++ dev = &bfad->pport.im_port->shost->shost_gendev; ++ ++ return scsi_add_host(shost, dev); ++} ++ ++struct Scsi_Host * ++bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad) ++{ ++ struct scsi_host_template *sht; ++ ++ if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE) ++ sht = &bfad_im_scsi_host_template; ++ else ++ sht = &bfad_im_vport_template; ++ ++ sht->sg_tablesize = bfad->cfg_data.io_max_sge; ++ ++ return scsi_host_alloc(sht, sizeof(unsigned long)); ++} ++ ++void ++bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) ++{ ++ flush_workqueue(bfad->im->drv_workq); ++ bfad_im_scsi_host_free(im_port->bfad, im_port); ++ bfad_im_port_clean(im_port); ++ kfree(im_port); ++} ++ ++void ++bfad_os_destroy_workq(struct bfad_im_s *im) ++{ ++ if (im && im->drv_workq) { ++ destroy_workqueue(im->drv_workq); ++ im->drv_workq = NULL; ++ } ++} ++ ++bfa_status_t ++bfad_os_thread_workq(struct bfad_s *bfad) ++{ ++ struct bfad_im_s *im = bfad->im; ++ ++ bfa_trc(bfad, 0); ++ snprintf(im->drv_workq_name, BFAD_KOBJ_NAME_LEN, "bfad_wq_%d", ++ bfad->inst_no); ++ im->drv_workq = create_singlethread_workqueue(im->drv_workq_name); ++ if (!im->drv_workq) ++ return BFA_STATUS_FAILED; ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Scsi_Host template entry. ++ * ++ * Description: ++ * OS entry point to adjust the queue_depths on a per-device basis. ++ * Called once per device during the bus scan. ++ * Return non-zero if fails. ++ */ ++static int ++bfad_im_slave_configure(struct scsi_device *sdev) ++{ ++ if (sdev->tagged_supported) ++ scsi_activate_tcq(sdev, bfa_lun_queue_depth); ++ else ++ scsi_deactivate_tcq(sdev, bfa_lun_queue_depth); ++ ++ return 0; ++} ++ ++struct scsi_host_template bfad_im_scsi_host_template = { ++ .module = THIS_MODULE, ++ .name = BFAD_DRIVER_NAME, ++ .info = bfad_im_info, ++ .queuecommand = bfad_im_queuecommand, ++ .eh_abort_handler = bfad_im_abort_handler, ++ .eh_device_reset_handler = bfad_im_reset_lun_handler, ++ .eh_bus_reset_handler = bfad_im_reset_bus_handler, ++ ++ .slave_alloc = bfad_im_slave_alloc, ++ .slave_configure = bfad_im_slave_configure, ++ .slave_destroy = bfad_im_slave_destroy, ++ ++ .this_id = -1, ++ .sg_tablesize = BFAD_IO_MAX_SGE, ++ .cmd_per_lun = 3, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = bfad_im_host_attrs, ++ .max_sectors = 0xFFFF, ++}; ++ ++struct scsi_host_template bfad_im_vport_template = { ++ .module = THIS_MODULE, ++ .name = BFAD_DRIVER_NAME, ++ .info = bfad_im_info, ++ .queuecommand = bfad_im_queuecommand, ++ .eh_abort_handler = bfad_im_abort_handler, ++ .eh_device_reset_handler = bfad_im_reset_lun_handler, ++ .eh_bus_reset_handler = bfad_im_reset_bus_handler, ++ ++ .slave_alloc = bfad_im_slave_alloc, ++ .slave_configure = bfad_im_slave_configure, ++ .slave_destroy = bfad_im_slave_destroy, ++ ++ .this_id = -1, ++ .sg_tablesize = BFAD_IO_MAX_SGE, ++ .cmd_per_lun = 3, ++ .use_clustering = ENABLE_CLUSTERING, ++ .shost_attrs = bfad_im_vport_attrs, ++ .max_sectors = 0xFFFF, ++}; ++ ++void ++bfad_im_probe_post(struct bfad_im_s *im) ++{ ++ flush_workqueue(im->drv_workq); ++} ++ ++bfa_status_t ++bfad_im_module_init(void) ++{ ++ bfad_im_scsi_transport_template = ++ fc_attach_transport(&bfad_im_fc_function_template); ++ if (!bfad_im_scsi_transport_template) ++ return BFA_STATUS_ENOMEM; ++ ++ return BFA_STATUS_OK; ++} ++ ++void ++bfad_im_module_exit(void) ++{ ++ if (bfad_im_scsi_transport_template) ++ fc_release_transport(bfad_im_scsi_transport_template); ++} ++ ++void ++bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv) ++{ ++ struct bfad_im_s *im = itnim_drv->im; ++ ++ if (itnim_drv->queue_work) ++ queue_work(im->drv_workq, &itnim_drv->itnim_work); ++} ++ ++void ++bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev) ++{ ++ struct scsi_device *tmp_sdev; ++ ++ if (((jiffies - itnim->last_ramp_up_time) > ++ BFA_QUEUE_FULL_RAMP_UP_TIME * HZ) && ++ ((jiffies - itnim->last_queue_full_time) > ++ BFA_QUEUE_FULL_RAMP_UP_TIME * HZ)) { ++ shost_for_each_device(tmp_sdev, sdev->host) { ++ if (bfa_lun_queue_depth > tmp_sdev->queue_depth) { ++ if (tmp_sdev->id != sdev->id) ++ continue; ++ if (tmp_sdev->ordered_tags) ++ scsi_adjust_queue_depth(tmp_sdev, ++ MSG_ORDERED_TAG, ++ tmp_sdev->queue_depth + 1); ++ else ++ scsi_adjust_queue_depth(tmp_sdev, ++ MSG_SIMPLE_TAG, ++ tmp_sdev->queue_depth + 1); ++ ++ itnim->last_ramp_up_time = jiffies; ++ } ++ } ++ } ++} ++ ++void ++bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev) ++{ ++ struct scsi_device *tmp_sdev; ++ ++ itnim->last_queue_full_time = jiffies; ++ ++ shost_for_each_device(tmp_sdev, sdev->host) { ++ if (tmp_sdev->id != sdev->id) ++ continue; ++ scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1); ++ } ++} ++ ++ ++ ++ ++struct bfad_itnim_s * ++bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id) ++{ ++ struct bfad_itnim_s *itnim = NULL; ++ ++ /* Search the mapped list for this target ID */ ++ list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) { ++ if (id == itnim->scsi_tgt_id) ++ return itnim; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * Scsi_Host template entry slave_alloc ++ */ ++static int ++bfad_im_slave_alloc(struct scsi_device *sdev) ++{ ++ struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); ++ ++ if (!rport || fc_remote_port_chkready(rport)) ++ return -ENXIO; ++ ++ sdev->hostdata = rport->dd_data; ++ ++ return 0; ++} ++ ++void ++bfad_os_fc_host_init(struct bfad_im_port_s *im_port) ++{ ++ struct Scsi_Host *host = im_port->shost; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfad_port_s *port = im_port->port; ++ union attr { ++ struct bfa_pport_attr_s pattr; ++ struct bfa_ioc_attr_s ioc_attr; ++ } attr; ++ ++ fc_host_node_name(host) = ++ bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port))); ++ fc_host_port_name(host) = ++ bfa_os_htonll((bfa_fcs_port_get_pwwn(port->fcs_port))); ++ ++ fc_host_supported_classes(host) = FC_COS_CLASS3; ++ ++ memset(fc_host_supported_fc4s(host), 0, ++ sizeof(fc_host_supported_fc4s(host))); ++ if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM)) ++ /* For FCP type 0x08 */ ++ fc_host_supported_fc4s(host)[2] = 1; ++ if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC) ++ /* For LLC/SNAP type 0x05 */ ++ fc_host_supported_fc4s(host)[3] = 0x20; ++ /* For fibre channel services type 0x20 */ ++ fc_host_supported_fc4s(host)[7] = 1; ++ ++ memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr)); ++ bfa_get_attr(&bfad->bfa, &attr.ioc_attr); ++ sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s", ++ attr.ioc_attr.adapter_attr.model, ++ attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION); ++ ++ fc_host_supported_speeds(host) = 0; ++ fc_host_supported_speeds(host) |= ++ FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | ++ FC_PORTSPEED_1GBIT; ++ ++ memset(&attr.pattr, 0, sizeof(attr.pattr)); ++ bfa_pport_get_attr(&bfad->bfa, &attr.pattr); ++ fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize; ++} ++ ++static void ++bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim) ++{ ++ struct fc_rport_identifiers rport_ids; ++ struct fc_rport *fc_rport; ++ struct bfad_itnim_data_s *itnim_data; ++ ++ rport_ids.node_name = ++ bfa_os_htonll(bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim)); ++ rport_ids.port_name = ++ bfa_os_htonll(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim)); ++ rport_ids.port_id = ++ bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim)); ++ rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; ++ ++ itnim->fc_rport = fc_rport = ++ fc_remote_port_add(im_port->shost, 0, &rport_ids); ++ ++ if (!fc_rport) ++ return; ++ ++ fc_rport->maxframe_size = ++ bfa_fcs_itnim_get_maxfrsize(&itnim->fcs_itnim); ++ fc_rport->supported_classes = bfa_fcs_itnim_get_cos(&itnim->fcs_itnim); ++ ++ itnim_data = fc_rport->dd_data; ++ itnim_data->itnim = itnim; ++ ++ rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; ++ ++ if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) ++ fc_remote_port_rolechg(fc_rport, rport_ids.roles); ++ ++ if ((fc_rport->scsi_target_id != -1) ++ && (fc_rport->scsi_target_id < MAX_FCP_TARGET)) ++ itnim->scsi_tgt_id = fc_rport->scsi_target_id; ++ ++ return; ++} ++ ++/** ++ * Work queue handler using FC transport service ++* Context: kernel ++ */ ++static void ++bfad_im_itnim_work_handler(struct work_struct *work) ++{ ++ struct bfad_itnim_s *itnim = container_of(work, struct bfad_itnim_s, ++ itnim_work); ++ struct bfad_im_s *im = itnim->im; ++ struct bfad_s *bfad = im->bfad; ++ struct bfad_im_port_s *im_port; ++ unsigned long flags; ++ struct fc_rport *fc_rport; ++ wwn_t wwpn; ++ u32 fcid; ++ char wwpn_str[32], fcid_str[16]; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ im_port = itnim->im_port; ++ bfa_trc(bfad, itnim->state); ++ switch (itnim->state) { ++ case ITNIM_STATE_ONLINE: ++ if (!itnim->fc_rport) { ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ bfad_im_fc_rport_add(im_port, itnim); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); ++ fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); ++ wwn2str(wwpn_str, wwpn); ++ fcid2str(fcid_str, fcid); ++ list_add_tail(&itnim->list_entry, ++ &im_port->itnim_mapped_list); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_ONLINE, ++ im_port->shost->host_no, ++ itnim->scsi_tgt_id, ++ fcid_str, wwpn_str); ++ } else { ++ printk(KERN_WARNING ++ "%s: itnim %llx is already in online state\n", ++ __FUNCTION__, ++ bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim)); ++ } ++ ++ break; ++ case ITNIM_STATE_OFFLINE_PENDING: ++ itnim->state = ITNIM_STATE_OFFLINE; ++ if (itnim->fc_rport) { ++ fc_rport = itnim->fc_rport; ++ ((struct bfad_itnim_data_s *) ++ fc_rport->dd_data)->itnim = NULL; ++ itnim->fc_rport = NULL; ++ if (!(im_port->port->flags & BFAD_PORT_DELETE)) { ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ fc_rport->dev_loss_tmo = ++ bfa_fcpim_path_tov_get(&bfad->bfa) + 1; ++ fc_remote_port_delete(fc_rport); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ } ++ wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim); ++ fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim); ++ wwn2str(wwpn_str, wwpn); ++ fcid2str(fcid_str, fcid); ++ list_del(&itnim->list_entry); ++ bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_OFFLINE, ++ im_port->shost->host_no, ++ itnim->scsi_tgt_id, ++ fcid_str, wwpn_str); ++ } ++ break; ++ case ITNIM_STATE_FREE: ++ if (itnim->fc_rport) { ++ fc_rport = itnim->fc_rport; ++ ((struct bfad_itnim_data_s *) ++ fc_rport->dd_data)->itnim = NULL; ++ itnim->fc_rport = NULL; ++ if (!(im_port->port->flags & BFAD_PORT_DELETE)) { ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ fc_rport->dev_loss_tmo = ++ bfa_fcpim_path_tov_get(&bfad->bfa) + 1; ++ fc_remote_port_delete(fc_rport); ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ } ++ list_del(&itnim->list_entry); ++ } ++ ++ kfree(itnim); ++ break; ++ default: ++ bfa_assert(0); ++ break; ++ } ++ ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++} ++ ++/** ++ * Scsi_Host template entry, queue a SCSI command to the BFAD. ++ */ ++static int ++bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) ++{ ++ struct bfad_im_port_s *im_port = ++ (struct bfad_im_port_s *) cmnd->device->host->hostdata[0]; ++ struct bfad_s *bfad = im_port->bfad; ++ struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata; ++ struct bfad_itnim_s *itnim; ++ struct bfa_ioim_s *hal_io; ++ unsigned long flags; ++ int rc; ++ s16 sg_cnt = 0; ++ struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); ++ ++ rc = fc_remote_port_chkready(rport); ++ if (rc) { ++ cmnd->result = rc; ++ done(cmnd); ++ return 0; ++ } ++ ++ sg_cnt = scsi_dma_map(cmnd); ++ ++ if (sg_cnt < 0) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ ++ cmnd->scsi_done = done; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ if (!(bfad->bfad_flags & BFAD_HAL_START_DONE)) { ++ printk(KERN_WARNING ++ "bfad%d, queuecommand %p %x failed, BFA stopped\n", ++ bfad->inst_no, cmnd, cmnd->cmnd[0]); ++ cmnd->result = ScsiResult(DID_NO_CONNECT, 0); ++ goto out_fail_cmd; ++ } ++ ++ itnim = itnim_data->itnim; ++ if (!itnim) { ++ cmnd->result = ScsiResult(DID_IMM_RETRY, 0); ++ goto out_fail_cmd; ++ } ++ ++ hal_io = bfa_ioim_alloc(&bfad->bfa, (struct bfad_ioim_s *) cmnd, ++ itnim->bfa_itnim, sg_cnt); ++ if (!hal_io) { ++ printk(KERN_WARNING "hal_io failure\n"); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ scsi_dma_unmap(cmnd); ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } ++ ++ cmnd->host_scribble = (char *)hal_io; ++ bfa_trc_fp(bfad, hal_io->iotag); ++ bfa_ioim_start(hal_io); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ return 0; ++ ++out_fail_cmd: ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ scsi_dma_unmap(cmnd); ++ if (done) ++ done(cmnd); ++ ++ return 0; ++} ++ ++void ++bfad_os_rport_online_wait(struct bfad_s *bfad) ++{ ++ int i; ++ int rport_delay = 10; ++ ++ for (i = 0; !(bfad->bfad_flags & BFAD_PORT_ONLINE) ++ && i < bfa_linkup_delay; i++) ++ schedule_timeout_uninterruptible(HZ); ++ ++ if (bfad->bfad_flags & BFAD_PORT_ONLINE) { ++ rport_delay = rport_delay < bfa_linkup_delay ? ++ rport_delay : bfa_linkup_delay; ++ for (i = 0; !(bfad->bfad_flags & BFAD_RPORT_ONLINE) ++ && i < rport_delay; i++) ++ schedule_timeout_uninterruptible(HZ); ++ ++ if (rport_delay > 0 && (bfad->bfad_flags & BFAD_RPORT_ONLINE)) ++ schedule_timeout_uninterruptible(rport_delay * HZ); ++ } ++} ++ ++int ++bfad_os_get_linkup_delay(struct bfad_s *bfad) ++{ ++ ++ u8 nwwns = 0; ++ wwn_t *wwns; ++ int ldelay; ++ ++ /* ++ * Querying for the boot target port wwns ++ * -- read from boot information in flash. ++ * If nwwns > 0 => boot over SAN and set bfa_linkup_delay = 30 ++ * else => local boot machine set bfa_linkup_delay = 10 ++ */ ++ ++ bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, &wwns); ++ ++ if (nwwns > 0) { ++ /* If boot over SAN; linkup_delay = 30sec */ ++ ldelay = 30; ++ } else { ++ /* If local boot; linkup_delay = 10sec */ ++ ldelay = 0; ++ } ++ ++ return ldelay; ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h +new file mode 100644 +index 0000000..189a5b2 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_im.h +@@ -0,0 +1,150 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFAD_IM_H__ ++#define __BFAD_IM_H__ ++ ++#include "fcs/bfa_fcs_fcpim.h" ++#include "bfad_im_compat.h" ++ ++#define FCPI_NAME " fcpim" ++ ++void bfad_flags_set(struct bfad_s *bfad, u32 flags); ++bfa_status_t bfad_im_module_init(void); ++void bfad_im_module_exit(void); ++bfa_status_t bfad_im_probe(struct bfad_s *bfad); ++void bfad_im_probe_undo(struct bfad_s *bfad); ++void bfad_im_probe_post(struct bfad_im_s *im); ++bfa_status_t bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port); ++void bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port); ++void bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port); ++void bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port); ++void bfad_im_port_clean(struct bfad_im_port_s *im_port); ++int bfad_im_scsi_host_alloc(struct bfad_s *bfad, ++ struct bfad_im_port_s *im_port); ++void bfad_im_scsi_host_free(struct bfad_s *bfad, ++ struct bfad_im_port_s *im_port); ++ ++#define MAX_FCP_TARGET 1024 ++#define MAX_FCP_LUN 16384 ++#define BFAD_TARGET_RESET_TMO 60 ++#define BFAD_LUN_RESET_TMO 60 ++#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code) ++#define BFA_QUEUE_FULL_RAMP_UP_TIME 120 ++#define BFAD_KOBJ_NAME_LEN 20 ++ ++/* ++ * itnim flags ++ */ ++#define ITNIM_MAPPED 0x00000001 ++ ++#define SCSI_TASK_MGMT 0x00000001 ++#define IO_DONE_BIT 0 ++ ++struct bfad_itnim_data_s { ++ struct bfad_itnim_s *itnim; ++}; ++ ++struct bfad_im_port_s { ++ struct bfad_s *bfad; ++ struct bfad_port_s *port; ++ struct work_struct port_delete_work; ++ int idr_id; ++ u16 cur_scsi_id; ++ struct list_head binding_list; ++ struct Scsi_Host *shost; ++ struct list_head itnim_mapped_list; ++}; ++ ++enum bfad_itnim_state { ++ ITNIM_STATE_NONE, ++ ITNIM_STATE_ONLINE, ++ ITNIM_STATE_OFFLINE_PENDING, ++ ITNIM_STATE_OFFLINE, ++ ITNIM_STATE_TIMEOUT, ++ ITNIM_STATE_FREE, ++}; ++ ++/* ++ * Per itnim data structure ++ */ ++struct bfad_itnim_s { ++ struct list_head list_entry; ++ struct bfa_fcs_itnim_s fcs_itnim; ++ struct work_struct itnim_work; ++ u32 flags; ++ enum bfad_itnim_state state; ++ struct bfad_im_s *im; ++ struct bfad_im_port_s *im_port; ++ struct bfad_rport_s *drv_rport; ++ struct fc_rport *fc_rport; ++ struct bfa_itnim_s *bfa_itnim; ++ u16 scsi_tgt_id; ++ u16 queue_work; ++ unsigned long last_ramp_up_time; ++ unsigned long last_queue_full_time; ++}; ++ ++enum bfad_binding_type { ++ FCP_PWWN_BINDING = 0x1, ++ FCP_NWWN_BINDING = 0x2, ++ FCP_FCID_BINDING = 0x3, ++}; ++ ++struct bfad_fcp_binding { ++ struct list_head list_entry; ++ enum bfad_binding_type binding_type; ++ u16 scsi_target_id; ++ u32 fc_id; ++ wwn_t nwwn; ++ wwn_t pwwn; ++}; ++ ++struct bfad_im_s { ++ struct bfad_s *bfad; ++ struct workqueue_struct *drv_workq; ++ char drv_workq_name[BFAD_KOBJ_NAME_LEN]; ++}; ++ ++struct Scsi_Host *bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, ++ struct bfad_s *); ++bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad); ++void bfad_os_destroy_workq(struct bfad_im_s *im); ++void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv); ++void bfad_os_fc_host_init(struct bfad_im_port_s *im_port); ++void bfad_os_init_work(struct bfad_im_port_s *im_port); ++void bfad_os_scsi_host_free(struct bfad_s *bfad, ++ struct bfad_im_port_s *im_port); ++void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, ++ struct scsi_device *sdev); ++void bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev); ++struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id); ++int bfad_os_scsi_add_host(struct Scsi_Host *shost, ++ struct bfad_im_port_s *im_port, struct bfad_s *bfad); ++ ++/* ++ * scsi_host_template entries ++ */ ++void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port, ++ struct bfad_itnim_s *itnim); ++ ++extern struct scsi_host_template bfad_im_scsi_host_template; ++extern struct scsi_host_template bfad_im_vport_template; ++extern struct fc_function_template bfad_im_fc_function_template; ++extern struct scsi_transport_template *bfad_im_scsi_transport_template; ++ ++#endif +diff --git a/drivers/scsi/bfa/bfad_im_compat.h b/drivers/scsi/bfa/bfad_im_compat.h +new file mode 100644 +index 0000000..1d3e74e +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_im_compat.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFAD_IM_COMPAT_H__ ++#define __BFAD_IM_COMPAT_H__ ++ ++extern u32 *bfi_image_buf; ++extern u32 bfi_image_size; ++ ++extern struct device_attribute *bfad_im_host_attrs[]; ++extern struct device_attribute *bfad_im_vport_attrs[]; ++ ++u32 *bfad_get_firmware_buf(struct pci_dev *pdev); ++u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, ++ u32 *bfi_image_size, char *fw_name); ++ ++static inline u32 * ++bfad_load_fwimg(struct pci_dev *pdev) ++{ ++ return(bfad_get_firmware_buf(pdev)); ++} ++ ++static inline void ++bfad_free_fwimg(void) ++{ ++ if (bfi_image_ct_size && bfi_image_ct) ++ vfree(bfi_image_ct); ++ if (bfi_image_cb_size && bfi_image_cb) ++ vfree(bfi_image_cb); ++} ++ ++#endif +diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c +new file mode 100644 +index 0000000..f104e02 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_intr.c +@@ -0,0 +1,214 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include "bfad_drv.h" ++#include "bfad_trcmod.h" ++ ++BFA_TRC_FILE(LDRV, INTR); ++ ++/** ++ * bfa_isr BFA driver interrupt functions ++ */ ++irqreturn_t bfad_intx(int irq, void *dev_id); ++static int msix_disable; ++module_param(msix_disable, int, S_IRUGO | S_IWUSR); ++/** ++ * Line based interrupt handler. ++ */ ++irqreturn_t ++bfad_intx(int irq, void *dev_id) ++{ ++ struct bfad_s *bfad = dev_id; ++ struct list_head doneq; ++ unsigned long flags; ++ bfa_boolean_t rc; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ rc = bfa_intx(&bfad->bfa); ++ if (!rc) { ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ return IRQ_NONE; ++ } ++ ++ bfa_comp_deq(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (!list_empty(&doneq)) { ++ bfa_comp_process(&bfad->bfa, &doneq); ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_comp_free(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ bfa_trc_fp(bfad, irq); ++ } ++ ++ return IRQ_HANDLED; ++ ++} ++ ++static irqreturn_t ++bfad_msix(int irq, void *dev_id) ++{ ++ struct bfad_msix_s *vec = dev_id; ++ struct bfad_s *bfad = vec->bfad; ++ struct list_head doneq; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ ++ bfa_msix(&bfad->bfa, vec->msix.entry); ++ bfa_comp_deq(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ ++ if (!list_empty(&doneq)) { ++ bfa_comp_process(&bfad->bfa, &doneq); ++ ++ spin_lock_irqsave(&bfad->bfad_lock, flags); ++ bfa_comp_free(&bfad->bfa, &doneq); ++ spin_unlock_irqrestore(&bfad->bfad_lock, flags); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * Initialize the MSIX entry table. ++ */ ++static void ++bfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries, ++ int mask, int max_bit) ++{ ++ int i; ++ int match = 0x00000001; ++ ++ for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) { ++ if (mask & match) { ++ bfad->msix_tab[bfad->nvec].msix.entry = i; ++ bfad->msix_tab[bfad->nvec].bfad = bfad; ++ msix_entries[bfad->nvec].entry = i; ++ bfad->nvec++; ++ } ++ ++ match <<= 1; ++ } ++ ++} ++ ++int ++bfad_install_msix_handler(struct bfad_s *bfad) ++{ ++ int i, error = 0; ++ ++ for (i = 0; i < bfad->nvec; i++) { ++ error = request_irq(bfad->msix_tab[i].msix.vector, ++ (irq_handler_t) bfad_msix, 0, ++ BFAD_DRIVER_NAME, &bfad->msix_tab[i]); ++ bfa_trc(bfad, i); ++ bfa_trc(bfad, bfad->msix_tab[i].msix.vector); ++ if (error) { ++ int j; ++ ++ for (j = 0; j < i; j++) ++ free_irq(bfad->msix_tab[j].msix.vector, ++ &bfad->msix_tab[j]); ++ ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++/** ++ * Setup MSIX based interrupt. ++ */ ++int ++bfad_setup_intr(struct bfad_s *bfad) ++{ ++ int error = 0; ++ u32 mask = 0, i, num_bit = 0, max_bit = 0; ++ struct msix_entry msix_entries[MAX_MSIX_ENTRY]; ++ ++ /* Call BFA to get the msix map for this PCI function. */ ++ bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); ++ ++ /* Set up the msix entry table */ ++ bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); ++ ++ if (!msix_disable) { ++ error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec); ++ if (error) { ++ /* ++ * Only error number of vector is available. ++ * We don't have a mechanism to map multiple ++ * interrupts into one vector, so even if we ++ * can try to request less vectors, we don't ++ * know how to associate interrupt events to ++ * vectors. Linux doesn't dupicate vectors ++ * in the MSIX table for this case. ++ */ ++ ++ printk(KERN_WARNING "bfad%d: " ++ "pci_enable_msix failed (%d)," ++ " use line based.\n", bfad->inst_no, error); ++ ++ goto line_based; ++ } ++ ++ /* Save the vectors */ ++ for (i = 0; i < bfad->nvec; i++) { ++ bfa_trc(bfad, msix_entries[i].vector); ++ bfad->msix_tab[i].msix.vector = msix_entries[i].vector; ++ } ++ ++ bfa_msix_init(&bfad->bfa, bfad->nvec); ++ ++ bfad->bfad_flags |= BFAD_MSIX_ON; ++ ++ return error; ++ } ++ ++line_based: ++ error = 0; ++ if (request_irq ++ (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS, ++ BFAD_DRIVER_NAME, bfad) != 0) { ++ /* Enable interrupt handler failed */ ++ return 1; ++ } ++ ++ return error; ++} ++ ++void ++bfad_remove_intr(struct bfad_s *bfad) ++{ ++ int i; ++ ++ if (bfad->bfad_flags & BFAD_MSIX_ON) { ++ for (i = 0; i < bfad->nvec; i++) ++ free_irq(bfad->msix_tab[i].msix.vector, ++ &bfad->msix_tab[i]); ++ ++ pci_disable_msix(bfad->pcidev); ++ bfad->bfad_flags &= ~BFAD_MSIX_ON; ++ } else { ++ free_irq(bfad->pcidev->irq, bfad); ++ } ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfad_ipfc.h b/drivers/scsi/bfa/bfad_ipfc.h +new file mode 100644 +index 0000000..718bc52 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_ipfc.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DRV_IPFC_H__ ++#define __BFA_DRV_IPFC_H__ ++ ++ ++#define IPFC_NAME "" ++ ++#define bfad_ipfc_module_init(x) do {} while (0) ++#define bfad_ipfc_module_exit(x) do {} while (0) ++#define bfad_ipfc_probe(x) do {} while (0) ++#define bfad_ipfc_probe_undo(x) do {} while (0) ++#define bfad_ipfc_port_config(x, y) BFA_STATUS_OK ++#define bfad_ipfc_port_unconfig(x, y) do {} while (0) ++ ++#define bfad_ipfc_probe_post(x) do {} while (0) ++#define bfad_ipfc_port_new(x, y, z) BFA_STATUS_OK ++#define bfad_ipfc_port_delete(x, y) do {} while (0) ++#define bfad_ipfc_port_online(x, y) do {} while (0) ++#define bfad_ipfc_port_offline(x, y) do {} while (0) ++ ++#define bfad_ip_get_attr(x) BFA_STATUS_FAILED ++#define bfad_ip_reset_drv_stats(x) BFA_STATUS_FAILED ++#define bfad_ip_get_drv_stats(x, y) BFA_STATUS_FAILED ++#define bfad_ip_enable_ipfc(x, y, z) BFA_STATUS_FAILED ++ ++ ++#endif +diff --git a/drivers/scsi/bfa/bfad_os.c b/drivers/scsi/bfa/bfad_os.c +new file mode 100644 +index 0000000..faf47b4 +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_os.c +@@ -0,0 +1,50 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfad_os.c Linux driver OS specific calls. ++ */ ++ ++#include "bfa_os_inc.h" ++#include "bfad_drv.h" ++ ++void ++bfa_os_gettimeofday(struct bfa_timeval_s *tv) ++{ ++ struct timeval tmp_tv; ++ ++ do_gettimeofday(&tmp_tv); ++ tv->tv_sec = (u32) tmp_tv.tv_sec; ++ tv->tv_usec = (u32) tmp_tv.tv_usec; ++} ++ ++void ++bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id, ++ const char *fmt, ...) ++{ ++ va_list ap; ++ #define BFA_STRING_256 256 ++ char tmp[BFA_STRING_256]; ++ ++ va_start(ap, fmt); ++ vsprintf(tmp, fmt, ap); ++ va_end(ap); ++ ++ printk(tmp); ++} ++ ++ +diff --git a/drivers/scsi/bfa/bfad_tm.h b/drivers/scsi/bfa/bfad_tm.h +new file mode 100644 +index 0000000..4901b1b +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_tm.h +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* ++ * Brocade Fibre Channel HBA Linux Target Mode Driver ++ */ ++ ++/** ++ * tm/dummy/bfad_tm.h BFA callback dummy header file for BFA Linux target mode PCI interface module. ++ */ ++ ++#ifndef __BFAD_TM_H__ ++#define __BFAD_TM_H__ ++ ++#include ++ ++#define FCPT_NAME "" ++ ++/* ++ * Called from base Linux driver on (De)Init events ++ */ ++ ++/* attach tgt template with scst */ ++#define bfad_tm_module_init() do {} while (0) ++ ++/* detach/release tgt template */ ++#define bfad_tm_module_exit() do {} while (0) ++ ++#define bfad_tm_probe(x) do {} while (0) ++#define bfad_tm_probe_undo(x) do {} while (0) ++#define bfad_tm_probe_post(x) do {} while (0) ++ ++/* ++ * Called by base Linux driver but triggered by BFA FCS on config events ++ */ ++#define bfad_tm_port_new(x, y) BFA_STATUS_OK ++#define bfad_tm_port_delete(x, y) do {} while (0) ++ ++/* ++ * Called by base Linux driver but triggered by BFA FCS on PLOGI/O events ++ */ ++#define bfad_tm_port_online(x, y) do {} while (0) ++#define bfad_tm_port_offline(x, y) do {} while (0) ++ ++#endif +diff --git a/drivers/scsi/bfa/bfad_trcmod.h b/drivers/scsi/bfa/bfad_trcmod.h +new file mode 100644 +index 0000000..2827b2a +--- /dev/null ++++ b/drivers/scsi/bfa/bfad_trcmod.h +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfad_trcmod.h Linux driver trace modules ++ */ ++ ++ ++#ifndef __BFAD_TRCMOD_H__ ++#define __BFAD_TRCMOD_H__ ++ ++#include ++ ++/* ++ * !!! Only append to the enums defined here to avoid any versioning ++ * !!! needed between trace utility and driver version ++ */ ++enum { ++ /* 2.6 Driver */ ++ BFA_TRC_LDRV_BFAD = 1, ++ BFA_TRC_LDRV_BFAD_2_6 = 2, ++ BFA_TRC_LDRV_BFAD_2_6_9 = 3, ++ BFA_TRC_LDRV_BFAD_2_6_10 = 4, ++ BFA_TRC_LDRV_INTR = 5, ++ BFA_TRC_LDRV_IOCTL = 6, ++ BFA_TRC_LDRV_OS = 7, ++ BFA_TRC_LDRV_IM = 8, ++ BFA_TRC_LDRV_IM_2_6 = 9, ++ BFA_TRC_LDRV_IM_2_6_9 = 10, ++ BFA_TRC_LDRV_IM_2_6_10 = 11, ++ BFA_TRC_LDRV_TM = 12, ++ BFA_TRC_LDRV_IPFC = 13, ++ BFA_TRC_LDRV_IM_2_4 = 14, ++ BFA_TRC_LDRV_IM_VMW = 15, ++ BFA_TRC_LDRV_IM_LT_2_6_10 = 16, ++}; ++ ++#endif /* __BFAD_TRCMOD_H__ */ +diff --git a/drivers/scsi/bfa/fab.c b/drivers/scsi/bfa/fab.c +new file mode 100644 +index 0000000..7e3a4d5 +--- /dev/null ++++ b/drivers/scsi/bfa/fab.c +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "lport_priv.h" ++ ++/** ++ * fab.c port fab implementation. ++ */ ++ ++/** ++ * bfa_fcs_port_fab_public port fab public functions ++ */ ++ ++/** ++ * Called by port to initialize fabric services of the base port. ++ */ ++void ++bfa_fcs_port_fab_init(struct bfa_fcs_port_s *port) ++{ ++ bfa_fcs_port_ns_init(port); ++ bfa_fcs_port_scn_init(port); ++ bfa_fcs_port_ms_init(port); ++} ++ ++/** ++ * Called by port to notify transition to online state. ++ */ ++void ++bfa_fcs_port_fab_online(struct bfa_fcs_port_s *port) ++{ ++ bfa_fcs_port_ns_online(port); ++ bfa_fcs_port_scn_online(port); ++} ++ ++/** ++ * Called by port to notify transition to offline state. ++ */ ++void ++bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *port) ++{ ++ bfa_fcs_port_ns_offline(port); ++ bfa_fcs_port_scn_offline(port); ++ bfa_fcs_port_ms_offline(port); ++} +diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c +new file mode 100644 +index 0000000..a8b14c4 +--- /dev/null ++++ b/drivers/scsi/bfa/fabric.c +@@ -0,0 +1,1278 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fabric.c Fabric module implementation. ++ */ ++ ++#include "fcs_fabric.h" ++#include "fcs_lport.h" ++#include "fcs_vport.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs_auth.h" ++#include "fcs.h" ++#include "fcbuild.h" ++#include ++#include ++#include ++ ++BFA_TRC_FILE(FCS, FABRIC); ++ ++#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */ ++#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */ ++ ++#define bfa_fcs_fabric_set_opertype(__fabric) do { \ ++ if (bfa_pport_get_topology((__fabric)->fcs->bfa) \ ++ == BFA_PPORT_TOPOLOGY_P2P) \ ++ (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \ ++ else \ ++ (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \ ++} while (0) ++ ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_delay(void *cbarg); ++static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_delete_comp(void *cbarg); ++static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, ++ struct fchs_s *fchs, u16 len); ++static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric, ++ struct fchs_s *fchs, u16 len); ++static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric); ++static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rspfchs); ++/** ++ * fcs_fabric_sm fabric state machine functions ++ */ ++ ++/** ++ * Fabric state machine events ++ */ ++enum bfa_fcs_fabric_event { ++ BFA_FCS_FABRIC_SM_CREATE = 1, /* fabric create from driver */ ++ BFA_FCS_FABRIC_SM_DELETE = 2, /* fabric delete from driver */ ++ BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */ ++ BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */ ++ BFA_FCS_FABRIC_SM_CONT_OP = 5, /* continue op from flogi/auth */ ++ BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* continue op from flogi/auth */ ++ BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* no fabric from flogi/auth ++ */ ++ BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* perform EVFP from ++ *flogi/auth */ ++ BFA_FCS_FABRIC_SM_ISOLATE = 9, /* isolate from EVFP processing */ ++ BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/* no VFT tagging from EVFP */ ++ BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */ ++ BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* authentication failed */ ++ BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* authentication successful ++ */ ++ BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */ ++ BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */ ++ BFA_FCS_FABRIC_SM_START = 16, /* fabric delete from driver */ ++}; ++ ++static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event); ++/** ++ * Beginning state before fabric creation. ++ */ ++static void ++bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_CREATE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created); ++ bfa_fcs_fabric_init(fabric); ++ bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL, ++ &fabric->bport.port_cfg, NULL); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_UP: ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Beginning state before fabric creation. ++ */ ++static void ++bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_START: ++ if (bfa_pport_is_linkup(fabric->fcs->bfa)) { ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); ++ bfa_fcs_fabric_login(fabric); ++ } else ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_UP: ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); ++ bfa_fcs_modexit_comp(fabric->fcs); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Link is down, awaiting LINK UP event from port. This is also the ++ * first state at fabric creation. ++ */ ++static void ++bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_LINK_UP: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); ++ bfa_fcs_fabric_login(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_RETRY_OP: ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * FLOGI is in progress, awaiting FLOGI reply. ++ */ ++static void ++bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_CONT_OP: ++ ++ bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); ++ fabric->fab_type = BFA_FCS_FABRIC_SWITCHED; ++ ++ if (fabric->auth_reqd && fabric->is_auth) { ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth); ++ bfa_trc(fabric->fcs, event); ++ } else { ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online); ++ bfa_fcs_fabric_notify_online(fabric); ++ } ++ break; ++ ++ case BFA_FCS_FABRIC_SM_RETRY_OP: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry); ++ bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer, ++ bfa_fcs_fabric_delay, fabric, ++ BFA_FCS_FABRIC_RETRY_DELAY); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LOOPBACK: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback); ++ bfa_lps_discard(fabric->lps); ++ bfa_fcs_fabric_set_opertype(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_NO_FABRIC: ++ fabric->fab_type = BFA_FCS_FABRIC_N2N; ++ bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); ++ bfa_fcs_fabric_notify_online(fabric); ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_lps_discard(fabric->lps); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_lps_discard(fabric->lps); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++ ++static void ++bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_DELAYED: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi); ++ bfa_fcs_fabric_login(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_timer_stop(&fabric->delay_timer); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_timer_stop(&fabric->delay_timer); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Authentication is in progress, awaiting authentication results. ++ */ ++static void ++bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_AUTH_FAILED: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed); ++ bfa_lps_discard(fabric->lps); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_AUTH_SUCCESS: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online); ++ bfa_fcs_fabric_notify_online(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_PERF_EVFP: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_lps_discard(fabric->lps); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Authentication failed ++ */ ++static void ++bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_fcs_fabric_notify_offline(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Port is in loopback mode. ++ */ ++static void ++bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_fcs_fabric_notify_offline(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * There is no attached fabric - private loop or NPort-to-NPort topology. ++ */ ++static void ++bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_lps_discard(fabric->lps); ++ bfa_fcs_fabric_notify_offline(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_NO_FABRIC: ++ bfa_trc(fabric->fcs, fabric->bb_credit); ++ bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Fabric is online - normal operating state. ++ */ ++static void ++bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown); ++ bfa_lps_discard(fabric->lps); ++ bfa_fcs_fabric_notify_offline(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_DELETE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting); ++ bfa_fcs_fabric_delete(fabric); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_AUTH_FAILED: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed); ++ bfa_lps_discard(fabric->lps); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_AUTH_SUCCESS: ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * Exchanging virtual fabric parameters. ++ */ ++static void ++bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_CONT_OP: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_ISOLATE: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++/** ++ * EVFP exchange complete and VFT tagging is enabled. ++ */ ++static void ++bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++} ++ ++/** ++ * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F). ++ */ ++static void ++bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ bfa_log(fabric->fcs->logm, BFA_LOG_FCS_FABRIC_ISOLATED, ++ fabric->bport.port_cfg.pwwn, fabric->fcs->port_vfid, ++ fabric->event_arg.swp_vfid); ++} ++ ++/** ++ * Fabric is being deleted, awaiting vport delete completions. ++ */ ++static void ++bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric, ++ enum bfa_fcs_fabric_event event) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_FABRIC_SM_DELCOMP: ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); ++ bfa_fcs_modexit_comp(fabric->fcs); ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_UP: ++ break; ++ ++ case BFA_FCS_FABRIC_SM_LINK_DOWN: ++ bfa_fcs_fabric_notify_offline(fabric); ++ break; ++ ++ default: ++ bfa_sm_fault(fabric->fcs, event); ++ } ++} ++ ++ ++ ++/** ++ * fcs_fabric_private fabric private functions ++ */ ++ ++static void ++bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; ++ ++ port_cfg->roles = BFA_PORT_ROLE_FCP_IM; ++ port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc); ++ port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc); ++} ++ ++/** ++ * Port Symbolic Name Creation for base port. ++ */ ++void ++bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg; ++ struct bfa_adapter_attr_s adapter_attr; ++ struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info; ++ ++ bfa_os_memset((void *)&adapter_attr, 0, ++ sizeof(struct bfa_adapter_attr_s)); ++ bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr); ++ ++ /* ++ * Model name/number ++ */ ++ strncpy((char *)&port_cfg->sym_name, adapter_attr.model, ++ BFA_FCS_PORT_SYMBNAME_MODEL_SZ); ++ strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ ++ /* ++ * Driver Version ++ */ ++ strncat((char *)&port_cfg->sym_name, (char *)driver_info->version, ++ BFA_FCS_PORT_SYMBNAME_VERSION_SZ); ++ strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ ++ /* ++ * Host machine name ++ */ ++ strncat((char *)&port_cfg->sym_name, ++ (char *)driver_info->host_machine_name, ++ BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ); ++ strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ ++ /* ++ * Host OS Info : ++ * If OS Patch Info is not there, do not truncate any bytes from the ++ * OS name string and instead copy the entire OS info string (64 bytes). ++ */ ++ if (driver_info->host_os_patch[0] == '\0') { ++ strncat((char *)&port_cfg->sym_name, ++ (char *)driver_info->host_os_name, BFA_FCS_OS_STR_LEN); ++ strncat((char *)&port_cfg->sym_name, ++ BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ } else { ++ strncat((char *)&port_cfg->sym_name, ++ (char *)driver_info->host_os_name, ++ BFA_FCS_PORT_SYMBNAME_OSINFO_SZ); ++ strncat((char *)&port_cfg->sym_name, ++ BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ ++ /* ++ * Append host OS Patch Info ++ */ ++ strncat((char *)&port_cfg->sym_name, ++ (char *)driver_info->host_os_patch, ++ BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ); ++ } ++ ++ /* ++ * null terminate ++ */ ++ port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0; ++} ++ ++/** ++ * bfa lps login completion callback ++ */ ++void ++bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status) ++{ ++ struct bfa_fcs_fabric_s *fabric = uarg; ++ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_trc(fabric->fcs, status); ++ ++ switch (status) { ++ case BFA_STATUS_OK: ++ fabric->stats.flogi_accepts++; ++ break; ++ ++ case BFA_STATUS_INVALID_MAC: ++ /* ++ * Only for CNA ++ */ ++ fabric->stats.flogi_acc_err++; ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); ++ ++ return; ++ ++ case BFA_STATUS_EPROTOCOL: ++ switch (bfa_lps_get_extstatus(fabric->lps)) { ++ case BFA_EPROTO_BAD_ACCEPT: ++ fabric->stats.flogi_acc_err++; ++ break; ++ ++ case BFA_EPROTO_UNKNOWN_RSP: ++ fabric->stats.flogi_unknown_rsp++; ++ break; ++ ++ default: ++ break; ++ } ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); ++ ++ return; ++ ++ case BFA_STATUS_FABRIC_RJT: ++ fabric->stats.flogi_rejects++; ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); ++ return; ++ ++ default: ++ fabric->stats.flogi_rsp_err++; ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP); ++ return; ++ } ++ ++ fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps); ++ bfa_trc(fabric->fcs, fabric->bb_credit); ++ ++ if (!bfa_lps_is_brcd_fabric(fabric->lps)) ++ fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps); ++ ++ /* ++ * Check port type. It should be 1 = F-port. ++ */ ++ if (bfa_lps_is_fport(fabric->lps)) { ++ fabric->bport.pid = bfa_lps_get_pid(fabric->lps); ++ fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps); ++ fabric->is_auth = bfa_lps_is_authreq(fabric->lps); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP); ++ } else { ++ /* ++ * Nport-2-Nport direct attached ++ */ ++ fabric->bport.port_topo.pn2n.rem_port_wwn = ++ bfa_lps_get_peer_pwwn(fabric->lps); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC); ++ } ++ ++ bfa_trc(fabric->fcs, fabric->bport.pid); ++ bfa_trc(fabric->fcs, fabric->is_npiv); ++ bfa_trc(fabric->fcs, fabric->is_auth); ++} ++ ++/** ++ * Allocate and send FLOGI. ++ */ ++static void ++bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_s *bfa = fabric->fcs->bfa; ++ struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; ++ u8 alpa = 0; ++ ++ if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP) ++ alpa = bfa_pport_get_myalpa(bfa); ++ ++ bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa), ++ pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd); ++ ++ fabric->stats.flogi_sent++; ++} ++ ++static void ++bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_fcs_vport_s *vport; ++ struct list_head *qe, *qen; ++ ++ bfa_trc(fabric->fcs, fabric->fabric_name); ++ ++ bfa_fcs_fabric_set_opertype(fabric); ++ fabric->stats.fabric_onlines++; ++ ++ /** ++ * notify online event to base and then virtual ports ++ */ ++ bfa_fcs_port_online(&fabric->bport); ++ ++ list_for_each_safe(qe, qen, &fabric->vport_q) { ++ vport = (struct bfa_fcs_vport_s *)qe; ++ bfa_fcs_vport_online(vport); ++ } ++} ++ ++static void ++bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_fcs_vport_s *vport; ++ struct list_head *qe, *qen; ++ ++ bfa_trc(fabric->fcs, fabric->fabric_name); ++ fabric->stats.fabric_offlines++; ++ ++ /** ++ * notify offline event first to vports and then base port. ++ */ ++ list_for_each_safe(qe, qen, &fabric->vport_q) { ++ vport = (struct bfa_fcs_vport_s *)qe; ++ bfa_fcs_vport_offline(vport); ++ } ++ ++ bfa_fcs_port_offline(&fabric->bport); ++ ++ fabric->fabric_name = 0; ++ fabric->fabric_ip_addr[0] = 0; ++} ++ ++static void ++bfa_fcs_fabric_delay(void *cbarg) ++{ ++ struct bfa_fcs_fabric_s *fabric = cbarg; ++ ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED); ++} ++ ++/** ++ * Delete all vports and wait for vport delete completions. ++ */ ++static void ++bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_fcs_vport_s *vport; ++ struct list_head *qe, *qen; ++ ++ list_for_each_safe(qe, qen, &fabric->vport_q) { ++ vport = (struct bfa_fcs_vport_s *)qe; ++ bfa_fcs_vport_delete(vport); ++ } ++ ++ bfa_fcs_port_delete(&fabric->bport); ++ bfa_wc_wait(&fabric->wc); ++} ++ ++static void ++bfa_fcs_fabric_delete_comp(void *cbarg) ++{ ++ struct bfa_fcs_fabric_s *fabric = cbarg; ++ ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP); ++} ++ ++ ++ ++/** ++ * fcs_fabric_public fabric public functions ++ */ ++ ++/** ++ * Module initialization ++ */ ++void ++bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs) ++{ ++ struct bfa_fcs_fabric_s *fabric; ++ ++ fabric = &fcs->fabric; ++ bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s)); ++ ++ /** ++ * Initialize base fabric. ++ */ ++ fabric->fcs = fcs; ++ INIT_LIST_HEAD(&fabric->vport_q); ++ INIT_LIST_HEAD(&fabric->vf_q); ++ fabric->lps = bfa_lps_alloc(fcs->bfa); ++ bfa_assert(fabric->lps); ++ ++ /** ++ * Initialize fabric delete completion handler. Fabric deletion is complete ++ * when the last vport delete is complete. ++ */ ++ bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric); ++ bfa_wc_up(&fabric->wc); /* For the base port */ ++ ++ bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE); ++ bfa_trc(fcs, 0); ++} ++ ++/** ++ * Module cleanup ++ */ ++void ++bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs) ++{ ++ struct bfa_fcs_fabric_s *fabric; ++ ++ bfa_trc(fcs, 0); ++ ++ /** ++ * Cleanup base fabric. ++ */ ++ fabric = &fcs->fabric; ++ bfa_lps_delete(fabric->lps); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE); ++} ++ ++/** ++ * Fabric module start -- kick starts FCS actions ++ */ ++void ++bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs) ++{ ++ struct bfa_fcs_fabric_s *fabric; ++ ++ bfa_trc(fcs, 0); ++ fabric = &fcs->fabric; ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START); ++} ++ ++/** ++ * Suspend fabric activity as part of driver suspend. ++ */ ++void ++bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs) ++{ ++} ++ ++bfa_boolean_t ++bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric) ++{ ++ return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback)); ++} ++ ++enum bfa_pport_type ++bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric) ++{ ++ return fabric->oper_type; ++} ++ ++/** ++ * Link up notification from BFA physical port module. ++ */ ++void ++bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP); ++} ++ ++/** ++ * Link down notification from BFA physical port module. ++ */ ++void ++bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric) ++{ ++ bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN); ++} ++ ++/** ++ * A child vport is being created in the fabric. ++ * ++ * Call from vport module at vport creation. A list of base port and vports ++ * belonging to a fabric is maintained to propagate link events. ++ * ++ * param[in] fabric - Fabric instance. This can be a base fabric or vf. ++ * param[in] vport - Vport being created. ++ * ++ * @return None (always succeeds) ++ */ ++void ++bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric, ++ struct bfa_fcs_vport_s *vport) ++{ ++ /** ++ * - add vport to fabric's vport_q ++ */ ++ bfa_trc(fabric->fcs, fabric->vf_id); ++ ++ list_add_tail(&vport->qe, &fabric->vport_q); ++ fabric->num_vports++; ++ bfa_wc_up(&fabric->wc); ++} ++ ++/** ++ * A child vport is being deleted from fabric. ++ * ++ * Vport is being deleted. ++ */ ++void ++bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric, ++ struct bfa_fcs_vport_s *vport) ++{ ++ list_del(&vport->qe); ++ fabric->num_vports--; ++ bfa_wc_down(&fabric->wc); ++} ++ ++/** ++ * Base port is deleted. ++ */ ++void ++bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric) ++{ ++ bfa_wc_down(&fabric->wc); ++} ++ ++/** ++ * Check if fabric is online. ++ * ++ * param[in] fabric - Fabric instance. This can be a base fabric or vf. ++ * ++ * @return TRUE/FALSE ++ */ ++int ++bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric) ++{ ++ return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online)); ++} ++ ++ ++bfa_status_t ++bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs, ++ struct bfa_port_cfg_s *port_cfg, ++ struct bfad_vf_s *vf_drv) ++{ ++ bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Lookup for a vport withing a fabric given its pwwn ++ */ ++struct bfa_fcs_vport_s * ++bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn) ++{ ++ struct bfa_fcs_vport_s *vport; ++ struct list_head *qe; ++ ++ list_for_each(qe, &fabric->vport_q) { ++ vport = (struct bfa_fcs_vport_s *)qe; ++ if (bfa_fcs_port_get_pwwn(&vport->lport) == pwwn) ++ return vport; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * In a given fabric, return the number of lports. ++ * ++ * param[in] fabric - Fabric instance. This can be a base fabric or vf. ++ * ++* @return : 1 or more. ++ */ ++u16 ++bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric) ++{ ++ return (fabric->num_vports); ++} ++ ++/** ++ * Unsolicited frame receive handling. ++ */ ++void ++bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs, ++ u16 len) ++{ ++ u32 pid = fchs->d_id; ++ struct bfa_fcs_vport_s *vport; ++ struct list_head *qe; ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd; ++ ++ bfa_trc(fabric->fcs, len); ++ bfa_trc(fabric->fcs, pid); ++ ++ /** ++ * Look for our own FLOGI frames being looped back. This means an ++ * external loopback cable is in place. Our own FLOGI frames are ++ * sometimes looped back when switch port gets temporarily bypassed. ++ */ ++ if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT)) ++ && (els_cmd->els_code == FC_ELS_FLOGI) ++ && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) { ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK); ++ return; ++ } ++ ++ /** ++ * FLOGI/EVFP exchanges should be consumed by base fabric. ++ */ ++ if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) { ++ bfa_trc(fabric->fcs, pid); ++ bfa_fcs_fabric_process_uf(fabric, fchs, len); ++ return; ++ } ++ ++ if (fabric->bport.pid == pid) { ++ /** ++ * All authentication frames should be routed to auth ++ */ ++ bfa_trc(fabric->fcs, els_cmd->els_code); ++ if (els_cmd->els_code == FC_ELS_AUTH) { ++ bfa_trc(fabric->fcs, els_cmd->els_code); ++ fabric->auth.response = (u8 *) els_cmd; ++ return; ++ } ++ ++ bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs)); ++ bfa_fcs_port_uf_recv(&fabric->bport, fchs, len); ++ return; ++ } ++ ++ /** ++ * look for a matching local port ID ++ */ ++ list_for_each(qe, &fabric->vport_q) { ++ vport = (struct bfa_fcs_vport_s *)qe; ++ if (vport->lport.pid == pid) { ++ bfa_fcs_port_uf_recv(&vport->lport, fchs, len); ++ return; ++ } ++ } ++ bfa_trc(fabric->fcs, els_cmd->els_code); ++ bfa_fcs_port_uf_recv(&fabric->bport, fchs, len); ++} ++ ++/** ++ * Unsolicited frames to be processed by fabric. ++ */ ++static void ++bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs, ++ u16 len) ++{ ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ bfa_trc(fabric->fcs, els_cmd->els_code); ++ ++ switch (els_cmd->els_code) { ++ case FC_ELS_FLOGI: ++ bfa_fcs_fabric_process_flogi(fabric, fchs, len); ++ break; ++ ++ default: ++ /* ++ * need to generate a LS_RJT ++ */ ++ break; ++ } ++} ++ ++/** ++ * Process incoming FLOGI ++ */ ++static void ++bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric, ++ struct fchs_s *fchs, u16 len) ++{ ++ struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1); ++ struct bfa_fcs_port_s *bport = &fabric->bport; ++ ++ bfa_trc(fabric->fcs, fchs->s_id); ++ ++ fabric->stats.flogi_rcvd++; ++ /* ++ * Check port type. It should be 0 = n-port. ++ */ ++ if (flogi->csp.port_type) { ++ /* ++ * @todo: may need to send a LS_RJT ++ */ ++ bfa_trc(fabric->fcs, flogi->port_name); ++ fabric->stats.flogi_rejected++; ++ return; ++ } ++ ++ fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred); ++ bport->port_topo.pn2n.rem_port_wwn = flogi->port_name; ++ bport->port_topo.pn2n.reply_oxid = fchs->ox_id; ++ ++ /* ++ * Send a Flogi Acc ++ */ ++ bfa_fcs_fabric_send_flogi_acc(fabric); ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC); ++} ++ ++static void ++bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric) ++{ ++ struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg; ++ struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n; ++ struct bfa_s *bfa = fabric->fcs->bfa; ++ struct bfa_fcxp_s *fcxp; ++ u16 reqlen; ++ struct fchs_s fchs; ++ ++ fcxp = bfa_fcs_fcxp_alloc(fabric->fcs); ++ /** ++ * Do not expect this failure -- expect remote node to retry ++ */ ++ if (!fcxp) ++ return; ++ ++ reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_os_hton3b(FC_FABRIC_PORT), ++ n2n_port->reply_oxid, pcfg->pwwn, ++ pcfg->nwwn, bfa_pport_get_maxfrsize(bfa), ++ bfa_pport_get_rx_bbcredit(bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps), ++ BFA_FALSE, FC_CLASS_3, reqlen, &fchs, ++ bfa_fcs_fabric_flogiacc_comp, fabric, ++ FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no ++ * response expected ++ */ ++} ++ ++/** ++ * Flogi Acc completion callback. ++ */ ++static void ++bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rspfchs) ++{ ++ struct bfa_fcs_fabric_s *fabric = cbarg; ++ ++ bfa_trc(fabric->fcs, status); ++} ++ ++/* ++ * ++ * @param[in] fabric - fabric ++ * @param[in] result - 1 ++ * ++ * @return - none ++ */ ++void ++bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status) ++{ ++ bfa_trc(fabric->fcs, status); ++ ++ if (status == FC_AUTH_STATE_SUCCESS) ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS); ++ else ++ bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED); ++} ++ ++/** ++ * Send AEN notification ++ */ ++static void ++bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port, ++ enum bfa_port_aen_event event) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = port->fcs->logm; ++ wwn_t pwwn = bfa_fcs_port_get_pwwn(port); ++ wwn_t fwwn = bfa_fcs_port_get_fabric_name(port); ++ char pwwn_ptr[BFA_STRING_32]; ++ char fwwn_ptr[BFA_STRING_32]; ++ ++ wwn2str(pwwn_ptr, pwwn); ++ wwn2str(fwwn_ptr, fwwn); ++ ++ switch (event) { ++ case BFA_PORT_AEN_FABRIC_NAME_CHANGE: ++ bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr, ++ fwwn_ptr); ++ break; ++ default: ++ break; ++ } ++ ++ aen_data.port.pwwn = pwwn; ++ aen_data.port.fwwn = fwwn; ++} ++ ++/* ++ * ++ * @param[in] fabric - fabric ++ * @param[in] wwn_t - new fabric name ++ * ++ * @return - none ++ */ ++void ++bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric, ++ wwn_t fabric_name) ++{ ++ bfa_trc(fabric->fcs, fabric_name); ++ ++ if (fabric->fabric_name == 0) { ++ /* ++ * With BRCD switches, we don't get Fabric Name in FLOGI. ++ * Don't generate a fabric name change event in this case. ++ */ ++ fabric->fabric_name = fabric_name; ++ } else { ++ fabric->fabric_name = fabric_name; ++ /* ++ * Generate a Event ++ */ ++ bfa_fcs_fabric_aen_post(&fabric->bport, ++ BFA_PORT_AEN_FABRIC_NAME_CHANGE); ++ } ++ ++} ++ ++/** ++ * Not used by FCS. ++ */ ++void ++bfa_cb_lps_flogo_comp(void *bfad, void *uarg) ++{ ++} ++ ++ +diff --git a/drivers/scsi/bfa/fcbuild.c b/drivers/scsi/bfa/fcbuild.c +new file mode 100644 +index 0000000..d174706 +--- /dev/null ++++ b/drivers/scsi/bfa/fcbuild.c +@@ -0,0 +1,1449 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++/* ++ * fcbuild.c - FC link service frame building and parsing routines ++ */ ++ ++#include ++#include "fcbuild.h" ++ ++/* ++ * static build functions ++ */ ++static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id); ++static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id); ++static struct fchs_s fc_els_req_tmpl; ++static struct fchs_s fc_els_rsp_tmpl; ++static struct fchs_s fc_bls_req_tmpl; ++static struct fchs_s fc_bls_rsp_tmpl; ++static struct fc_ba_acc_s ba_acc_tmpl; ++static struct fc_logi_s plogi_tmpl; ++static struct fc_prli_s prli_tmpl; ++static struct fc_rrq_s rrq_tmpl; ++static struct fchs_s fcp_fchs_tmpl; ++ ++void ++fcbuild_init(void) ++{ ++ /* ++ * fc_els_req_tmpl ++ */ ++ fc_els_req_tmpl.routing = FC_RTG_EXT_LINK; ++ fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST; ++ fc_els_req_tmpl.type = FC_TYPE_ELS; ++ fc_els_req_tmpl.f_ctl = ++ bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | ++ FCTL_SI_XFER); ++ fc_els_req_tmpl.rx_id = FC_RXID_ANY; ++ ++ /* ++ * fc_els_rsp_tmpl ++ */ ++ fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK; ++ fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY; ++ fc_els_rsp_tmpl.type = FC_TYPE_ELS; ++ fc_els_rsp_tmpl.f_ctl = ++ bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | ++ FCTL_END_SEQ | FCTL_SI_XFER); ++ fc_els_rsp_tmpl.rx_id = FC_RXID_ANY; ++ ++ /* ++ * fc_bls_req_tmpl ++ */ ++ fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK; ++ fc_bls_req_tmpl.type = FC_TYPE_BLS; ++ fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER); ++ fc_bls_req_tmpl.rx_id = FC_RXID_ANY; ++ ++ /* ++ * fc_bls_rsp_tmpl ++ */ ++ fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK; ++ fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC; ++ fc_bls_rsp_tmpl.type = FC_TYPE_BLS; ++ fc_bls_rsp_tmpl.f_ctl = ++ bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH | ++ FCTL_END_SEQ | FCTL_SI_XFER); ++ fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY; ++ ++ /* ++ * ba_acc_tmpl ++ */ ++ ba_acc_tmpl.seq_id_valid = 0; ++ ba_acc_tmpl.low_seq_cnt = 0; ++ ba_acc_tmpl.high_seq_cnt = 0xFFFF; ++ ++ /* ++ * plogi_tmpl ++ */ ++ plogi_tmpl.csp.verhi = FC_PH_VER_PH_3; ++ plogi_tmpl.csp.verlo = FC_PH_VER_4_3; ++ plogi_tmpl.csp.bbcred = bfa_os_htons(0x0004); ++ plogi_tmpl.csp.ciro = 0x1; ++ plogi_tmpl.csp.cisc = 0x0; ++ plogi_tmpl.csp.altbbcred = 0x0; ++ plogi_tmpl.csp.conseq = bfa_os_htons(0x00FF); ++ plogi_tmpl.csp.ro_bitmap = bfa_os_htons(0x0002); ++ plogi_tmpl.csp.e_d_tov = bfa_os_htonl(2000); ++ ++ plogi_tmpl.class3.class_valid = 1; ++ plogi_tmpl.class3.sequential = 1; ++ plogi_tmpl.class3.conseq = 0xFF; ++ plogi_tmpl.class3.ospx = 1; ++ ++ /* ++ * prli_tmpl ++ */ ++ prli_tmpl.command = FC_ELS_PRLI; ++ prli_tmpl.pglen = 0x10; ++ prli_tmpl.pagebytes = bfa_os_htons(0x0014); ++ prli_tmpl.parampage.type = FC_TYPE_FCP; ++ prli_tmpl.parampage.imagepair = 1; ++ prli_tmpl.parampage.servparams.rxrdisab = 1; ++ ++ /* ++ * rrq_tmpl ++ */ ++ rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ; ++ ++ /* ++ * fcp_fchs_tmpl ++ */ ++ fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA; ++ fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD; ++ fcp_fchs_tmpl.type = FC_TYPE_FCP; ++ fcp_fchs_tmpl.f_ctl = ++ bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER); ++ fcp_fchs_tmpl.seq_id = 1; ++ fcp_fchs_tmpl.rx_id = FC_RXID_ANY; ++} ++ ++static void ++fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u32 ox_id) ++{ ++ bfa_os_memset(fchs, 0, sizeof(struct fchs_s)); ++ ++ fchs->routing = FC_RTG_FC4_DEV_DATA; ++ fchs->cat_info = FC_CAT_UNSOLICIT_CTRL; ++ fchs->type = FC_TYPE_SERVICES; ++ fchs->f_ctl = ++ bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ | ++ FCTL_SI_XFER); ++ fchs->rx_id = FC_RXID_ANY; ++ fchs->d_id = (d_id); ++ fchs->s_id = (s_id); ++ fchs->ox_id = bfa_os_htons(ox_id); ++ ++ /** ++ * @todo no need to set ox_id for request ++ * no need to set rx_id for response ++ */ ++} ++ ++void ++fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id) ++{ ++ bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); ++ fchs->d_id = (d_id); ++ fchs->s_id = (s_id); ++ fchs->ox_id = bfa_os_htons(ox_id); ++} ++ ++static void ++fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id) ++{ ++ bfa_os_memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s)); ++ fchs->d_id = d_id; ++ fchs->s_id = s_id; ++ fchs->ox_id = ox_id; ++} ++ ++enum fc_parse_status ++fc_els_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd; ++ ++ len = len; ++ ++ switch (els_cmd->els_code) { ++ case FC_ELS_LS_RJT: ++ if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) ++ return (FC_PARSE_BUSY); ++ else ++ return (FC_PARSE_FAILURE); ++ ++ case FC_ELS_ACC: ++ return (FC_PARSE_OK); ++ } ++ return (FC_PARSE_OK); ++} ++ ++static void ++fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id) ++{ ++ bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); ++ fchs->d_id = d_id; ++ fchs->s_id = s_id; ++ fchs->ox_id = ox_id; ++} ++ ++static u16 ++fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size, u8 els_code) ++{ ++ struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); ++ ++ bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); ++ ++ plogi->els_cmd.els_code = els_code; ++ if (els_code == FC_ELS_PLOGI) ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ else ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size); ++ ++ bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); ++ bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); ++ ++ return (sizeof(struct fc_logi_s)); ++} ++ ++u16 ++fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size, u8 set_npiv, u8 set_auth, ++ u16 local_bb_credits) ++{ ++ u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); ++ u32 *vvl_info; ++ ++ bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); ++ ++ flogi->els_cmd.els_code = FC_ELS_FLOGI; ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); ++ flogi->port_name = port_name; ++ flogi->node_name = node_name; ++ ++ /* ++ * Set the NPIV Capability Bit ( word 1, bit 31) of Common ++ * Service Parameters. ++ */ ++ flogi->csp.ciro = set_npiv; ++ ++ /* set AUTH capability */ ++ flogi->csp.security = set_auth; ++ ++ flogi->csp.bbcred = bfa_os_htons(local_bb_credits); ++ ++ /* Set brcd token in VVL */ ++ vvl_info = (u32 *)&flogi->vvl[0]; ++ ++ /* set the flag to indicate the presence of VVL */ ++ flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ ++ vvl_info[0] = bfa_os_htonl(FLOGI_VVL_BRCD); ++ ++ return (sizeof(struct fc_logi_s)); ++} ++ ++u16 ++fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size, u16 local_bb_credits) ++{ ++ u32 d_id = 0; ++ ++ bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ flogi->els_cmd.els_code = FC_ELS_ACC; ++ flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); ++ flogi->port_name = port_name; ++ flogi->node_name = node_name; ++ ++ flogi->csp.bbcred = bfa_os_htons(local_bb_credits); ++ ++ return (sizeof(struct fc_logi_s)); ++} ++ ++u16 ++fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size) ++{ ++ u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); ++ ++ bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); ++ ++ flogi->els_cmd.els_code = FC_ELS_FDISC; ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); ++ flogi->port_name = port_name; ++ flogi->node_name = node_name; ++ ++ return (sizeof(struct fc_logi_s)); ++} ++ ++u16 ++fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size) ++{ ++ return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, ++ node_name, pdu_size, FC_ELS_PLOGI); ++} ++ ++u16 ++fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size) ++{ ++ return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name, ++ node_name, pdu_size, FC_ELS_ACC); ++} ++ ++enum fc_parse_status ++fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) ++{ ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ struct fc_logi_s *plogi; ++ struct fc_ls_rjt_s *ls_rjt; ++ ++ switch (els_cmd->els_code) { ++ case FC_ELS_LS_RJT: ++ ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); ++ if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) ++ return (FC_PARSE_BUSY); ++ else ++ return (FC_PARSE_FAILURE); ++ case FC_ELS_ACC: ++ plogi = (struct fc_logi_s *) (fchs + 1); ++ if (len < sizeof(struct fc_logi_s)) ++ return (FC_PARSE_FAILURE); ++ ++ if (!wwn_is_equal(plogi->port_name, port_name)) ++ return (FC_PARSE_FAILURE); ++ ++ if (!plogi->class3.class_valid) ++ return (FC_PARSE_FAILURE); ++ ++ if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) ++ return (FC_PARSE_FAILURE); ++ ++ return (FC_PARSE_OK); ++ default: ++ return (FC_PARSE_FAILURE); ++ } ++} ++ ++enum fc_parse_status ++fc_plogi_parse(struct fchs_s *fchs) ++{ ++ struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); ++ ++ if (plogi->class3.class_valid != 1) ++ return FC_PARSE_FAILURE; ++ ++ if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ) ++ || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ) ++ || (plogi->class3.rxsz == 0)) ++ return (FC_PARSE_FAILURE); ++ ++ return FC_PARSE_OK; ++} ++ ++u16 ++fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id) ++{ ++ struct fc_prli_s *prli = (struct fc_prli_s *) (pld); ++ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); ++ ++ prli->command = FC_ELS_PRLI; ++ prli->parampage.servparams.initiator = 1; ++ prli->parampage.servparams.retry = 1; ++ prli->parampage.servparams.rec_support = 1; ++ prli->parampage.servparams.task_retry_id = 0; ++ prli->parampage.servparams.confirm = 1; ++ ++ return (sizeof(struct fc_prli_s)); ++} ++ ++u16 ++fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id, enum bfa_port_role role) ++{ ++ struct fc_prli_s *prli = (struct fc_prli_s *) (pld); ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); ++ ++ prli->command = FC_ELS_ACC; ++ ++ if ((role & BFA_PORT_ROLE_FCP_TM) == BFA_PORT_ROLE_FCP_TM) ++ prli->parampage.servparams.target = 1; ++ else ++ prli->parampage.servparams.initiator = 1; ++ ++ prli->parampage.rspcode = FC_PRLI_ACC_XQTD; ++ ++ return (sizeof(struct fc_prli_s)); ++} ++ ++enum fc_parse_status ++fc_prli_rsp_parse(struct fc_prli_s *prli, int len) ++{ ++ if (len < sizeof(struct fc_prli_s)) ++ return (FC_PARSE_FAILURE); ++ ++ if (prli->command != FC_ELS_ACC) ++ return (FC_PARSE_FAILURE); ++ ++ if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD) ++ && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG)) ++ return (FC_PARSE_FAILURE); ++ ++ if (prli->parampage.servparams.target != 1) ++ return (FC_PARSE_FAILURE); ++ ++ return (FC_PARSE_OK); ++} ++ ++enum fc_parse_status ++fc_prli_parse(struct fc_prli_s *prli) ++{ ++ if (prli->parampage.type != FC_TYPE_FCP) ++ return (FC_PARSE_FAILURE); ++ ++ if (!prli->parampage.imagepair) ++ return (FC_PARSE_FAILURE); ++ ++ if (!prli->parampage.servparams.initiator) ++ return (FC_PARSE_FAILURE); ++ ++ return (FC_PARSE_OK); ++} ++ ++u16 ++fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id, ++ u32 s_id, u16 ox_id, wwn_t port_name) ++{ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ memset(logo, '\0', sizeof(struct fc_logo_s)); ++ logo->els_cmd.els_code = FC_ELS_LOGO; ++ logo->nport_id = (s_id); ++ logo->orig_port_name = port_name; ++ ++ return (sizeof(struct fc_logo_s)); ++} ++ ++static u16 ++fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name, u8 els_code) ++{ ++ memset(adisc, '\0', sizeof(struct fc_adisc_s)); ++ ++ adisc->els_cmd.els_code = els_code; ++ ++ if (els_code == FC_ELS_ADISC) ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ else ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ adisc->orig_HA = 0; ++ adisc->orig_port_name = port_name; ++ adisc->orig_node_name = node_name; ++ adisc->nport_id = (s_id); ++ ++ return (sizeof(struct fc_adisc_s)); ++} ++ ++u16 ++fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name) ++{ ++ return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, ++ node_name, FC_ELS_ADISC); ++} ++ ++u16 ++fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name) ++{ ++ return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name, ++ node_name, FC_ELS_ACC); ++} ++ ++enum fc_parse_status ++fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name, ++ wwn_t node_name) ++{ ++ ++ if (len < sizeof(struct fc_adisc_s)) ++ return (FC_PARSE_FAILURE); ++ ++ if (adisc->els_cmd.els_code != FC_ELS_ACC) ++ return (FC_PARSE_FAILURE); ++ ++ if (!wwn_is_equal(adisc->orig_port_name, port_name)) ++ return (FC_PARSE_FAILURE); ++ ++ return (FC_PARSE_OK); ++} ++ ++enum fc_parse_status ++fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap, ++ wwn_t node_name, wwn_t port_name) ++{ ++ struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld; ++ ++ if (adisc->els_cmd.els_code != FC_ELS_ACC) ++ return (FC_PARSE_FAILURE); ++ ++ if ((adisc->nport_id == (host_dap)) ++ && wwn_is_equal(adisc->orig_port_name, port_name) ++ && wwn_is_equal(adisc->orig_node_name, node_name)) ++ return (FC_PARSE_OK); ++ ++ return (FC_PARSE_FAILURE); ++} ++ ++enum fc_parse_status ++fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) ++{ ++ struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); ++ ++ if (pdisc->class3.class_valid != 1) ++ return FC_PARSE_FAILURE; ++ ++ if ((bfa_os_ntohs(pdisc->class3.rxsz) < ++ (FC_MIN_PDUSZ - sizeof(struct fchs_s))) ++ || (pdisc->class3.rxsz == 0)) ++ return (FC_PARSE_FAILURE); ++ ++ if (!wwn_is_equal(pdisc->port_name, port_name)) ++ return (FC_PARSE_FAILURE); ++ ++ if (!wwn_is_equal(pdisc->node_name, node_name)) ++ return (FC_PARSE_FAILURE); ++ ++ return FC_PARSE_OK; ++} ++ ++u16 ++fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) ++{ ++ bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); ++ fchs->cat_info = FC_CAT_ABTS; ++ fchs->d_id = (d_id); ++ fchs->s_id = (s_id); ++ fchs->ox_id = bfa_os_htons(ox_id); ++ ++ return (sizeof(struct fchs_s)); ++} ++ ++enum fc_parse_status ++fc_abts_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ if ((fchs->cat_info == FC_CAT_BA_ACC) ++ || (fchs->cat_info == FC_CAT_BA_RJT)) ++ return (FC_PARSE_OK); ++ ++ return (FC_PARSE_FAILURE); ++} ++ ++u16 ++fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, ++ u32 s_id, u16 ox_id, u16 rrq_oxid) ++{ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ /* ++ * build rrq payload ++ */ ++ bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); ++ rrq->s_id = (s_id); ++ rrq->ox_id = bfa_os_htons(rrq_oxid); ++ rrq->rx_id = FC_RXID_ANY; ++ ++ return (sizeof(struct fc_rrq_s)); ++} ++ ++u16 ++fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, ++ u16 ox_id) ++{ ++ struct fc_els_cmd_s *acc = pld; ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ memset(acc, 0, sizeof(struct fc_els_cmd_s)); ++ acc->els_code = FC_ELS_ACC; ++ ++ return (sizeof(struct fc_els_cmd_s)); ++} ++ ++u16 ++fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id, ++ u32 s_id, u16 ox_id, u8 reason_code, ++ u8 reason_code_expl) ++{ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s)); ++ ++ ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT; ++ ls_rjt->reason_code = reason_code; ++ ls_rjt->reason_code_expl = reason_code_expl; ++ ls_rjt->vendor_unique = 0x00; ++ ++ return (sizeof(struct fc_ls_rjt_s)); ++} ++ ++u16 ++fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, ++ u32 s_id, u16 ox_id, u16 rx_id) ++{ ++ fc_bls_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); ++ ++ fchs->rx_id = rx_id; ++ ++ ba_acc->ox_id = fchs->ox_id; ++ ba_acc->rx_id = fchs->rx_id; ++ ++ return (sizeof(struct fc_ba_acc_s)); ++} ++ ++u16 ++fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, ++ u32 d_id, u32 s_id, u16 ox_id) ++{ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ memset(els_cmd, 0, sizeof(struct fc_els_cmd_s)); ++ els_cmd->els_code = FC_ELS_ACC; ++ ++ return (sizeof(struct fc_els_cmd_s)); ++} ++ ++int ++fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) ++{ ++ int num_pages = 0; ++ struct fc_prlo_s *prlo; ++ struct fc_tprlo_s *tprlo; ++ ++ if (els_code == FC_ELS_PRLO) { ++ prlo = (struct fc_prlo_s *) (fc_frame + 1); ++ num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16; ++ } else { ++ tprlo = (struct fc_tprlo_s *) (fc_frame + 1); ++ num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; ++ } ++ return num_pages; ++} ++ ++u16 ++fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ int num_pages) ++{ ++ int page; ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ memset(tprlo_acc, 0, (num_pages * 16) + 4); ++ tprlo_acc->command = FC_ELS_ACC; ++ ++ tprlo_acc->page_len = 0x10; ++ tprlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4); ++ ++ for (page = 0; page < num_pages; page++) { ++ tprlo_acc->tprlo_acc_params[page].opa_valid = 0; ++ tprlo_acc->tprlo_acc_params[page].rpa_valid = 0; ++ tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; ++ tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0; ++ tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0; ++ } ++ return (bfa_os_ntohs(tprlo_acc->payload_len)); ++} ++ ++u16 ++fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ int num_pages) ++{ ++ int page; ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ memset(prlo_acc, 0, (num_pages * 16) + 4); ++ prlo_acc->command = FC_ELS_ACC; ++ prlo_acc->page_len = 0x10; ++ prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4); ++ ++ for (page = 0; page < num_pages; page++) { ++ prlo_acc->prlo_acc_params[page].opa_valid = 0; ++ prlo_acc->prlo_acc_params[page].rpa_valid = 0; ++ prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; ++ prlo_acc->prlo_acc_params[page].orig_process_assc = 0; ++ prlo_acc->prlo_acc_params[page].resp_process_assc = 0; ++ } ++ ++ return (bfa_os_ntohs(prlo_acc->payload_len)); ++} ++ ++u16 ++fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id, ++ u32 s_id, u16 ox_id, u32 data_format) ++{ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ memset(rnid, 0, sizeof(struct fc_rnid_cmd_s)); ++ ++ rnid->els_cmd.els_code = FC_ELS_RNID; ++ rnid->node_id_data_format = data_format; ++ ++ return (sizeof(struct fc_rnid_cmd_s)); ++} ++ ++u16 ++fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ u32 data_format, ++ struct fc_rnid_common_id_data_s *common_id_data, ++ struct fc_rnid_general_topology_data_s *gen_topo_data) ++{ ++ memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ rnid_acc->els_cmd.els_code = FC_ELS_ACC; ++ rnid_acc->node_id_data_format = data_format; ++ rnid_acc->common_id_data_length = ++ sizeof(struct fc_rnid_common_id_data_s); ++ rnid_acc->common_id_data = *common_id_data; ++ ++ if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { ++ rnid_acc->specific_id_data_length = ++ sizeof(struct fc_rnid_general_topology_data_s); ++ bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data); ++ return (sizeof(struct fc_rnid_acc_s)); ++ } else { ++ return (sizeof(struct fc_rnid_acc_s) - ++ sizeof(struct fc_rnid_general_topology_data_s)); ++ } ++ ++} ++ ++u16 ++fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id, ++ u32 s_id, u16 ox_id) ++{ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s)); ++ ++ rpsc->els_cmd.els_code = FC_ELS_RPSC; ++ return (sizeof(struct fc_rpsc_cmd_s)); ++} ++ ++u16 ++fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2, ++ u32 d_id, u32 s_id, u32 *pid_list, ++ u16 npids) ++{ ++ u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id)); ++ int i = 0; ++ ++ fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0); ++ ++ memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s)); ++ ++ rpsc2->els_cmd.els_code = FC_ELS_RPSC; ++ rpsc2->token = bfa_os_htonl(FC_BRCD_TOKEN); ++ rpsc2->num_pids = bfa_os_htons(npids); ++ for (i = 0; i < npids; i++) ++ rpsc2->pid_list[i].pid = pid_list[i]; ++ ++ return (sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) * ++ (sizeof(u32)))); ++} ++ ++u16 ++fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ struct fc_rpsc_speed_info_s *oper_speed) ++{ ++ memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s)); ++ ++ fc_els_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ rpsc_acc->command = FC_ELS_ACC; ++ rpsc_acc->num_entries = bfa_os_htons(1); ++ ++ rpsc_acc->speed_info[0].port_speed_cap = ++ bfa_os_htons(oper_speed->port_speed_cap); ++ ++ rpsc_acc->speed_info[0].port_op_speed = ++ bfa_os_htons(oper_speed->port_op_speed); ++ ++ return (sizeof(struct fc_rpsc_acc_s)); ++ ++} ++ ++/* ++ * TBD - ++ * . get rid of unnecessary memsets ++ */ ++ ++u16 ++fc_logo_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ len = len; ++ if (els_cmd->els_code != FC_ELS_ACC) ++ return FC_PARSE_FAILURE; ++ ++ return FC_PARSE_OK; ++} ++ ++u16 ++fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size) ++{ ++ struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); ++ ++ bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); ++ ++ pdisc->els_cmd.els_code = FC_ELS_PDISC; ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size); ++ pdisc->port_name = port_name; ++ pdisc->node_name = node_name; ++ ++ return (sizeof(struct fc_logi_s)); ++} ++ ++u16 ++fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) ++{ ++ struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); ++ ++ if (len < sizeof(struct fc_logi_s)) ++ return (FC_PARSE_LEN_INVAL); ++ ++ if (pdisc->els_cmd.els_code != FC_ELS_ACC) ++ return (FC_PARSE_ACC_INVAL); ++ ++ if (!wwn_is_equal(pdisc->port_name, port_name)) ++ return (FC_PARSE_PWWN_NOT_EQUAL); ++ ++ if (!pdisc->class3.class_valid) ++ return (FC_PARSE_NWWN_NOT_EQUAL); ++ ++ if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) ++ return (FC_PARSE_RXSZ_INVAL); ++ ++ return (FC_PARSE_OK); ++} ++ ++u16 ++fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, ++ int num_pages) ++{ ++ struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); ++ int page; ++ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ memset(prlo, 0, (num_pages * 16) + 4); ++ prlo->command = FC_ELS_PRLO; ++ prlo->page_len = 0x10; ++ prlo->payload_len = bfa_os_htons((num_pages * 16) + 4); ++ ++ for (page = 0; page < num_pages; page++) { ++ prlo->prlo_params[page].type = FC_TYPE_FCP; ++ prlo->prlo_params[page].opa_valid = 0; ++ prlo->prlo_params[page].rpa_valid = 0; ++ prlo->prlo_params[page].orig_process_assc = 0; ++ prlo->prlo_params[page].resp_process_assc = 0; ++ } ++ ++ return (bfa_os_ntohs(prlo->payload_len)); ++} ++ ++u16 ++fc_prlo_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); ++ int num_pages = 0; ++ int page = 0; ++ ++ len = len; ++ ++ if (prlo->command != FC_ELS_ACC) ++ return (FC_PARSE_FAILURE); ++ ++ num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16; ++ ++ for (page = 0; page < num_pages; page++) { ++ if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) ++ return FC_PARSE_FAILURE; ++ ++ if (prlo->prlo_acc_params[page].opa_valid != 0) ++ return FC_PARSE_FAILURE; ++ ++ if (prlo->prlo_acc_params[page].rpa_valid != 0) ++ return FC_PARSE_FAILURE; ++ ++ if (prlo->prlo_acc_params[page].orig_process_assc != 0) ++ return FC_PARSE_FAILURE; ++ ++ if (prlo->prlo_acc_params[page].resp_process_assc != 0) ++ return FC_PARSE_FAILURE; ++ } ++ return (FC_PARSE_OK); ++ ++} ++ ++u16 ++fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, int num_pages, ++ enum fc_tprlo_type tprlo_type, u32 tpr_id) ++{ ++ struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); ++ int page; ++ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ memset(tprlo, 0, (num_pages * 16) + 4); ++ tprlo->command = FC_ELS_TPRLO; ++ tprlo->page_len = 0x10; ++ tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4); ++ ++ for (page = 0; page < num_pages; page++) { ++ tprlo->tprlo_params[page].type = FC_TYPE_FCP; ++ tprlo->tprlo_params[page].opa_valid = 0; ++ tprlo->tprlo_params[page].rpa_valid = 0; ++ tprlo->tprlo_params[page].orig_process_assc = 0; ++ tprlo->tprlo_params[page].resp_process_assc = 0; ++ if (tprlo_type == FC_GLOBAL_LOGO) { ++ tprlo->tprlo_params[page].global_process_logout = 1; ++ } else if (tprlo_type == FC_TPR_LOGO) { ++ tprlo->tprlo_params[page].tpo_nport_valid = 1; ++ tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); ++ } ++ } ++ ++ return (bfa_os_ntohs(tprlo->payload_len)); ++} ++ ++u16 ++fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); ++ int num_pages = 0; ++ int page = 0; ++ ++ len = len; ++ ++ if (tprlo->command != FC_ELS_ACC) ++ return (FC_PARSE_ACC_INVAL); ++ ++ num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; ++ ++ for (page = 0; page < num_pages; page++) { ++ if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) ++ return (FC_PARSE_NOT_FCP); ++ if (tprlo->tprlo_acc_params[page].opa_valid != 0) ++ return (FC_PARSE_OPAFLAG_INVAL); ++ if (tprlo->tprlo_acc_params[page].rpa_valid != 0) ++ return (FC_PARSE_RPAFLAG_INVAL); ++ if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) ++ return (FC_PARSE_OPA_INVAL); ++ if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) ++ return (FC_PARSE_RPA_INVAL); ++ } ++ return (FC_PARSE_OK); ++} ++ ++enum fc_parse_status ++fc_rrq_rsp_parse(struct fchs_s *fchs, int len) ++{ ++ struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ len = len; ++ if (els_cmd->els_code != FC_ELS_ACC) ++ return FC_PARSE_FAILURE; ++ ++ return FC_PARSE_OK; ++} ++ ++u16 ++fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, u32 reason_code, ++ u32 reason_expl) ++{ ++ struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1); ++ ++ fc_bls_rsp_build(fchs, d_id, s_id, ox_id); ++ ++ fchs->cat_info = FC_CAT_BA_RJT; ++ ba_rjt->reason_code = reason_code; ++ ba_rjt->reason_expl = reason_expl; ++ return (sizeof(struct fc_ba_rjt_s)); ++} ++ ++static void ++fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) ++{ ++ bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); ++ cthdr->rev_id = CT_GS3_REVISION; ++ cthdr->gs_type = CT_GSTYPE_DIRSERVICE; ++ cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER; ++ cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); ++} ++ ++static void ++fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code) ++{ ++ bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); ++ cthdr->rev_id = CT_GS3_REVISION; ++ cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; ++ cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER; ++ cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); ++} ++ ++static void ++fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code, ++ u8 sub_type) ++{ ++ bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s)); ++ cthdr->rev_id = CT_GS3_REVISION; ++ cthdr->gs_type = CT_GSTYPE_MGMTSERVICE; ++ cthdr->gs_sub_type = sub_type; ++ cthdr->cmd_rsp_code = bfa_os_htons(cmd_code); ++} ++ ++u16 ++fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ wwn_t port_name) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_gidpn_req_s *gidpn = ++ (struct fcgs_gidpn_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN); ++ ++ bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s)); ++ gidpn->port_name = port_name; ++ return (sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ u32 port_id) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID); ++ ++ bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t)); ++ gpnid->dap = port_id; ++ return (sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ u32 port_id) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID); ++ ++ bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t)); ++ gnnid->dap = port_id; ++ return (sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_ct_rsp_parse(struct ct_hdr_s *cthdr) ++{ ++ if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { ++ if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) ++ return FC_PARSE_BUSY; ++ else ++ return FC_PARSE_FAILURE; ++ } ++ ++ return FC_PARSE_OK; ++} ++ ++u16 ++fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg, ++ u32 s_id, u16 ox_id) ++{ ++ u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER); ++ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ ++ bfa_os_memset(scr, 0, sizeof(struct fc_scr_s)); ++ scr->command = FC_ELS_SCR; ++ scr->reg_func = FC_SCR_REG_FUNC_FULL; ++ if (set_br_reg) ++ scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE; ++ ++ return (sizeof(struct fc_scr_s)); ++} ++ ++u16 ++fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, u32 s_id, ++ u16 ox_id) ++{ ++ u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER); ++ u16 payldlen; ++ ++ fc_els_req_build(fchs, d_id, s_id, ox_id); ++ rscn->command = FC_ELS_RSCN; ++ rscn->pagelen = sizeof(rscn->event[0]); ++ ++ payldlen = sizeof(u32) + rscn->pagelen; ++ rscn->payldlen = bfa_os_htons(payldlen); ++ ++ rscn->event[0].format = FC_RSCN_FORMAT_PORTID; ++ rscn->event[0].portid = s_id; ++ ++ return (sizeof(struct fc_rscn_pl_s)); ++} ++ ++u16 ++fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ enum bfa_port_role roles) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rftid_req_s *rftid = ++ (struct fcgs_rftid_req_s *) (cthdr + 1); ++ u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ u8 index; ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); ++ ++ bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); ++ ++ rftid->dap = s_id; ++ ++ /* By default, FCP FC4 Type is registered */ ++ index = FC_TYPE_FCP >> 5; ++ type_value = 1 << (FC_TYPE_FCP % 32); ++ rftid->fc4_type[index] = bfa_os_htonl(type_value); ++ ++ if (roles & BFA_PORT_ROLE_FCP_IPFC) { ++ index = FC_TYPE_IP >> 5; ++ type_value = 1 << (FC_TYPE_IP % 32); ++ rftid->fc4_type[index] |= bfa_os_htonl(type_value); ++ } ++ ++ return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 ox_id, u8 *fc4_bitmap, ++ u32 bitmap_size) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rftid_req_s *rftid = ++ (struct fcgs_rftid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID); ++ ++ bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s)); ++ ++ rftid->dap = s_id; ++ bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap, ++ (bitmap_size < 32 ? bitmap_size : 32)); ++ ++ return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ u8 fc4_type, u8 fc4_ftrs) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rffid_req_s *rffid = ++ (struct fcgs_rffid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID); ++ ++ bfa_os_memset(rffid, 0, sizeof(struct fcgs_rffid_req_s)); ++ ++ rffid->dap = s_id; ++ rffid->fc4ftr_bits = fc4_ftrs; ++ rffid->fc4_type = fc4_type; ++ ++ return (sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, ++ u8 *name) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rspnid_req_s *rspnid = ++ (struct fcgs_rspnid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, ox_id); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID); ++ ++ bfa_os_memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); ++ ++ rspnid->dap = s_id; ++ rspnid->spn_len = (u8) strlen((char *)name); ++ strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); ++ ++ return (sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u8 fc4_type) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_gidft_req_s *gidft = ++ (struct fcgs_gidft_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ ++ fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT); ++ ++ bfa_os_memset(gidft, 0, sizeof(struct fcgs_gidft_req_s)); ++ gidft->fc4_type = fc4_type; ++ gidft->domain_id = 0; ++ gidft->area_id = 0; ++ ++ return (sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, ++ wwn_t port_name) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rpnid_req_s *rpnid = ++ (struct fcgs_rpnid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID); ++ ++ bfa_os_memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s)); ++ rpnid->port_id = port_id; ++ rpnid->port_name = port_name; ++ ++ return (sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, ++ wwn_t node_name) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rnnid_req_s *rnnid = ++ (struct fcgs_rnnid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID); ++ ++ bfa_os_memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s)); ++ rnnid->port_id = port_id; ++ rnnid->node_name = node_name; ++ ++ return (sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, ++ u32 cos) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rcsid_req_s *rcsid = ++ (struct fcgs_rcsid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID); ++ ++ bfa_os_memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s)); ++ rcsid->port_id = port_id; ++ rcsid->cos = cos; ++ ++ return (sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id, ++ u8 port_type) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_rptid_req_s *rptid = ++ (struct fcgs_rptid_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID); ++ ++ bfa_os_memset(rptid, 0, sizeof(struct fcgs_rptid_req_s)); ++ rptid->port_id = port_id; ++ rptid->port_type = port_type; ++ ++ return (sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s)); ++} ++ ++u16 ++fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ struct fcgs_ganxt_req_s *ganxt = ++ (struct fcgs_ganxt_req_s *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_NAME_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT); ++ ++ bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s)); ++ ganxt->port_id = port_id; ++ ++ return (sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s)); ++} ++ ++/* ++ * Builds fc hdr and ct hdr for FDMI requests. ++ */ ++u16 ++fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 cmd_code) ++{ ++ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code); ++ ++ return (sizeof(struct ct_hdr_s)); ++} ++ ++/* ++ * Given a FC4 Type, this function returns a fc4 type bitmask ++ */ ++void ++fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask) ++{ ++ u8 index; ++ u32 *ptr = (u32 *) bit_mask; ++ u32 type_value; ++ ++ /* ++ * @todo : Check for bitmask size ++ */ ++ ++ index = fc4_type >> 5; ++ type_value = 1 << (fc4_type % 32); ++ ptr[index] = bfa_os_htonl(type_value); ++ ++} ++ ++/* ++ * GMAL Request ++ */ ++u16 ++fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD, ++ CT_GSSUBTYPE_CFGSERVER); ++ ++ bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t)); ++ gmal->wwn = wwn; ++ ++ return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t)); ++} ++ ++/* ++ * GFN (Get Fabric Name) Request ++ */ ++u16 ++fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn) ++{ ++ struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld; ++ fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1); ++ u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER); ++ ++ fc_gs_fchdr_build(fchs, d_id, s_id, 0); ++ fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD, ++ CT_GSSUBTYPE_CFGSERVER); ++ ++ bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t)); ++ gfn->wwn = wwn; ++ ++ return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t)); ++} +diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h +new file mode 100644 +index 0000000..4d24842 +--- /dev/null ++++ b/drivers/scsi/bfa/fcbuild.h +@@ -0,0 +1,273 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++/* ++ * fcbuild.h - FC link service frame building and parsing routines ++ */ ++ ++#ifndef __FCBUILD_H__ ++#define __FCBUILD_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Utility Macros/functions ++ */ ++ ++#define fcif_sof_set(_ifhdr, _sof) (_ifhdr)->sof = FC_ ## _sof ++#define fcif_eof_set(_ifhdr, _eof) (_ifhdr)->eof = FC_ ## _eof ++ ++#define wwn_is_equal(_wwn1, _wwn2) \ ++ (memcmp(&(_wwn1), &(_wwn2), sizeof(wwn_t)) == 0) ++ ++#define fc_roundup(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1)) ++ ++/* ++ * Given the fc response length, this routine will return ++ * the length of the actual payload bytes following the CT header. ++ * ++ * Assumes the input response length does not include the crc, eof, etc. ++ */ ++static inline u32 ++fc_get_ctresp_pyld_len(u32 resp_len) ++{ ++ return (resp_len - sizeof(struct ct_hdr_s)); ++} ++ ++/* ++ * Convert bfa speed to rpsc speed value. ++ */ ++static inline enum bfa_pport_speed ++fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed) ++{ ++ switch (speed) { ++ ++ case RPSC_OP_SPEED_1G: ++ return BFA_PPORT_SPEED_1GBPS; ++ ++ case RPSC_OP_SPEED_2G: ++ return BFA_PPORT_SPEED_2GBPS; ++ ++ case RPSC_OP_SPEED_4G: ++ return BFA_PPORT_SPEED_4GBPS; ++ ++ case RPSC_OP_SPEED_8G: ++ return BFA_PPORT_SPEED_8GBPS; ++ ++ default: ++ return BFA_PPORT_SPEED_UNKNOWN; ++ } ++} ++ ++/* ++ * Convert RPSC speed to bfa speed value. ++ */ ++static inline enum fc_rpsc_op_speed_s ++fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed) ++{ ++ switch (op_speed) { ++ ++ case BFA_PPORT_SPEED_1GBPS: ++ return RPSC_OP_SPEED_1G; ++ ++ case BFA_PPORT_SPEED_2GBPS: ++ return RPSC_OP_SPEED_2G; ++ ++ case BFA_PPORT_SPEED_4GBPS: ++ return RPSC_OP_SPEED_4G; ++ ++ case BFA_PPORT_SPEED_8GBPS: ++ return RPSC_OP_SPEED_8G; ++ ++ default: ++ return RPSC_OP_SPEED_NOT_EST; ++ } ++} ++enum fc_parse_status { ++ FC_PARSE_OK = 0, ++ FC_PARSE_FAILURE = 1, ++ FC_PARSE_BUSY = 2, ++ FC_PARSE_LEN_INVAL, ++ FC_PARSE_ACC_INVAL, ++ FC_PARSE_PWWN_NOT_EQUAL, ++ FC_PARSE_NWWN_NOT_EQUAL, ++ FC_PARSE_RXSZ_INVAL, ++ FC_PARSE_NOT_FCP, ++ FC_PARSE_OPAFLAG_INVAL, ++ FC_PARSE_RPAFLAG_INVAL, ++ FC_PARSE_OPA_INVAL, ++ FC_PARSE_RPA_INVAL, ++ ++}; ++ ++struct fc_templates_s { ++ struct fchs_s fc_els_req; ++ struct fchs_s fc_bls_req; ++ struct fc_logi_s plogi; ++ struct fc_rrq_s rrq; ++}; ++ ++void fcbuild_init(void); ++ ++u16 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name, u16 pdu_size, u8 set_npiv, ++ u8 set_auth, u16 local_bb_credits); ++u16 fc_fdisc_build(struct fchs_s *buf, struct fc_logi_s *flogi, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name, u16 pdu_size); ++u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name, u16 pdu_size, ++ u16 local_bb_credits); ++u16 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, ++ u32 s_id, u16 ox_id, wwn_t port_name, ++ wwn_t node_name, u16 pdu_size); ++enum fc_parse_status fc_plogi_parse(struct fchs_s *fchs); ++u16 fc_abts_build(struct fchs_s *buf, u32 d_id, u32 s_id, ++ u16 ox_id); ++enum fc_parse_status fc_abts_rsp_parse(struct fchs_s *buf, int len); ++u16 fc_rrq_build(struct fchs_s *buf, struct fc_rrq_s *rrq, u32 d_id, ++ u32 s_id, u16 ox_id, u16 rrq_oxid); ++enum fc_parse_status fc_rrq_rsp_parse(struct fchs_s *buf, int len); ++u16 fc_rspnid_build(struct fchs_s *fchs, void *pld, u32 s_id, ++ u16 ox_id, u8 *name); ++u16 fc_rftid_build(struct fchs_s *fchs, void *pld, u32 s_id, ++ u16 ox_id, enum bfa_port_role role); ++u16 fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 ox_id, u8 *fc4_bitmap, ++ u32 bitmap_size); ++u16 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 ox_id, u8 fc4_type, u8 fc4_ftrs); ++u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 ox_id, wwn_t port_name); ++u16 fc_gpnid_build(struct fchs_s *fchs, void *pld, u32 s_id, ++ u16 ox_id, u32 port_id); ++u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, ++ u8 set_br_reg, u32 s_id, u16 ox_id); ++u16 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, ++ u32 s_id, u16 ox_id, ++ wwn_t port_name, wwn_t node_name, u16 pdu_size); ++ ++u16 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ wwn_t port_name, wwn_t node_name); ++enum fc_parse_status fc_adisc_parse(struct fchs_s *fchs, void *pld, ++ u32 host_dap, ++ wwn_t node_name, wwn_t port_name); ++enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, ++ wwn_t port_name, wwn_t node_name); ++u16 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ wwn_t port_name, wwn_t node_name); ++u16 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, ++ u32 d_id, u32 s_id, u16 ox_id, ++ u8 reason_code, u8 reason_code_expl); ++u16 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd, ++ u32 d_id, u32 s_id, u16 ox_id); ++u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, ++ u32 s_id, u16 ox_id); ++enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len); ++ ++u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, ++ u32 s_id, u16 ox_id, ++ enum bfa_port_role role); ++u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, ++ u32 d_id, u32 s_id, u16 ox_id, ++ u32 data_format); ++u16 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ u32 data_format, ++ struct fc_rnid_common_id_data_s *common_id_data, ++ struct fc_rnid_general_topology_data_s * ++ gen_topo_data); ++u16 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rps2c, ++ u32 d_id, u32 s_id, ++ u32 *pid_list, u16 npids); ++u16 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, ++ u32 d_id, u32 s_id, u16 ox_id); ++u16 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ struct fc_rpsc_speed_info_s *oper_speed); ++u16 fc_gid_ft_build(struct fchs_s *fchs, void *pld, u32 s_id, ++ u8 fc4_type); ++u16 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u32 port_id, wwn_t port_name); ++u16 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u32 port_id, wwn_t node_name); ++u16 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u32 port_id, u32 cos); ++u16 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u32 port_id, u8 port_type); ++u16 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u32 port_id); ++u16 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, ++ u32 d_id, u32 s_id, u16 ox_id, ++ wwn_t port_name); ++u16 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, ++ u32 s_id, u16 ox_id); ++u16 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 cmd_code); ++u16 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ wwn_t wwn); ++u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ wwn_t wwn); ++void fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask); ++void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id); ++enum fc_parse_status fc_els_rsp_parse(struct fchs_s *fchs, int len); ++enum fc_parse_status fc_plogi_rsp_parse(struct fchs_s *fchs, int len, ++ wwn_t port_name); ++enum fc_parse_status fc_prli_parse(struct fc_prli_s *prli); ++enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, ++ wwn_t port_name); ++u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ u16 rx_id); ++int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code); ++u16 fc_tprlo_acc_build(struct fchs_s *fchs, ++ struct fc_tprlo_acc_s *tprlo_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ int num_pages); ++u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, ++ u32 d_id, u32 s_id, u16 ox_id, ++ int num_pages); ++u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len); ++u16 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, wwn_t port_name, wwn_t node_name, ++ u16 pdu_size); ++u16 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name); ++u16 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, int num_pages); ++u16 fc_prlo_rsp_parse(struct fchs_s *fchs, int len); ++u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, int num_pages, ++ enum fc_tprlo_type tprlo_type, u32 tpr_id); ++u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len); ++u16 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id, ++ u16 ox_id, u32 reason_code, ++ u32 reason_expl); ++u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, ++ u16 ox_id, u32 port_id); ++u16 fc_ct_rsp_parse(struct ct_hdr_s *cthdr); ++u16 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, ++ u32 s_id, u16 ox_id); ++#endif +diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c +new file mode 100644 +index 0000000..8ce5d89 +--- /dev/null ++++ b/drivers/scsi/bfa/fcpim.c +@@ -0,0 +1,844 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcpim.c - FCP initiator mode i-t nexus state machine ++ */ ++ ++#include ++#include ++#include "fcs_fcpim.h" ++#include "fcs_rport.h" ++#include "fcs_lport.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs.h" ++#include ++#include ++#include ++ ++BFA_TRC_FILE(FCS, FCPIM); ++ ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_itnim_timeout(void *arg); ++static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim); ++static void bfa_fcs_itnim_send_prli(void *itnim_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_itnim_prli_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_itnim_aen_event event); ++ ++/** ++ * fcs_itnim_sm FCS itnim state machine events ++ */ ++ ++enum bfa_fcs_itnim_event { ++ BFA_FCS_ITNIM_SM_ONLINE = 1, /* rport online event */ ++ BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */ ++ BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */ ++ BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */ ++ BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */ ++ BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */ ++ BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */ ++ BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */ ++ BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */ ++ BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ ++ BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ ++}; ++ ++static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event); ++ ++static struct bfa_sm_table_s itnim_sm_table[] = { ++ {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE}, ++ {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND}, ++ {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT}, ++ {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY}, ++ {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE}, ++ {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE}, ++ {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE}, ++ {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR}, ++}; ++ ++/** ++ * fcs_itnim_sm FCS itnim state machine ++ */ ++ ++static void ++bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_ONLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send); ++ bfa_fcs_itnim_send_prli(itnim, NULL); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_INITIATOR: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++ ++} ++ ++static void ++bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_FRMSENT: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_INITIATOR: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); ++ bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_RSP_OK: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online); ++ bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_RSP_ERROR: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry); ++ bfa_timer_start(itnim->fcs->bfa, &itnim->timer, ++ bfa_fcs_itnim_timeout, itnim, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcxp_discard(itnim->fcxp); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_INITIATOR: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); ++ /* ++ * dont discard fcxp. accept will reach same state ++ */ ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcxp_discard(itnim->fcxp); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_TIMEOUT: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send); ++ bfa_fcs_itnim_send_prli(itnim, NULL); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_timer_stop(&itnim->timer); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_INITIATOR: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); ++ bfa_timer_stop(&itnim->timer); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_timer_stop(&itnim->timer); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_HCB_ONLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online); ++ bfa_fcb_itnim_online(itnim->itnim_drv); ++ bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_itnim_offline(itnim->bfa_itnim); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline); ++ bfa_fcb_itnim_offline(itnim->itnim_drv); ++ bfa_itnim_offline(itnim->bfa_itnim); ++ if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE) { ++ bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT); ++ } else { ++ bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE); ++ } ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_HCB_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/* ++ * This state is set when a discovered rport is also in intiator mode. ++ * This ITN is marked as no_op and is not active and will not be truned into ++ * online state. ++ */ ++static void ++bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_fcs_itnim_event event) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_trc(itnim->fcs, event); ++ ++ switch (event) { ++ case BFA_FCS_ITNIM_SM_OFFLINE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_rport_itnim_ack(itnim->rport); ++ break; ++ ++ case BFA_FCS_ITNIM_SM_RSP_ERROR: ++ case BFA_FCS_ITNIM_SM_ONLINE: ++ case BFA_FCS_ITNIM_SM_INITIATOR: ++ break; ++ ++ case BFA_FCS_ITNIM_SM_DELETE: ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ bfa_fcs_itnim_free(itnim); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * itnim_private FCS ITNIM private interfaces ++ */ ++ ++static void ++bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim, ++ enum bfa_itnim_aen_event event) ++{ ++ struct bfa_fcs_rport_s *rport = itnim->rport; ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = rport->fcs->logm; ++ wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port); ++ wwn_t rpwwn = rport->pwwn; ++ char lpwwn_ptr[BFA_STRING_32]; ++ char rpwwn_ptr[BFA_STRING_32]; ++ ++ /* ++ * Don't post events for well known addresses ++ */ ++ if (BFA_FCS_PID_IS_WKA(rport->pid)) ++ return; ++ ++ wwn2str(lpwwn_ptr, lpwwn); ++ wwn2str(rpwwn_ptr, rpwwn); ++ ++ switch (event) { ++ case BFA_ITNIM_AEN_ONLINE: ++ bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_ITNIM_AEN_OFFLINE: ++ bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_ITNIM_AEN_DISCONNECT: ++ bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr); ++ break; ++ default: ++ break; ++ } ++ ++ aen_data.itnim.vf_id = rport->port->fabric->vf_id; ++ aen_data.itnim.ppwwn = ++ bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(itnim->fcs)); ++ aen_data.itnim.lpwwn = lpwwn; ++ aen_data.itnim.rpwwn = rpwwn; ++} ++ ++static void ++bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_itnim_s *itnim = itnim_cbarg; ++ struct bfa_fcs_rport_s *rport = itnim->rport; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ itnim->stats.fcxp_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe, ++ bfa_fcs_itnim_send_prli, itnim); ++ return; ++ } ++ itnim->fcxp = fcxp; ++ ++ len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), itnim->rport->pid, ++ bfa_fcs_port_get_fcid(port), 0); ++ ++ bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, len, &fchs, ++ bfa_fcs_itnim_prli_response, (void *)itnim, FC_MAX_PDUSZ, ++ FC_RA_TOV); ++ ++ itnim->stats.prli_sent++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT); ++} ++ ++static void ++bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg; ++ struct fc_els_cmd_s *els_cmd; ++ struct fc_prli_s *prli_resp; ++ struct fc_ls_rjt_s *ls_rjt; ++ struct fc_prli_params_s *sparams; ++ ++ bfa_trc(itnim->fcs, req_status); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ itnim->stats.prli_rsp_err++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR); ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ if (els_cmd->els_code == FC_ELS_ACC) { ++ prli_resp = (struct fc_prli_s *) els_cmd; ++ ++ if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) { ++ bfa_trc(itnim->fcs, rsp_len); ++ /* ++ * Check if this r-port is also in Initiator mode. ++ * If so, we need to set this ITN as a no-op. ++ */ ++ if (prli_resp->parampage.servparams.initiator) { ++ bfa_trc(itnim->fcs, prli_resp->parampage.type); ++ itnim->rport->scsi_function = ++ BFA_RPORT_INITIATOR; ++ itnim->stats.prli_rsp_acc++; ++ bfa_sm_send_event(itnim, ++ BFA_FCS_ITNIM_SM_INITIATOR); ++ return; ++ } ++ ++ itnim->stats.prli_rsp_parse_err++; ++ return; ++ } ++ itnim->rport->scsi_function = BFA_RPORT_TARGET; ++ ++ sparams = &prli_resp->parampage.servparams; ++ itnim->seq_rec = sparams->retry; ++ itnim->rec_support = sparams->rec_support; ++ itnim->task_retry_id = sparams->task_retry_id; ++ itnim->conf_comp = sparams->confirm; ++ ++ itnim->stats.prli_rsp_acc++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK); ++ } else { ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ bfa_trc(itnim->fcs, ls_rjt->reason_code); ++ bfa_trc(itnim->fcs, ls_rjt->reason_code_expl); ++ ++ itnim->stats.prli_rsp_rjt++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR); ++ } ++} ++ ++static void ++bfa_fcs_itnim_timeout(void *arg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)arg; ++ ++ itnim->stats.timeout++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_TIMEOUT); ++} ++ ++static void ++bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim) ++{ ++ bfa_itnim_delete(itnim->bfa_itnim); ++ bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv); ++} ++ ++ ++ ++/** ++ * itnim_public FCS ITNIM public interfaces ++ */ ++ ++/** ++ * Called by rport when a new rport is created. ++ * ++ * @param[in] rport - remote port. ++ */ ++struct bfa_fcs_itnim_s * ++bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ struct bfa_fcs_itnim_s *itnim; ++ struct bfad_itnim_s *itnim_drv; ++ struct bfa_itnim_s *bfa_itnim; ++ ++ /* ++ * call bfad to allocate the itnim ++ */ ++ bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv); ++ if (itnim == NULL) { ++ bfa_trc(port->fcs, rport->pwwn); ++ return NULL; ++ } ++ ++ /* ++ * Initialize itnim ++ */ ++ itnim->rport = rport; ++ itnim->fcs = rport->fcs; ++ itnim->itnim_drv = itnim_drv; ++ ++ /* ++ * call BFA to create the itnim ++ */ ++ bfa_itnim = bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim); ++ ++ if (bfa_itnim == NULL) { ++ bfa_trc(port->fcs, rport->pwwn); ++ bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv); ++ bfa_assert(0); ++ return NULL; ++ } ++ ++ itnim->bfa_itnim = bfa_itnim; ++ itnim->seq_rec = BFA_FALSE; ++ itnim->rec_support = BFA_FALSE; ++ itnim->conf_comp = BFA_FALSE; ++ itnim->task_retry_id = BFA_FALSE; ++ ++ /* ++ * Set State machine ++ */ ++ bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); ++ ++ return itnim; ++} ++ ++/** ++ * Called by rport to delete the instance of FCPIM. ++ * ++ * @param[in] rport - remote port. ++ */ ++void ++bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pid); ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE); ++} ++ ++/** ++ * Notification from rport that PLOGI is complete to initiate FC-4 session. ++ */ ++void ++bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim) ++{ ++ itnim->stats.onlines++; ++ ++ if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) { ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE); ++ } else { ++ /* ++ * For well known addresses, we set the itnim to initiator ++ * state ++ */ ++ itnim->stats.initiator++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR); ++ } ++} ++ ++/** ++ * Called by rport to handle a remote device offline. ++ */ ++void ++bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim) ++{ ++ itnim->stats.offlines++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE); ++} ++ ++/** ++ * Called by rport when remote port is known to be an initiator from ++ * PRLI received. ++ */ ++void ++bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pid); ++ itnim->stats.initiator++; ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR); ++} ++ ++/** ++ * Called by rport to check if the itnim is online. ++ */ ++bfa_status_t ++bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim) ++{ ++ bfa_trc(itnim->fcs, itnim->rport->pid); ++ switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) { ++ case BFA_ITNIM_ONLINE: ++ case BFA_ITNIM_INITIATIOR: ++ return BFA_STATUS_OK; ++ ++ default: ++ return BFA_STATUS_NO_FCPIM_NEXUS; ++ ++ } ++} ++ ++/** ++ * BFA completion callback for bfa_itnim_online(). ++ */ ++void ++bfa_cb_itnim_online(void *cbarg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg; ++ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE); ++} ++ ++/** ++ * BFA completion callback for bfa_itnim_offline(). ++ */ ++void ++bfa_cb_itnim_offline(void *cb_arg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; ++ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE); ++} ++ ++/** ++ * Mark the beginning of PATH TOV handling. IO completion callbacks ++ * are still pending. ++ */ ++void ++bfa_cb_itnim_tov_begin(void *cb_arg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; ++ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_fcb_itnim_tov_begin(itnim->itnim_drv); ++} ++ ++/** ++ * Mark the end of PATH TOV handling. All pending IOs are already cleaned up. ++ */ ++void ++bfa_cb_itnim_tov(void *cb_arg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; ++ ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_fcb_itnim_tov(itnim->itnim_drv); ++} ++ ++/** ++ * BFA notification to FCS/driver for second level error recovery. ++ * ++ * Atleast one I/O request has timedout and target is unresponsive to ++ * repeated abort requests. Second level error recovery should be initiated ++ * by starting implicit logout and recovery procedures. ++ */ ++void ++bfa_cb_itnim_sler(void *cb_arg) ++{ ++ struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg; ++ ++ itnim->stats.sler++; ++ bfa_trc(itnim->fcs, itnim->rport->pwwn); ++ bfa_fcs_rport_logo_imp(itnim->rport); ++} ++ ++struct bfa_fcs_itnim_s * ++bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ rport = bfa_fcs_rport_lookup(port, rpwwn); ++ ++ if (!rport) ++ return NULL; ++ ++ bfa_assert(rport->itnim != NULL); ++ return (rport->itnim); ++} ++ ++bfa_status_t ++bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn, ++ struct bfa_itnim_attr_s *attr) ++{ ++ struct bfa_fcs_itnim_s *itnim = NULL; ++ ++ itnim = bfa_fcs_itnim_lookup(port, rpwwn); ++ ++ if (itnim == NULL) ++ return BFA_STATUS_NO_FCPIM_NEXUS; ++ ++ attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm); ++ attr->retry = itnim->seq_rec; ++ attr->rec_support = itnim->rec_support; ++ attr->conf_comp = itnim->conf_comp; ++ attr->task_retry_id = itnim->task_retry_id; ++ ++ return BFA_STATUS_OK; ++} ++ ++bfa_status_t ++bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn, ++ struct bfa_itnim_stats_s *stats) ++{ ++ struct bfa_fcs_itnim_s *itnim = NULL; ++ ++ bfa_assert(port != NULL); ++ ++ itnim = bfa_fcs_itnim_lookup(port, rpwwn); ++ ++ if (itnim == NULL) ++ return BFA_STATUS_NO_FCPIM_NEXUS; ++ ++ bfa_os_memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s)); ++ ++ return BFA_STATUS_OK; ++} ++ ++bfa_status_t ++bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port, wwn_t rpwwn) ++{ ++ struct bfa_fcs_itnim_s *itnim = NULL; ++ ++ bfa_assert(port != NULL); ++ ++ itnim = bfa_fcs_itnim_lookup(port, rpwwn); ++ ++ if (itnim == NULL) ++ return BFA_STATUS_NO_FCPIM_NEXUS; ++ ++ bfa_os_memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s)); ++ return BFA_STATUS_OK; ++} ++ ++void ++bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, ++ u16 len) ++{ ++ struct fc_els_cmd_s *els_cmd; ++ ++ bfa_trc(itnim->fcs, fchs->type); ++ ++ if (fchs->type != FC_TYPE_ELS) ++ return; ++ ++ els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ bfa_trc(itnim->fcs, els_cmd->els_code); ++ ++ switch (els_cmd->els_code) { ++ case FC_ELS_PRLO: ++ /* bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_PRLO); */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++void ++bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim) ++{ ++} ++ ++void ++bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim) ++{ ++} ++ ++/** ++ * Module initialization ++ */ ++void ++bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs) ++{ ++} ++ ++/** ++ * Module cleanup ++ */ ++void ++bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} ++ ++ +diff --git a/drivers/scsi/bfa/fcptm.c b/drivers/scsi/bfa/fcptm.c +new file mode 100644 +index 0000000..8c8b08c +--- /dev/null ++++ b/drivers/scsi/bfa/fcptm.c +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * This file contains dummy FCPTM routines to aid in Initiator Mode only ++ * compilation of OS driver. ++ * ++ */ ++ ++#include "bfa_os_inc.h" ++#include "fcs_rport.h" ++#include "fcs_fcptm.h" ++#include "fcs/bfa_fcs_rport.h" ++ ++struct bfa_fcs_tin_s * ++bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport) ++{ ++ return NULL; ++} ++ ++void ++bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin) ++{ ++} ++ ++void ++bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin) ++{ ++} ++ ++void ++bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin) ++{ ++} ++ ++void ++bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len) ++{ ++} ++ ++void ++bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len) ++{ ++} ++ ++void ++bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin) ++{ ++} ++ ++void ++bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin) ++{ ++} +diff --git a/drivers/scsi/bfa/fcs.h b/drivers/scsi/bfa/fcs.h +new file mode 100644 +index 0000000..deee685 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs.h FCS module functions ++ */ ++ ++ ++#ifndef __FCS_H__ ++#define __FCS_H__ ++ ++#define __fcs_min_cfg(__fcs) (__fcs)->min_cfg ++ ++void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs); ++ ++#endif /* __FCS_H__ */ +diff --git a/drivers/scsi/bfa/fcs_auth.h b/drivers/scsi/bfa/fcs_auth.h +new file mode 100644 +index 0000000..65d155f +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_auth.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_uf.h FCS unsolicited frame receive ++ */ ++ ++ ++#ifndef __FCS_AUTH_H__ ++#define __FCS_AUTH_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * fcs friend functions: only between fcs modules ++ */ ++void bfa_fcs_auth_uf_recv(struct bfa_fcs_fabric_s *fabric, int len); ++void bfa_fcs_auth_start(struct bfa_fcs_fabric_s *fabric); ++void bfa_fcs_auth_stop(struct bfa_fcs_fabric_s *fabric); ++ ++#endif /* __FCS_UF_H__ */ +diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h +new file mode 100644 +index 0000000..eee9608 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_fabric.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_lport.h FCS logical port interfaces ++ */ ++ ++#ifndef __FCS_FABRIC_H__ ++#define __FCS_FABRIC_H__ ++ ++#include ++#include ++#include ++ ++/* ++* fcs friend functions: only between fcs modules ++ */ ++void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs); ++void bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric); ++void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric); ++void bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric, ++ struct bfa_fcs_vport_s *vport); ++void bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric, ++ struct bfa_fcs_vport_s *vport); ++int bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric); ++struct bfa_fcs_vport_s *bfa_fcs_fabric_vport_lookup( ++ struct bfa_fcs_fabric_s *fabric, wwn_t pwwn); ++void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs); ++void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, ++ struct fchs_s *fchs, u16 len); ++u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric); ++bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric); ++enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric); ++void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric); ++void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric); ++ ++bfa_status_t bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, ++ struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg, ++ struct bfad_vf_s *vf_drv); ++void bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, ++ enum auth_status status); ++ ++void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric, ++ wwn_t fabric_name); ++#endif /* __FCS_FABRIC_H__ */ +diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h +new file mode 100644 +index 0000000..61e9e26 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_fcpim.h +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __FCS_FCPIM_H__ ++#define __FCS_FCPIM_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * Following routines are from FCPIM and will be called by rport. ++ */ ++struct bfa_fcs_itnim_s *bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim); ++void bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim); ++void bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim); ++bfa_status_t bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim); ++ ++void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); ++void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim); ++void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim); ++ ++/* ++ * Modudle init/cleanup routines. ++ */ ++void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs, ++ u16 len); ++#endif /* __FCS_FCPIM_H__ */ +diff --git a/drivers/scsi/bfa/fcs_fcptm.h b/drivers/scsi/bfa/fcs_fcptm.h +new file mode 100644 +index 0000000..ffff082 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_fcptm.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FCS_FCPTM_H__ ++#define __FCS_FCPTM_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * Following routines are from FCPTM and will be called by rport. ++ */ ++struct bfa_fcs_tin_s *bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin); ++void bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin); ++void bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin); ++void bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, ++ u16 len); ++void bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin); ++void bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin); ++ ++/* ++ * Modudle init/cleanup routines. ++ */ ++void bfa_fcs_fcptm_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fcptm_modexit(struct bfa_fcs_s *fcs); ++void bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, ++ u16 len); ++ ++#endif /* __FCS_FCPTM_H__ */ +diff --git a/drivers/scsi/bfa/fcs_fcxp.h b/drivers/scsi/bfa/fcs_fcxp.h +new file mode 100644 +index 0000000..8277fe9 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_fcxp.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_fcxp.h FCXP helper macros for FCS ++ */ ++ ++ ++#ifndef __FCS_FCXP_H__ ++#define __FCS_FCXP_H__ ++ ++#define bfa_fcs_fcxp_alloc(__fcs) \ ++ bfa_fcxp_alloc(NULL, (__fcs)->bfa, 0, 0, NULL, NULL, NULL, NULL) ++ ++#endif /* __FCS_FCXP_H__ */ +diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h +new file mode 100644 +index 0000000..ae744ba +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_lport.h +@@ -0,0 +1,117 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_lport.h FCS logical port interfaces ++ */ ++ ++#ifndef __FCS_LPORT_H__ ++#define __FCS_LPORT_H__ ++ ++#define __VPORT_H__ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * PID used in P2P/N2N ( In Big Endian) ++ */ ++#define N2N_LOCAL_PID 0x010000 ++#define N2N_REMOTE_PID 0x020000 ++ ++/* ++ * Misc Timeouts ++ */ ++/* ++ * To be used when spawning a timer before retrying a failed command. Milli ++ * Secs. ++ */ ++#define BFA_FCS_RETRY_TIMEOUT 2000 ++ ++/* ++ * Check for Port/Vport Mode/Role ++ */ ++#define BFA_FCS_VPORT_IS_INITIATOR_MODE(port) \ ++ (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IM) ++ ++#define BFA_FCS_VPORT_IS_TARGET_MODE(port) \ ++ (port->port_cfg.roles & BFA_PORT_ROLE_FCP_TM) ++ ++#define BFA_FCS_VPORT_IS_IPFC_MODE(port) \ ++ (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IPFC) ++ ++/* ++ * Is this a Well Known Address ++ */ ++#define BFA_FCS_PID_IS_WKA(pid) ((bfa_os_ntoh3b(pid) > 0xFFF000) ? 1 : 0) ++ ++/* ++ * Pointer to elements within Port ++ */ ++#define BFA_FCS_GET_HAL_FROM_PORT(port) (port->fcs->bfa) ++#define BFA_FCS_GET_NS_FROM_PORT(port) (&port->port_topo.pfab.ns) ++#define BFA_FCS_GET_SCN_FROM_PORT(port) (&port->port_topo.pfab.scn) ++#define BFA_FCS_GET_MS_FROM_PORT(port) (&port->port_topo.pfab.ms) ++#define BFA_FCS_GET_FDMI_FROM_PORT(port) (&port->port_topo.pfab.ms.fdmi) ++ ++/* ++ * handler for unsolicied frames ++ */ ++void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs, ++ u16 len); ++ ++/* ++ * Following routines will be called by Fabric to indicate port ++ * online/offline to vport. ++ */ ++void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs, ++ u16 vf_id, struct bfa_port_cfg_s *port_cfg, ++ struct bfa_fcs_vport_s *vport); ++void bfa_fcs_port_online(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_offline(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_delete(struct bfa_fcs_port_s *port); ++bfa_boolean_t bfa_fcs_port_is_online(struct bfa_fcs_port_s *port); ++ ++/* ++ * Lookup rport based on PID ++ */ ++struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pid( ++ struct bfa_fcs_port_s *port, u32 pid); ++ ++/* ++ * Lookup rport based on PWWN ++ */ ++struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pwwn( ++ struct bfa_fcs_port_s *port, wwn_t pwwn); ++struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_nwwn( ++ struct bfa_fcs_port_s *port, wwn_t nwwn); ++void bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port, ++ struct bfa_fcs_rport_s *rport); ++void bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port, ++ struct bfa_fcs_rport_s *rport); ++ ++void bfa_fcs_port_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_port_modexit(struct bfa_fcs_s *fcs); ++void bfa_fcs_port_lip(struct bfa_fcs_port_s *port); ++ ++#endif /* __FCS_LPORT_H__ */ +diff --git a/drivers/scsi/bfa/fcs_ms.h b/drivers/scsi/bfa/fcs_ms.h +new file mode 100644 +index 0000000..b6a8c12 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_ms.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_ms.h FCS ms interfaces ++ */ ++#ifndef __FCS_MS_H__ ++#define __FCS_MS_H__ ++ ++/* MS FCS routines */ ++void bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port); ++ ++/* FDMI FCS routines */ ++void bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms); ++void bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms); ++void bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms); ++ ++#endif +diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h +new file mode 100644 +index 0000000..abb6519 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_port.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_pport.h FCS physical port interfaces ++ */ ++ ++ ++#ifndef __FCS_PPORT_H__ ++#define __FCS_PPORT_H__ ++ ++/* ++ * fcs friend functions: only between fcs modules ++ */ ++void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs); ++ ++#endif /* __FCS_PPORT_H__ */ +diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h +new file mode 100644 +index 0000000..f601e9d +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_rport.h +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_rport.h FCS rport interfaces and defines ++ */ ++ ++#ifndef __FCS_RPORT_H__ ++#define __FCS_RPORT_H__ ++ ++#include ++ ++void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs); ++ ++void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, ++ u16 len); ++void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); ++ ++struct bfa_fcs_rport_s *bfa_fcs_rport_create(struct bfa_fcs_port_s *port, ++ u32 pid); ++void bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs, ++ struct fc_logi_s *plogi_rsp); ++void bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs, ++ struct fc_logi_s *plogi); ++void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, ++ struct fc_logi_s *plogi); ++void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_fcptm_offline_done(struct bfa_fcs_rport_s *rport); ++int bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport); ++struct bfa_fcs_rport_s *bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port, ++ wwn_t wwn); ++ ++ ++/* Rport Features */ ++void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport); ++ ++#endif /* __FCS_RPORT_H__ */ +diff --git a/drivers/scsi/bfa/fcs_trcmod.h b/drivers/scsi/bfa/fcs_trcmod.h +new file mode 100644 +index 0000000..41b5ae8 +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_trcmod.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_trcmod.h BFA FCS trace modules ++ */ ++ ++#ifndef __FCS_TRCMOD_H__ ++#define __FCS_TRCMOD_H__ ++ ++#include ++ ++/* ++ * !!! Only append to the enums defined here to avoid any versioning ++ * !!! needed between trace utility and driver version ++ */ ++enum { ++ BFA_TRC_FCS_FABRIC = 1, ++ BFA_TRC_FCS_VFAPI = 2, ++ BFA_TRC_FCS_PORT = 3, ++ BFA_TRC_FCS_VPORT = 4, ++ BFA_TRC_FCS_VP_API = 5, ++ BFA_TRC_FCS_VPS = 6, ++ BFA_TRC_FCS_RPORT = 7, ++ BFA_TRC_FCS_FCPIM = 8, ++ BFA_TRC_FCS_FCPTM = 9, ++ BFA_TRC_FCS_NS = 10, ++ BFA_TRC_FCS_SCN = 11, ++ BFA_TRC_FCS_LOOP = 12, ++ BFA_TRC_FCS_UF = 13, ++ BFA_TRC_FCS_PPORT = 14, ++ BFA_TRC_FCS_FCPIP = 15, ++ BFA_TRC_FCS_PORT_API = 16, ++ BFA_TRC_FCS_RPORT_API = 17, ++ BFA_TRC_FCS_AUTH = 18, ++ BFA_TRC_FCS_N2N = 19, ++ BFA_TRC_FCS_MS = 20, ++ BFA_TRC_FCS_FDMI = 21, ++ BFA_TRC_FCS_RPORT_FTRS = 22, ++}; ++ ++#endif /* __FCS_TRCMOD_H__ */ +diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h +new file mode 100644 +index 0000000..96f1bdc +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_uf.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * fcs_uf.h FCS unsolicited frame receive ++ */ ++ ++ ++#ifndef __FCS_UF_H__ ++#define __FCS_UF_H__ ++ ++/* ++ * fcs friend functions: only between fcs modules ++ */ ++void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs); ++ ++#endif /* __FCS_UF_H__ */ +diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h +new file mode 100644 +index 0000000..9e80b6a +--- /dev/null ++++ b/drivers/scsi/bfa/fcs_vport.h +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FCS_VPORT_H__ ++#define __FCS_VPORT_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * Modudle init/cleanup routines. ++ */ ++ ++void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs); ++void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs); ++ ++void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport); ++void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport); ++void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport); ++void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport); ++u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs); ++ ++#endif /* __FCS_VPORT_H__ */ ++ +diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c +new file mode 100644 +index 0000000..b845eb2 +--- /dev/null ++++ b/drivers/scsi/bfa/fdmi.c +@@ -0,0 +1,1223 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * port_api.c BFA FCS port ++ */ ++ ++ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "lport_priv.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include ++ ++BFA_TRC_FILE(FCS, FDMI); ++ ++#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2 ++ ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_fdmi_timeout(void *arg); ++static u16 bfa_fcs_port_fdmi_build_rhba_pyld( ++ struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); ++static u16 bfa_fcs_port_fdmi_build_rprt_pyld( ++ struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); ++static u16 bfa_fcs_port_fdmi_build_rpa_pyld( ++ struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); ++static u16 bfa_fcs_port_fdmi_build_portattr_block( ++ struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld); ++void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, ++ struct bfa_fcs_fdmi_hba_attr_s *hba_attr); ++void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, ++ struct bfa_fcs_fdmi_port_attr_s *port_attr); ++/** ++ * fcs_fdmi_sm FCS FDMI state machine ++ */ ++ ++/** ++ * FDMI State Machine events ++ */ ++enum port_fdmi_event { ++ FDMISM_EVENT_PORT_ONLINE = 1, ++ FDMISM_EVENT_PORT_OFFLINE = 2, ++ FDMISM_EVENT_RSP_OK = 4, ++ FDMISM_EVENT_RSP_ERROR = 5, ++ FDMISM_EVENT_TIMEOUT = 6, ++ FDMISM_EVENT_RHBA_SENT = 7, ++ FDMISM_EVENT_RPRT_SENT = 8, ++ FDMISM_EVENT_RPA_SENT = 9, ++}; ++ ++static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event); ++/** ++ * Start in offline state - awaiting MS to send start. ++ */ ++static void ++bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ fdmi->retry_cnt = 0; ++ ++ switch (event) { ++ case FDMISM_EVENT_PORT_ONLINE: ++ if (port->vport) { ++ /* ++ * For Vports, register a new port. ++ */ ++ bfa_sm_set_state(fdmi, ++ bfa_fcs_port_fdmi_sm_sending_rprt); ++ bfa_fcs_port_fdmi_send_rprt(fdmi, NULL); ++ } else { ++ /* ++ * For a base port, we should first register the HBA ++ * atribute. The HBA attribute also contains the base ++ * port registration. ++ */ ++ bfa_sm_set_state(fdmi, ++ bfa_fcs_port_fdmi_sm_sending_rhba); ++ bfa_fcs_port_fdmi_send_rhba(fdmi, NULL); ++ } ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RHBA_SENT: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RSP_ERROR: ++ /* ++ * if max retries have not been reached, start timer for a ++ * delayed retry ++ */ ++ if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->timer, bfa_fcs_port_fdmi_timeout, ++ fdmi, BFA_FCS_RETRY_TIMEOUT); ++ } else { ++ /* ++ * set state to offline ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ } ++ break; ++ ++ case FDMISM_EVENT_RSP_OK: ++ /* ++ * Initiate Register Port Attributes ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa); ++ fdmi->retry_cnt = 0; ++ bfa_fcs_port_fdmi_send_rpa(fdmi, NULL); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_fcxp_discard(fdmi->fcxp); ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba); ++ bfa_fcs_port_fdmi_send_rhba(fdmi, NULL); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_timer_stop(&fdmi->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/* ++* RPRT : Register Port ++ */ ++static void ++bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RPRT_SENT: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RSP_ERROR: ++ /* ++ * if max retries have not been reached, start timer for a ++ * delayed retry ++ */ ++ if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->timer, bfa_fcs_port_fdmi_timeout, ++ fdmi, BFA_FCS_RETRY_TIMEOUT); ++ ++ } else { ++ /* ++ * set state to offline ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ fdmi->retry_cnt = 0; ++ } ++ break; ++ ++ case FDMISM_EVENT_RSP_OK: ++ fdmi->retry_cnt = 0; ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_fcxp_discard(fdmi->fcxp); ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt); ++ bfa_fcs_port_fdmi_send_rprt(fdmi, NULL); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_timer_stop(&fdmi->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/* ++ * Register Port Attributes ++ */ ++static void ++bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RPA_SENT: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_RSP_ERROR: ++ /* ++ * if max retries have not been reached, start timer for a ++ * delayed retry ++ */ ++ if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) { ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port), ++ &fdmi->timer, bfa_fcs_port_fdmi_timeout, ++ fdmi, BFA_FCS_RETRY_TIMEOUT); ++ } else { ++ /* ++ * set state to offline ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ fdmi->retry_cnt = 0; ++ } ++ break; ++ ++ case FDMISM_EVENT_RSP_OK: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online); ++ fdmi->retry_cnt = 0; ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_fcxp_discard(fdmi->fcxp); ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa); ++ bfa_fcs_port_fdmi_send_rpa(fdmi, NULL); ++ break; ++ ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ bfa_timer_stop(&fdmi->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi, ++ enum port_fdmi_event event) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ bfa_trc(port->fcs, event); ++ ++ switch (event) { ++ case FDMISM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++/** ++* RHBA : Register HBA Attributes. ++ */ ++static void ++bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct fchs_s fchs; ++ int len, attr_len; ++ struct bfa_fcxp_s *fcxp; ++ u8 *pyld; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, ++ bfa_fcs_port_fdmi_send_rhba, fdmi); ++ return; ++ } ++ fdmi->fcxp = fcxp; ++ ++ pyld = bfa_fcxp_get_reqbuf(fcxp); ++ bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); ++ ++ len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), ++ FDMI_RHBA); ++ ++ attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi, ++ (u8 *) ((struct ct_hdr_s *) pyld + 1)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, (len + attr_len), &fchs, ++ bfa_fcs_port_fdmi_rhba_response, (void *)fdmi, ++ FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); ++} ++ ++static u16 ++bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi, ++ u8 *pyld) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct bfa_fcs_fdmi_hba_attr_s hba_attr; /* @todo */ ++ struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; /* @todo */ ++ struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; ++ struct fdmi_attr_s *attr; ++ u8 *curr_ptr; ++ u16 len, count; ++ ++ /* ++ * get hba attributes ++ */ ++ bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr); ++ ++ rhba->hba_id = bfa_fcs_port_get_pwwn(port); ++ rhba->port_list.num_ports = bfa_os_htonl(1); ++ rhba->port_list.port_entry = bfa_fcs_port_get_pwwn(port); ++ ++ len = sizeof(rhba->hba_id) + sizeof(rhba->port_list); ++ ++ count = 0; ++ len += sizeof(rhba->hba_attr_blk.attr_count); ++ ++ /* ++ * fill out the invididual entries of the HBA attrib Block ++ */ ++ curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr; ++ ++ /* ++ * Node Name ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME); ++ attr->len = sizeof(wwn_t); ++ memcpy(attr->value, &bfa_fcs_port_get_nwwn(port), attr->len); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Manufacturer ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER); ++ attr->len = (u16) strlen(fcs_hba_attr->manufacturer); ++ memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Serial Number ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM); ++ attr->len = (u16) strlen(fcs_hba_attr->serial_num); ++ memcpy(attr->value, fcs_hba_attr->serial_num, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Model ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL); ++ attr->len = (u16) strlen(fcs_hba_attr->model); ++ memcpy(attr->value, fcs_hba_attr->model, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Model Desc ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC); ++ attr->len = (u16) strlen(fcs_hba_attr->model_desc); ++ memcpy(attr->value, fcs_hba_attr->model_desc, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * H/W Version ++ */ ++ if (fcs_hba_attr->hw_version[0] != '\0') { ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION); ++ attr->len = (u16) strlen(fcs_hba_attr->hw_version); ++ memcpy(attr->value, fcs_hba_attr->hw_version, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ } ++ ++ /* ++ * Driver Version ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION); ++ attr->len = (u16) strlen(fcs_hba_attr->driver_version); ++ memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len;; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Option Rom Version ++ */ ++ if (fcs_hba_attr->option_rom_ver[0] != '\0') { ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION); ++ attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver); ++ memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ } ++ ++ /* ++ * f/w Version = driver version ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION); ++ attr->len = (u16) strlen(fcs_hba_attr->driver_version); ++ memcpy(attr->value, fcs_hba_attr->driver_version, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * OS Name ++ */ ++ if (fcs_hba_attr->os_name[0] != '\0') { ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME); ++ attr->len = (u16) strlen(fcs_hba_attr->os_name); ++ memcpy(attr->value, fcs_hba_attr->os_name, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ } ++ ++ /* ++ * MAX_CT_PAYLOAD ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT); ++ attr->len = sizeof(fcs_hba_attr->max_ct_pyld); ++ memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len); ++ len += attr->len; ++ count++; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Update size of payload ++ */ ++ len += ((sizeof(attr->type) + sizeof(attr->len)) * count); ++ ++ rhba->hba_attr_blk.attr_count = bfa_os_htonl(count); ++ return len; ++} ++ ++static void ++bfa_fcs_port_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); ++ return; ++ } ++ ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++} ++ ++/** ++* RPRT : Register Port ++ */ ++static void ++bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct fchs_s fchs; ++ u16 len, attr_len; ++ struct bfa_fcxp_s *fcxp; ++ u8 *pyld; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, ++ bfa_fcs_port_fdmi_send_rprt, fdmi); ++ return; ++ } ++ fdmi->fcxp = fcxp; ++ ++ pyld = bfa_fcxp_get_reqbuf(fcxp); ++ bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); ++ ++ len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), ++ FDMI_RPRT); ++ ++ attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi, ++ (u8 *) ((struct ct_hdr_s *) pyld + 1)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len + attr_len, &fchs, ++ bfa_fcs_port_fdmi_rprt_response, (void *)fdmi, ++ FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); ++} ++ ++/** ++ * This routine builds Port Attribute Block that used in RPA, RPRT commands. ++ */ ++static u16 ++bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi, ++ u8 *pyld) ++{ ++ struct bfa_fcs_fdmi_port_attr_s fcs_port_attr; ++ struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld; ++ struct fdmi_attr_s *attr; ++ u8 *curr_ptr; ++ u16 len; ++ u8 count = 0; ++ ++ /* ++ * get port attributes ++ */ ++ bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); ++ ++ len = sizeof(port_attrib->attr_count); ++ ++ /* ++ * fill out the invididual entries ++ */ ++ curr_ptr = (u8 *) &port_attrib->port_attr; ++ ++ /* ++ * FC4 Types ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES); ++ attr->len = sizeof(fcs_port_attr.supp_fc4_types); ++ memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * Supported Speed ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED); ++ attr->len = sizeof(fcs_port_attr.supp_speed); ++ memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * current Port Speed ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED); ++ attr->len = sizeof(fcs_port_attr.curr_speed); ++ memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * max frame size ++ */ ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE); ++ attr->len = sizeof(fcs_port_attr.max_frm_size); ++ memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ /* ++ * OS Device Name ++ */ ++ if (fcs_port_attr.os_device_name[0] != '\0') { ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME); ++ attr->len = (u16) strlen(fcs_port_attr.os_device_name); ++ memcpy(attr->value, fcs_port_attr.os_device_name, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ } ++ /* ++ * Host Name ++ */ ++ if (fcs_port_attr.host_name[0] != '\0') { ++ attr = (struct fdmi_attr_s *) curr_ptr; ++ attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME); ++ attr->len = (u16) strlen(fcs_port_attr.host_name); ++ memcpy(attr->value, fcs_port_attr.host_name, attr->len); ++ /* variable fields need to be 4 byte aligned */ ++ attr->len = fc_roundup(attr->len, sizeof(u32)); ++ curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len; ++ len += attr->len; ++ ++count; ++ attr->len = ++ bfa_os_htons(attr->len + sizeof(attr->type) + ++ sizeof(attr->len)); ++ ++ } ++ ++ /* ++ * Update size of payload ++ */ ++ port_attrib->attr_count = bfa_os_htonl(count); ++ len += ((sizeof(attr->type) + sizeof(attr->len)) * count); ++ return len; ++} ++ ++static u16 ++bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi, ++ u8 *pyld) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld; ++ u16 len; ++ ++ rprt->hba_id = bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs)); ++ rprt->port_name = bfa_fcs_port_get_pwwn(port); ++ ++ len = bfa_fcs_port_fdmi_build_portattr_block(fdmi, ++ (u8 *) &rprt->port_attr_blk); ++ ++ len += sizeof(rprt->hba_id) + sizeof(rprt->port_name); ++ ++ return len; ++} ++ ++static void ++bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); ++ return; ++ } ++ ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++} ++ ++/** ++* RPA : Register Port Attributes. ++ */ ++static void ++bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct fchs_s fchs; ++ u16 len, attr_len; ++ struct bfa_fcxp_s *fcxp; ++ u8 *pyld; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, ++ bfa_fcs_port_fdmi_send_rpa, fdmi); ++ return; ++ } ++ fdmi->fcxp = fcxp; ++ ++ pyld = bfa_fcxp_get_reqbuf(fcxp); ++ bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); ++ ++ len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), ++ FDMI_RPA); ++ ++ attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi, ++ (u8 *) ((struct ct_hdr_s *) pyld + 1)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len + attr_len, &fchs, ++ bfa_fcs_port_fdmi_rpa_response, (void *)fdmi, ++ FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT); ++} ++ ++static u16 ++bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi, ++ u8 *pyld) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld; ++ u16 len; ++ ++ rpa->port_name = bfa_fcs_port_get_pwwn(port); ++ ++ len = bfa_fcs_port_fdmi_build_portattr_block(fdmi, ++ (u8 *) &rpa->port_attr_blk); ++ ++ len += sizeof(rpa->port_name); ++ ++ return len; ++} ++ ++static void ++bfa_fcs_port_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); ++ return; ++ } ++ ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); ++} ++ ++static void ++bfa_fcs_port_fdmi_timeout(void *arg) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg; ++ ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT); ++} ++ ++void ++bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi, ++ struct bfa_fcs_fdmi_hba_attr_s *hba_attr) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; ++ struct bfa_adapter_attr_s adapter_attr; ++ ++ bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s)); ++ bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s)); ++ ++ bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr); ++ ++ strncpy(hba_attr->manufacturer, adapter_attr.manufacturer, ++ sizeof(adapter_attr.manufacturer)); ++ ++ strncpy(hba_attr->serial_num, adapter_attr.serial_num, ++ sizeof(adapter_attr.serial_num)); ++ ++ strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model)); ++ ++ strncpy(hba_attr->model_desc, adapter_attr.model_descr, ++ sizeof(hba_attr->model_desc)); ++ ++ strncpy(hba_attr->hw_version, adapter_attr.hw_ver, ++ sizeof(hba_attr->hw_version)); ++ ++ strncpy(hba_attr->driver_version, (char *)driver_info->version, ++ sizeof(hba_attr->driver_version)); ++ ++ strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver, ++ sizeof(hba_attr->option_rom_ver)); ++ ++ strncpy(hba_attr->fw_version, adapter_attr.fw_ver, ++ sizeof(hba_attr->fw_version)); ++ ++ strncpy(hba_attr->os_name, driver_info->host_os_name, ++ sizeof(hba_attr->os_name)); ++ ++ /* ++ * If there is a patch level, append it to the os name along with a ++ * separator ++ */ ++ if (driver_info->host_os_patch[0] != '\0') { ++ strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, ++ sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); ++ strncat(hba_attr->os_name, driver_info->host_os_patch, ++ sizeof(driver_info->host_os_patch)); ++ } ++ ++ hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ); ++ ++} ++ ++void ++bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi, ++ struct bfa_fcs_fdmi_port_attr_s *port_attr) ++{ ++ struct bfa_fcs_port_s *port = fdmi->ms->port; ++ struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info; ++ struct bfa_pport_attr_s pport_attr; ++ ++ bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s)); ++ ++ /* ++ * get pport attributes from hal ++ */ ++ bfa_pport_get_attr(port->fcs->bfa, &pport_attr); ++ ++ /* ++ * get FC4 type Bitmask ++ */ ++ fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types); ++ ++ /* ++ * Supported Speeds ++ */ ++ port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS); ++ ++ /* ++ * Current Speed ++ */ ++ port_attr->curr_speed = bfa_os_htonl(pport_attr.speed); ++ ++ /* ++ * Max PDU Size. ++ */ ++ port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ); ++ ++ /* ++ * OS device Name ++ */ ++ strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, ++ sizeof(port_attr->os_device_name)); ++ ++ /* ++ * Host name ++ */ ++ strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, ++ sizeof(port_attr->host_name)); ++ ++} ++ ++ ++void ++bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; ++ ++ fdmi->ms = ms; ++ bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline); ++} ++ ++void ++bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; ++ ++ fdmi->ms = ms; ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE); ++} ++ ++void ++bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms) ++{ ++ struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi; ++ ++ fdmi->ms = ms; ++ bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE); ++} +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h +new file mode 100644 +index 0000000..da8cac0 +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen.h +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_AEN_H__ ++#define __BFA_AEN_H__ ++ ++#include "defs/bfa_defs_aen.h" ++ ++#define BFA_AEN_MAX_ENTRY 512 ++ ++extern s32 bfa_aen_max_cfg_entry; ++struct bfa_aen_s { ++ void *bfad; ++ s32 max_entry; ++ s32 write_index; ++ s32 read_index; ++ u32 bfad_num; ++ u32 seq_num; ++ void (*aen_cb_notify)(void *bfad); ++ void (*gettimeofday)(struct bfa_timeval_s *tv); ++ struct bfa_trc_mod_s *trcmod; ++ struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */ ++}; ++ ++ ++/** ++ * Public APIs ++ */ ++static inline void ++bfa_aen_set_max_cfg_entry(int max_entry) ++{ ++ bfa_aen_max_cfg_entry = max_entry; ++} ++ ++static inline s32 ++bfa_aen_get_max_cfg_entry(void) ++{ ++ return bfa_aen_max_cfg_entry; ++} ++ ++static inline s32 ++bfa_aen_get_meminfo(void) ++{ ++ return (sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry()); ++} ++ ++static inline s32 ++bfa_aen_get_wi(struct bfa_aen_s *aen) ++{ ++ return aen->write_index; ++} ++ ++static inline s32 ++bfa_aen_get_ri(struct bfa_aen_s *aen) ++{ ++ return aen->read_index; ++} ++ ++static inline s32 ++bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index) ++{ ++ return ((aen->write_index + aen->max_entry) - read_index) ++ % aen->max_entry; ++} ++ ++s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod, ++ void *bfad, u32 inst_id, void (*aen_cb_notify)(void *), ++ void (*gettimeofday)(struct bfa_timeval_s *)); ++ ++s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category, ++ int aen_type, union bfa_aen_data_u *aen_data); ++ ++s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry, ++ s32 entry_space, s32 rii, s32 *ri_arr, ++ s32 ri_arr_cnt); ++ ++s32 bfa_aen_get_inst(struct bfa_aen_s *aen); ++ ++#endif /* __BFA_AEN_H__ */ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h +new file mode 100644 +index 0000000..260d3ea +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_ADAPTER Module */ ++#ifndef __bfa_aen_adapter_h__ ++#define __bfa_aen_adapter_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_ADAPTER_ADD \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_ADD) ++#define BFA_AEN_ADAPTER_REMOVE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_REMOVE) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_audit.h b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h +new file mode 100644 +index 0000000..12cd7aa +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h +@@ -0,0 +1,31 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_AUDIT Module */ ++#ifndef __bfa_aen_audit_h__ ++#define __bfa_aen_audit_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_AUDIT_AUTH_ENABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_ENABLE) ++#define BFA_AEN_AUDIT_AUTH_DISABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_DISABLE) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h +new file mode 100644 +index 0000000..507d0b5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_ETHPORT Module */ ++#ifndef __bfa_aen_ethport_h__ ++#define __bfa_aen_ethport_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_ETHPORT_LINKUP \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKUP) ++#define BFA_AEN_ETHPORT_LINKDOWN \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKDOWN) ++#define BFA_AEN_ETHPORT_ENABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_ENABLE) ++#define BFA_AEN_ETHPORT_DISABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_DISABLE) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h +new file mode 100644 +index 0000000..71378b4 +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_IOC Module */ ++#ifndef __bfa_aen_ioc_h__ ++#define __bfa_aen_ioc_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_IOC_HBGOOD \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBGOOD) ++#define BFA_AEN_IOC_HBFAIL \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBFAIL) ++#define BFA_AEN_IOC_ENABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_ENABLE) ++#define BFA_AEN_IOC_DISABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_DISABLE) ++#define BFA_AEN_IOC_FWMISMATCH \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_FWMISMATCH) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h +new file mode 100644 +index 0000000..a7d8ddc +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_ITNIM Module */ ++#ifndef __bfa_aen_itnim_h__ ++#define __bfa_aen_itnim_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_ITNIM_ONLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_ONLINE) ++#define BFA_AEN_ITNIM_OFFLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_OFFLINE) ++#define BFA_AEN_ITNIM_DISCONNECT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_DISCONNECT) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_lport.h b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h +new file mode 100644 +index 0000000..5a8ebb6 +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_LPORT Module */ ++#ifndef __bfa_aen_lport_h__ ++#define __bfa_aen_lport_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_LPORT_NEW \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW) ++#define BFA_AEN_LPORT_DELETE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE) ++#define BFA_AEN_LPORT_ONLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_ONLINE) ++#define BFA_AEN_LPORT_OFFLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_OFFLINE) ++#define BFA_AEN_LPORT_DISCONNECT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DISCONNECT) ++#define BFA_AEN_LPORT_NEW_PROP \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_PROP) ++#define BFA_AEN_LPORT_DELETE_PROP \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_PROP) ++#define BFA_AEN_LPORT_NEW_STANDARD \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_STANDARD) ++#define BFA_AEN_LPORT_DELETE_STANDARD \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_STANDARD) ++#define BFA_AEN_LPORT_NPIV_DUP_WWN \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_DUP_WWN) ++#define BFA_AEN_LPORT_NPIV_FABRIC_MAX \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_FABRIC_MAX) ++#define BFA_AEN_LPORT_NPIV_UNKNOWN \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_UNKNOWN) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_port.h b/drivers/scsi/bfa/include/aen/bfa_aen_port.h +new file mode 100644 +index 0000000..9add905 +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_port.h +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_PORT Module */ ++#ifndef __bfa_aen_port_h__ ++#define __bfa_aen_port_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_PORT_ONLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ONLINE) ++#define BFA_AEN_PORT_OFFLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_OFFLINE) ++#define BFA_AEN_PORT_RLIR \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_RLIR) ++#define BFA_AEN_PORT_SFP_INSERT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_INSERT) ++#define BFA_AEN_PORT_SFP_REMOVE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_REMOVE) ++#define BFA_AEN_PORT_SFP_POM \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_POM) ++#define BFA_AEN_PORT_ENABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ENABLE) ++#define BFA_AEN_PORT_DISABLE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISABLE) ++#define BFA_AEN_PORT_AUTH_ON \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_ON) ++#define BFA_AEN_PORT_AUTH_OFF \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_OFF) ++#define BFA_AEN_PORT_DISCONNECT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISCONNECT) ++#define BFA_AEN_PORT_QOS_NEG \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_QOS_NEG) ++#define BFA_AEN_PORT_FABRIC_NAME_CHANGE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_FABRIC_NAME_CHANGE) ++#define BFA_AEN_PORT_SFP_ACCESS_ERROR \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_ACCESS_ERROR) ++#define BFA_AEN_PORT_SFP_UNSUPPORT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_UNSUPPORT) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_rport.h b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h +new file mode 100644 +index 0000000..7e4be1f +--- /dev/null ++++ b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for BFA_AEN_CAT_RPORT Module */ ++#ifndef __bfa_aen_rport_h__ ++#define __bfa_aen_rport_h__ ++ ++#include ++#include ++ ++#define BFA_AEN_RPORT_ONLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_ONLINE) ++#define BFA_AEN_RPORT_OFFLINE \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_OFFLINE) ++#define BFA_AEN_RPORT_DISCONNECT \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_DISCONNECT) ++#define BFA_AEN_RPORT_QOS_PRIO \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_PRIO) ++#define BFA_AEN_RPORT_QOS_FLOWID \ ++ BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_FLOWID) ++ ++#endif ++ +diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h +new file mode 100644 +index 0000000..64c1412 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfa.h +@@ -0,0 +1,177 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_H__ ++#define __BFA_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct bfa_s; ++#include ++ ++struct bfa_pcidev_s; ++ ++/** ++ * PCI devices supported by the current BFA ++ */ ++struct bfa_pciid_s { ++ u16 device_id; ++ u16 vendor_id; ++}; ++ ++extern char bfa_version[]; ++ ++/** ++ * BFA Power Mgmt Commands ++ */ ++enum bfa_pm_cmd { ++ BFA_PM_CTL_D0 = 0, ++ BFA_PM_CTL_D1 = 1, ++ BFA_PM_CTL_D2 = 2, ++ BFA_PM_CTL_D3 = 3, ++}; ++ ++/** ++ * BFA memory resources ++ */ ++enum bfa_mem_type { ++ BFA_MEM_TYPE_KVA = 1, /*! Kernel Virtual Memory *(non-dma-able) */ ++ BFA_MEM_TYPE_DMA = 2, /*! DMA-able memory */ ++ BFA_MEM_TYPE_MAX = BFA_MEM_TYPE_DMA, ++}; ++ ++struct bfa_mem_elem_s { ++ enum bfa_mem_type mem_type; /* see enum bfa_mem_type */ ++ u32 mem_len; /* Total Length in Bytes */ ++ u8 *kva; /* kernel virtual address */ ++ u64 dma; /* dma address if DMA memory */ ++ u8 *kva_curp; /* kva allocation cursor */ ++ u64 dma_curp; /* dma allocation cursor */ ++}; ++ ++struct bfa_meminfo_s { ++ struct bfa_mem_elem_s meminfo[BFA_MEM_TYPE_MAX]; ++}; ++#define bfa_meminfo_kva(_m) \ ++ (_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp ++#define bfa_meminfo_dma_virt(_m) \ ++ (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp ++#define bfa_meminfo_dma_phys(_m) \ ++ (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp ++ ++/** ++ * Generic Scatter Gather Element used by driver ++ */ ++struct bfa_sge_s { ++ u32 sg_len; ++ void *sg_addr; ++}; ++ ++#define bfa_sge_to_be(__sge) do { \ ++ ((u32 *)(__sge))[0] = bfa_os_htonl(((u32 *)(__sge))[0]); \ ++ ((u32 *)(__sge))[1] = bfa_os_htonl(((u32 *)(__sge))[1]); \ ++ ((u32 *)(__sge))[2] = bfa_os_htonl(((u32 *)(__sge))[2]); \ ++} while (0) ++ ++ ++/* ++ * bfa stats interfaces ++ */ ++#define bfa_stats(_mod, _stats) (_mod)->stats._stats ++ ++ ++#define bfa_ioc_get_stats(__bfa, __ioc_stats) \ ++ bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats) ++#define bfa_ioc_clear_stats(__bfa) \ ++ bfa_ioc_clr_stats(&(__bfa)->ioc) ++ ++/* ++ * bfa API functions ++ */ ++void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids); ++void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg); ++void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg); ++void bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo); ++void bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, ++ struct bfa_meminfo_s *meminfo, ++ struct bfa_pcidev_s *pcidev); ++void bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod); ++void bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod); ++void bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen); ++void bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog); ++void bfa_detach(struct bfa_s *bfa); ++void bfa_init(struct bfa_s *bfa); ++void bfa_start(struct bfa_s *bfa); ++void bfa_stop(struct bfa_s *bfa); ++void bfa_attach_fcs(struct bfa_s *bfa); ++void bfa_cb_init(void *bfad, bfa_status_t status); ++void bfa_cb_stop(void *bfad, bfa_status_t status); ++void bfa_cb_updateq(void *bfad, bfa_status_t status); ++ ++bfa_boolean_t bfa_intx(struct bfa_s *bfa); ++void bfa_isr_enable(struct bfa_s *bfa); ++void bfa_isr_disable(struct bfa_s *bfa); ++void bfa_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap, ++ u32 *num_vecs, u32 *max_vec_bit); ++#define bfa_msix(__bfa, __vec) (__bfa)->msix.handler[__vec](__bfa, __vec) ++ ++void bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q); ++void bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q); ++void bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q); ++ ++typedef void (*bfa_cb_ioc_t) (void *cbarg, enum bfa_status status); ++void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr); ++bfa_status_t bfa_iocfc_get_stats(struct bfa_s *bfa, ++ struct bfa_iocfc_stats_s *stats, ++ bfa_cb_ioc_t cbfn, void *cbarg); ++bfa_status_t bfa_iocfc_clear_stats(struct bfa_s *bfa, ++ bfa_cb_ioc_t cbfn, void *cbarg); ++void bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr); ++ ++void bfa_adapter_get_attr(struct bfa_s *bfa, ++ struct bfa_adapter_attr_s *ad_attr); ++u64 bfa_adapter_get_id(struct bfa_s *bfa); ++ ++bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa, ++ struct bfa_iocfc_intr_attr_s *attr); ++ ++void bfa_iocfc_enable(struct bfa_s *bfa); ++void bfa_iocfc_disable(struct bfa_s *bfa); ++void bfa_ioc_auto_recover(bfa_boolean_t auto_recover); ++void bfa_cb_ioc_disable(void *bfad); ++void bfa_timer_tick(struct bfa_s *bfa); ++#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \ ++ bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout) ++ ++/* ++ * BFA debug API functions ++ */ ++bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen); ++bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen); ++ ++#include "bfa_priv.h" ++ ++#endif /* __BFA_H__ */ +diff --git a/drivers/scsi/bfa/include/bfa_fcpim.h b/drivers/scsi/bfa/include/bfa_fcpim.h +new file mode 100644 +index 0000000..0478979 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfa_fcpim.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCPIM_H__ ++#define __BFA_FCPIM_H__ ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * forward declarations ++ */ ++struct bfa_itnim_s; ++struct bfa_ioim_s; ++struct bfa_tskim_s; ++struct bfad_ioim_s; ++struct bfad_tskim_s; ++ ++/* ++ * bfa fcpim module API functions ++ */ ++void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov); ++u16 bfa_fcpim_path_tov_get(struct bfa_s *bfa); ++void bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth); ++u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa); ++bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa, ++ struct bfa_fcpim_stats_s *modstats); ++bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa); ++ ++/* ++ * bfa itnim API functions ++ */ ++struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa, ++ struct bfa_rport_s *rport, void *itnim); ++void bfa_itnim_delete(struct bfa_itnim_s *itnim); ++void bfa_itnim_online(struct bfa_itnim_s *itnim, ++ bfa_boolean_t seq_rec); ++void bfa_itnim_offline(struct bfa_itnim_s *itnim); ++void bfa_itnim_get_stats(struct bfa_itnim_s *itnim, ++ struct bfa_itnim_hal_stats_s *stats); ++void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim); ++ ++ ++/** ++ * BFA completion callback for bfa_itnim_online(). ++ * ++ * @param[in] itnim FCS or driver itnim instance ++ * ++ * return None ++ */ ++void bfa_cb_itnim_online(void *itnim); ++ ++/** ++ * BFA completion callback for bfa_itnim_offline(). ++ * ++ * @param[in] itnim FCS or driver itnim instance ++ * ++ * return None ++ */ ++void bfa_cb_itnim_offline(void *itnim); ++void bfa_cb_itnim_tov_begin(void *itnim); ++void bfa_cb_itnim_tov(void *itnim); ++ ++/** ++ * BFA notification to FCS/driver for second level error recovery. ++ * ++ * Atleast one I/O request has timedout and target is unresponsive to ++ * repeated abort requests. Second level error recovery should be initiated ++ * by starting implicit logout and recovery procedures. ++ * ++ * @param[in] itnim FCS or driver itnim instance ++ * ++ * return None ++ */ ++void bfa_cb_itnim_sler(void *itnim); ++ ++/* ++ * bfa ioim API functions ++ */ ++struct bfa_ioim_s *bfa_ioim_alloc(struct bfa_s *bfa, ++ struct bfad_ioim_s *dio, ++ struct bfa_itnim_s *itnim, ++ u16 nsgles); ++ ++void bfa_ioim_free(struct bfa_ioim_s *ioim); ++void bfa_ioim_start(struct bfa_ioim_s *ioim); ++void bfa_ioim_abort(struct bfa_ioim_s *ioim); ++void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, ++ bfa_boolean_t iotov); ++ ++ ++/** ++ * I/O completion notification. ++ * ++ * @param[in] dio driver IO structure ++ * @param[in] io_status IO completion status ++ * @param[in] scsi_status SCSI status returned by target ++ * @param[in] sns_len SCSI sense length, 0 if none ++ * @param[in] sns_info SCSI sense data, if any ++ * @param[in] residue Residual length ++ * ++ * @return None ++ */ ++void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio, ++ enum bfi_ioim_status io_status, ++ u8 scsi_status, int sns_len, ++ u8 *sns_info, s32 residue); ++ ++/** ++ * I/O good completion notification. ++ * ++ * @param[in] dio driver IO structure ++ * ++ * @return None ++ */ ++void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio); ++ ++/** ++ * I/O abort completion notification ++ * ++ * @param[in] dio driver IO that was aborted ++ * ++ * @return None ++ */ ++void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio); ++void bfa_cb_ioim_resfree(void *hcb_bfad); ++ ++void bfa_cb_ioim_resfree(void *hcb_bfad); ++ ++/* ++ * bfa tskim API functions ++ */ ++struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa, ++ struct bfad_tskim_s *dtsk); ++void bfa_tskim_free(struct bfa_tskim_s *tskim); ++void bfa_tskim_start(struct bfa_tskim_s *tskim, ++ struct bfa_itnim_s *itnim, lun_t lun, ++ enum fcp_tm_cmnd tm, u8 t_secs); ++void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk, ++ enum bfi_tskim_status tsk_status); ++ ++#endif /* __BFA_FCPIM_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfa_fcptm.h b/drivers/scsi/bfa/include/bfa_fcptm.h +new file mode 100644 +index 0000000..5f5ffe0 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfa_fcptm.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCPTM_H__ ++#define __BFA_FCPTM_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * forward declarations ++ */ ++struct bfa_tin_s; ++struct bfa_iotm_s; ++struct bfa_tsktm_s; ++ ++/* ++ * bfa fcptm module API functions ++ */ ++void bfa_fcptm_path_tov_set(struct bfa_s *bfa, u16 path_tov); ++u16 bfa_fcptm_path_tov_get(struct bfa_s *bfa); ++void bfa_fcptm_qdepth_set(struct bfa_s *bfa, u16 q_depth); ++u16 bfa_fcptm_qdepth_get(struct bfa_s *bfa); ++ ++/* ++ * bfa tin API functions ++ */ ++void bfa_tin_get_stats(struct bfa_tin_s *tin, struct bfa_tin_stats_s *stats); ++void bfa_tin_clear_stats(struct bfa_tin_s *tin); ++ ++#endif /* __BFA_FCPTM_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h +new file mode 100644 +index 0000000..0c80b74 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfa_svc.h +@@ -0,0 +1,324 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_SVC_H__ ++#define __BFA_SVC_H__ ++ ++/* ++ * forward declarations ++ */ ++struct bfa_fcxp_s; ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * BFA rport information. ++ */ ++struct bfa_rport_info_s { ++ u16 max_frmsz; /* max rcv pdu size */ ++ u32 pid : 24, /* remote port ID */ ++ lp_tag : 8; ++ u32 local_pid : 24, /* local port ID */ ++ cisc : 8; /* CIRO supported */ ++ u8 fc_class; /* supported FC classes. enum fc_cos */ ++ u8 vf_en; /* virtual fabric enable */ ++ u16 vf_id; /* virtual fabric ID */ ++ enum bfa_pport_speed speed; /* Rport's current speed */ ++}; ++ ++/** ++ * BFA rport data structure ++ */ ++struct bfa_rport_s { ++ struct list_head qe; /* queue element */ ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_s *bfa; /* backpointer to BFA */ ++ void *rport_drv; /* fcs/driver rport object */ ++ u16 fw_handle; /* firmware rport handle */ ++ u16 rport_tag; /* BFA rport tag */ ++ struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */ ++ struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */ ++ struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */ ++ struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */ ++ struct bfa_rport_qos_attr_s qos_attr; ++ union a { ++ bfa_status_t status; /* f/w status */ ++ void *fw_msg; /* QoS scn event */ ++ } event_arg; ++}; ++#define BFA_RPORT_FC_COS(_rport) ((_rport)->rport_info.fc_class) ++ ++/** ++ * Send completion callback. ++ */ ++typedef void (*bfa_cb_fcxp_send_t) (void *bfad_fcxp, struct bfa_fcxp_s *fcxp, ++ void *cbarg, enum bfa_status req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++/** ++ * BFA fcxp allocation (asynchronous) ++ */ ++typedef void (*bfa_fcxp_alloc_cbfn_t) (void *cbarg, struct bfa_fcxp_s *fcxp); ++ ++struct bfa_fcxp_wqe_s { ++ struct list_head qe; ++ bfa_fcxp_alloc_cbfn_t alloc_cbfn; ++ void *alloc_cbarg; ++}; ++ ++typedef u64 (*bfa_fcxp_get_sgaddr_t) (void *bfad_fcxp, int sgeid); ++typedef u32 (*bfa_fcxp_get_sglen_t) (void *bfad_fcxp, int sgeid); ++ ++#define BFA_UF_BUFSZ (2 * 1024 + 256) ++ ++/** ++ * @todo private ++ */ ++struct bfa_uf_buf_s { ++ u8 d[BFA_UF_BUFSZ]; ++}; ++ ++ ++struct bfa_uf_s { ++ struct list_head qe; /* queue element */ ++ struct bfa_s *bfa; /* bfa instance */ ++ u16 uf_tag; /* identifying tag f/w messages */ ++ u16 vf_id; ++ u16 src_rport_handle; ++ u16 rsvd; ++ u8 *data_ptr; ++ u16 data_len; /* actual receive length */ ++ u16 pb_len; /* posted buffer length */ ++ void *buf_kva; /* buffer virtual address */ ++ u64 buf_pa; /* buffer physical address */ ++ struct bfa_cb_qe_s hcb_qe; /* comp: BFA comp qelem */ ++ struct bfa_sge_s sges[BFI_SGE_INLINE_MAX]; ++}; ++ ++typedef void (*bfa_cb_pport_t) (void *cbarg, enum bfa_status status); ++ ++/** ++ * bfa lport login/logout service interface ++ */ ++struct bfa_lps_s { ++ struct list_head qe; /* queue element */ ++ struct bfa_s *bfa; /* parent bfa instance */ ++ bfa_sm_t sm; /* finite state machine */ ++ u8 lp_tag; /* lport tag */ ++ u8 reqq; /* lport request queue */ ++ u8 alpa; /* ALPA for loop topologies */ ++ u32 lp_pid; /* lport port ID */ ++ bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/ ++ bfa_boolean_t auth_en; /* enable authentication */ ++ bfa_boolean_t auth_req; /* authentication required */ ++ bfa_boolean_t npiv_en; /* NPIV is allowed by peer */ ++ bfa_boolean_t fport; /* attached peer is F_PORT */ ++ bfa_boolean_t brcd_switch;/* attached peer is brcd switch */ ++ bfa_status_t status; /* login status */ ++ u16 pdusz; /* max receive PDU size */ ++ u16 pr_bbcred; /* BB_CREDIT from peer */ ++ u8 lsrjt_rsn; /* LSRJT reason */ ++ u8 lsrjt_expl; /* LSRJT explanation */ ++ wwn_t pwwn; /* port wwn of lport */ ++ wwn_t nwwn; /* node wwn of lport */ ++ wwn_t pr_pwwn; /* port wwn of lport peer */ ++ wwn_t pr_nwwn; /* node wwn of lport peer */ ++ mac_t lp_mac; /* fpma/spma MAC for lport */ ++ mac_t fcf_mac; /* FCF MAC of lport */ ++ struct bfa_reqq_wait_s wqe; /* request wait queue element */ ++ void *uarg; /* user callback arg */ ++ struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */ ++ struct bfi_lps_login_rsp_s *loginrsp; ++ bfa_eproto_status_t ext_status; ++}; ++ ++/* ++ * bfa pport API functions ++ */ ++bfa_status_t bfa_pport_enable(struct bfa_s *bfa); ++bfa_status_t bfa_pport_disable(struct bfa_s *bfa); ++bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa, ++ enum bfa_pport_speed speed); ++enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa); ++bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa, ++ enum bfa_pport_topology topo); ++enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa); ++bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa); ++bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa); ++u8 bfa_pport_get_myalpa(struct bfa_s *bfa); ++bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa); ++bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize); ++u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa); ++u32 bfa_pport_mypid(struct bfa_s *bfa); ++u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa); ++bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap); ++bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa); ++bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap); ++void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr); ++wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node); ++bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa, ++ union bfa_pport_stats_u *stats, ++ bfa_cb_pport_t cbfn, void *cbarg); ++bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, ++ void *cbarg); ++void bfa_pport_event_register(struct bfa_s *bfa, ++ void (*event_cbfn) (void *cbarg, ++ bfa_pport_event_t event), void *event_cbarg); ++bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa); ++void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off); ++void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off); ++bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, ++ enum bfa_pport_speed speed); ++enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa); ++ ++void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit); ++void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status); ++void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon, ++ bfa_boolean_t link_e2e_beacon); ++void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event); ++void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr); ++void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, ++ struct bfa_qos_vc_attr_s *qos_vc_attr); ++bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa, ++ union bfa_pport_stats_u *stats, ++ bfa_cb_pport_t cbfn, void *cbarg); ++bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, ++ void *cbarg); ++bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa); ++bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa); ++ ++/* ++ * bfa rport API functions ++ */ ++struct bfa_rport_s *bfa_rport_create(struct bfa_s *bfa, void *rport_drv); ++void bfa_rport_delete(struct bfa_rport_s *rport); ++void bfa_rport_online(struct bfa_rport_s *rport, ++ struct bfa_rport_info_s *rport_info); ++void bfa_rport_offline(struct bfa_rport_s *rport); ++void bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed); ++void bfa_rport_get_stats(struct bfa_rport_s *rport, ++ struct bfa_rport_hal_stats_s *stats); ++void bfa_rport_clear_stats(struct bfa_rport_s *rport); ++void bfa_cb_rport_online(void *rport); ++void bfa_cb_rport_offline(void *rport); ++void bfa_cb_rport_qos_scn_flowid(void *rport, ++ struct bfa_rport_qos_attr_s old_qos_attr, ++ struct bfa_rport_qos_attr_s new_qos_attr); ++void bfa_cb_rport_qos_scn_prio(void *rport, ++ struct bfa_rport_qos_attr_s old_qos_attr, ++ struct bfa_rport_qos_attr_s new_qos_attr); ++void bfa_rport_get_qos_attr(struct bfa_rport_s *rport, ++ struct bfa_rport_qos_attr_s *qos_attr); ++ ++/* ++ * bfa fcxp API functions ++ */ ++struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa, ++ int nreq_sgles, int nrsp_sgles, ++ bfa_fcxp_get_sgaddr_t get_req_sga, ++ bfa_fcxp_get_sglen_t get_req_sglen, ++ bfa_fcxp_get_sgaddr_t get_rsp_sga, ++ bfa_fcxp_get_sglen_t get_rsp_sglen); ++void bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe, ++ bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *cbarg); ++void bfa_fcxp_walloc_cancel(struct bfa_s *bfa, ++ struct bfa_fcxp_wqe_s *wqe); ++void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp); ++ ++void *bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp); ++void *bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp); ++ ++void bfa_fcxp_free(struct bfa_fcxp_s *fcxp); ++ ++void bfa_fcxp_send(struct bfa_fcxp_s *fcxp, ++ struct bfa_rport_s *rport, u16 vf_id, u8 lp_tag, ++ bfa_boolean_t cts, enum fc_cos cos, ++ u32 reqlen, struct fchs_s *fchs, ++ bfa_cb_fcxp_send_t cbfn, ++ void *cbarg, ++ u32 rsp_maxlen, u8 rsp_timeout); ++bfa_status_t bfa_fcxp_abort(struct bfa_fcxp_s *fcxp); ++u32 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp); ++u32 bfa_fcxp_get_maxrsp(struct bfa_s *bfa); ++ ++static inline void * ++bfa_uf_get_frmbuf(struct bfa_uf_s *uf) ++{ ++ return uf->data_ptr; ++} ++ ++static inline u16 ++bfa_uf_get_frmlen(struct bfa_uf_s *uf) ++{ ++ return uf->data_len; ++} ++ ++/** ++ * Callback prototype for unsolicited frame receive handler. ++ * ++ * @param[in] cbarg callback arg for receive handler ++ * @param[in] uf unsolicited frame descriptor ++ * ++ * @return None ++ */ ++typedef void (*bfa_cb_uf_recv_t) (void *cbarg, struct bfa_uf_s *uf); ++ ++/* ++ * bfa uf API functions ++ */ ++void bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, ++ void *cbarg); ++void bfa_uf_free(struct bfa_uf_s *uf); ++ ++/** ++ * bfa lport service api ++ */ ++ ++struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa); ++void bfa_lps_delete(struct bfa_lps_s *lps); ++void bfa_lps_discard(struct bfa_lps_s *lps); ++void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz, ++ wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en); ++void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn, ++ wwn_t nwwn); ++void bfa_lps_flogo(struct bfa_lps_s *lps); ++void bfa_lps_fdisclogo(struct bfa_lps_s *lps); ++u8 bfa_lps_get_tag(struct bfa_lps_s *lps); ++bfa_boolean_t bfa_lps_is_npiv_en(struct bfa_lps_s *lps); ++bfa_boolean_t bfa_lps_is_fport(struct bfa_lps_s *lps); ++bfa_boolean_t bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps); ++bfa_boolean_t bfa_lps_is_authreq(struct bfa_lps_s *lps); ++bfa_eproto_status_t bfa_lps_get_extstatus(struct bfa_lps_s *lps); ++u32 bfa_lps_get_pid(struct bfa_lps_s *lps); ++u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid); ++u16 bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps); ++wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps); ++wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps); ++u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps); ++u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps); ++void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); ++void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); ++void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); ++void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); ++ ++#endif /* __BFA_SVC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h +new file mode 100644 +index 0000000..e407103 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfa_timer.h +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_TIMER_H__ ++#define __BFA_TIMER_H__ ++ ++#include ++#include ++ ++struct bfa_s; ++ ++typedef void (*bfa_timer_cbfn_t)(void *); ++ ++/** ++ * BFA timer data structure ++ */ ++struct bfa_timer_s { ++ struct list_head qe; ++ bfa_timer_cbfn_t timercb; ++ void *arg; ++ int timeout; /**< in millisecs. */ ++}; ++ ++/** ++ * Timer module structure ++ */ ++struct bfa_timer_mod_s { ++ struct list_head timer_q; ++}; ++ ++#define BFA_TIMER_FREQ 500 /**< specified in millisecs */ ++ ++void bfa_timer_beat(struct bfa_timer_mod_s *mod); ++void bfa_timer_init(struct bfa_timer_mod_s *mod); ++void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer, ++ bfa_timer_cbfn_t timercb, void *arg, ++ unsigned int timeout); ++void bfa_timer_stop(struct bfa_timer_s *timer); ++ ++#endif /* __BFA_TIMER_H__ */ +diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h +new file mode 100644 +index 0000000..6cadfe0 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi.h +@@ -0,0 +1,174 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_H__ ++#define __BFI_H__ ++ ++#include ++#include ++ ++#pragma pack(1) ++ ++/** ++ * Msg header common to all msgs ++ */ ++struct bfi_mhdr_s { ++ u8 msg_class; /* @ref bfi_mclass_t */ ++ u8 msg_id; /* msg opcode with in the class */ ++ union { ++ struct { ++ u8 rsvd; ++ u8 lpu_id; /* msg destination */ ++ } h2i; ++ u16 i2htok; /* token in msgs to host */ ++ } mtag; ++}; ++ ++#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \ ++ (_mh).msg_class = (_mc); \ ++ (_mh).msg_id = (_op); \ ++ (_mh).mtag.h2i.lpu_id = (_lpuid); \ ++} while (0) ++ ++#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \ ++ (_mh).msg_class = (_mc); \ ++ (_mh).msg_id = (_op); \ ++ (_mh).mtag.i2htok = (_i2htok); \ ++} while (0) ++ ++/* ++ * Message opcodes: 0-127 to firmware, 128-255 to host ++ */ ++#define BFI_I2H_OPCODE_BASE 128 ++#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE) ++ ++/** ++ **************************************************************************** ++ * ++ * Scatter Gather Element and Page definition ++ * ++ **************************************************************************** ++ */ ++ ++#define BFI_SGE_INLINE 1 ++#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1) ++ ++/** ++ * SG Flags ++ */ ++enum { ++ BFI_SGE_DATA = 0, /* data address, not last */ ++ BFI_SGE_DATA_CPL = 1, /* data addr, last in current page */ ++ BFI_SGE_DATA_LAST = 3, /* data address, last */ ++ BFI_SGE_LINK = 2, /* link address */ ++ BFI_SGE_PGDLEN = 2, /* cumulative data length for page */ ++}; ++ ++/** ++ * DMA addresses ++ */ ++union bfi_addr_u { ++ struct { ++ u32 addr_lo; ++ u32 addr_hi; ++ } a32; ++}; ++ ++/** ++ * Scatter Gather Element ++ */ ++struct bfi_sge_s { ++#ifdef __BIGENDIAN ++ u32 flags : 2, ++ rsvd : 2, ++ sg_len : 28; ++#else ++ u32 sg_len : 28, ++ rsvd : 2, ++ flags : 2; ++#endif ++ union bfi_addr_u sga; ++}; ++ ++/** ++ * Scatter Gather Page ++ */ ++#define BFI_SGPG_DATA_SGES 7 ++#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1) ++#define BFI_SGPG_RSVD_WD_LEN 8 ++struct bfi_sgpg_s { ++ struct bfi_sge_s sges[BFI_SGPG_SGES_MAX]; ++ u32 rsvd[BFI_SGPG_RSVD_WD_LEN]; ++}; ++ ++/* ++ * Large Message structure - 128 Bytes size Msgs ++ */ ++#define BFI_LMSG_SZ 128 ++#define BFI_LMSG_PL_WSZ \ ++ ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr_s)) / 4) ++ ++struct bfi_msg_s { ++ struct bfi_mhdr_s mhdr; ++ u32 pl[BFI_LMSG_PL_WSZ]; ++}; ++ ++/** ++ * Mailbox message structure ++ */ ++#define BFI_MBMSG_SZ 7 ++struct bfi_mbmsg_s { ++ struct bfi_mhdr_s mh; ++ u32 pl[BFI_MBMSG_SZ]; ++}; ++ ++/** ++ * Message Classes ++ */ ++enum bfi_mclass { ++ BFI_MC_IOC = 1, /* IO Controller (IOC) */ ++ BFI_MC_DIAG = 2, /* Diagnostic Msgs */ ++ BFI_MC_FLASH = 3, /* Flash message class */ ++ BFI_MC_CEE = 4, ++ BFI_MC_FC_PORT = 5, /* FC port */ ++ BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */ ++ BFI_MC_LL = 7, /* Link Layer */ ++ BFI_MC_UF = 8, /* Unsolicited frame receive */ ++ BFI_MC_FCXP = 9, /* FC Transport */ ++ BFI_MC_LPS = 10, /* lport fc login services */ ++ BFI_MC_RPORT = 11, /* Remote port */ ++ BFI_MC_ITNIM = 12, /* I-T nexus (Initiator mode) */ ++ BFI_MC_IOIM_READ = 13, /* read IO (Initiator mode) */ ++ BFI_MC_IOIM_WRITE = 14, /* write IO (Initiator mode) */ ++ BFI_MC_IOIM_IO = 15, /* IO (Initiator mode) */ ++ BFI_MC_IOIM = 16, /* IO (Initiator mode) */ ++ BFI_MC_IOIM_IOCOM = 17, /* good IO completion */ ++ BFI_MC_TSKIM = 18, /* Initiator Task management */ ++ BFI_MC_SBOOT = 19, /* SAN boot services */ ++ BFI_MC_IPFC = 20, /* IP over FC Msgs */ ++ BFI_MC_PORT = 21, /* Physical port */ ++ BFI_MC_MAX = 32 ++}; ++ ++#define BFI_IOC_MAX_CQS 4 ++#define BFI_IOC_MAX_CQS_ASIC 8 ++#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */ ++ ++#pragma pack() ++ ++#endif /* __BFI_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_boot.h b/drivers/scsi/bfa/include/bfi/bfi_boot.h +new file mode 100644 +index 0000000..5955afe +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_boot.h +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++/* ++ * bfi_boot.h ++ */ ++ ++#ifndef __BFI_BOOT_H__ ++#define __BFI_BOOT_H__ ++ ++#define BFI_BOOT_TYPE_OFF 8 ++#define BFI_BOOT_PARAM_OFF 12 ++ ++#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */ ++#define BFI_BOOT_TYPE_FLASH 1 ++#define BFI_BOOT_TYPE_MEMTEST 2 ++ ++#define BFI_BOOT_MEMTEST_RES_ADDR 0x900 ++#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3 ++ ++#endif +diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h +new file mode 100644 +index 0000000..b3bb52b +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h +@@ -0,0 +1,305 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* ++ * bfi_cbreg.h crossbow host block register definitions ++ * ++ * !!! Do not edit. Auto generated. !!! ++ */ ++ ++#ifndef __BFI_CBREG_H__ ++#define __BFI_CBREG_H__ ++ ++ ++#define HOSTFN0_INT_STATUS 0x00014000 ++#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000 ++#define __HOSTFN0_INT_STATUS_LVL_SH 20 ++#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH) ++#define __HOSTFN0_INT_STATUS_P 0x000fffff ++#define HOSTFN0_INT_MSK 0x00014004 ++#define HOST_PAGE_NUM_FN0 0x00014008 ++#define __HOST_PAGE_NUM_FN 0x000001ff ++#define HOSTFN1_INT_STATUS 0x00014100 ++#define __HOSTFN1_INT_STAT_LVL_MK 0x00f00000 ++#define __HOSTFN1_INT_STAT_LVL_SH 20 ++#define __HOSTFN1_INT_STAT_LVL(_v) ((_v) << __HOSTFN1_INT_STAT_LVL_SH) ++#define __HOSTFN1_INT_STAT_P 0x000fffff ++#define HOSTFN1_INT_MSK 0x00014104 ++#define HOST_PAGE_NUM_FN1 0x00014108 ++#define APP_PLL_400_CTL_REG 0x00014204 ++#define __P_400_PLL_LOCK 0x80000000 ++#define __APP_PLL_400_SRAM_USE_100MHZ 0x00100000 ++#define __APP_PLL_400_RESET_TIMER_MK 0x000e0000 ++#define __APP_PLL_400_RESET_TIMER_SH 17 ++#define __APP_PLL_400_RESET_TIMER(_v) ((_v) << __APP_PLL_400_RESET_TIMER_SH) ++#define __APP_PLL_400_LOGIC_SOFT_RESET 0x00010000 ++#define __APP_PLL_400_CNTLMT0_1_MK 0x0000c000 ++#define __APP_PLL_400_CNTLMT0_1_SH 14 ++#define __APP_PLL_400_CNTLMT0_1(_v) ((_v) << __APP_PLL_400_CNTLMT0_1_SH) ++#define __APP_PLL_400_JITLMT0_1_MK 0x00003000 ++#define __APP_PLL_400_JITLMT0_1_SH 12 ++#define __APP_PLL_400_JITLMT0_1(_v) ((_v) << __APP_PLL_400_JITLMT0_1_SH) ++#define __APP_PLL_400_HREF 0x00000800 ++#define __APP_PLL_400_HDIV 0x00000400 ++#define __APP_PLL_400_P0_1_MK 0x00000300 ++#define __APP_PLL_400_P0_1_SH 8 ++#define __APP_PLL_400_P0_1(_v) ((_v) << __APP_PLL_400_P0_1_SH) ++#define __APP_PLL_400_Z0_2_MK 0x000000e0 ++#define __APP_PLL_400_Z0_2_SH 5 ++#define __APP_PLL_400_Z0_2(_v) ((_v) << __APP_PLL_400_Z0_2_SH) ++#define __APP_PLL_400_RSEL200500 0x00000010 ++#define __APP_PLL_400_ENARST 0x00000008 ++#define __APP_PLL_400_BYPASS 0x00000004 ++#define __APP_PLL_400_LRESETN 0x00000002 ++#define __APP_PLL_400_ENABLE 0x00000001 ++#define APP_PLL_212_CTL_REG 0x00014208 ++#define __P_212_PLL_LOCK 0x80000000 ++#define __APP_PLL_212_RESET_TIMER_MK 0x000e0000 ++#define __APP_PLL_212_RESET_TIMER_SH 17 ++#define __APP_PLL_212_RESET_TIMER(_v) ((_v) << __APP_PLL_212_RESET_TIMER_SH) ++#define __APP_PLL_212_LOGIC_SOFT_RESET 0x00010000 ++#define __APP_PLL_212_CNTLMT0_1_MK 0x0000c000 ++#define __APP_PLL_212_CNTLMT0_1_SH 14 ++#define __APP_PLL_212_CNTLMT0_1(_v) ((_v) << __APP_PLL_212_CNTLMT0_1_SH) ++#define __APP_PLL_212_JITLMT0_1_MK 0x00003000 ++#define __APP_PLL_212_JITLMT0_1_SH 12 ++#define __APP_PLL_212_JITLMT0_1(_v) ((_v) << __APP_PLL_212_JITLMT0_1_SH) ++#define __APP_PLL_212_HREF 0x00000800 ++#define __APP_PLL_212_HDIV 0x00000400 ++#define __APP_PLL_212_P0_1_MK 0x00000300 ++#define __APP_PLL_212_P0_1_SH 8 ++#define __APP_PLL_212_P0_1(_v) ((_v) << __APP_PLL_212_P0_1_SH) ++#define __APP_PLL_212_Z0_2_MK 0x000000e0 ++#define __APP_PLL_212_Z0_2_SH 5 ++#define __APP_PLL_212_Z0_2(_v) ((_v) << __APP_PLL_212_Z0_2_SH) ++#define __APP_PLL_212_RSEL200500 0x00000010 ++#define __APP_PLL_212_ENARST 0x00000008 ++#define __APP_PLL_212_BYPASS 0x00000004 ++#define __APP_PLL_212_LRESETN 0x00000002 ++#define __APP_PLL_212_ENABLE 0x00000001 ++#define HOST_SEM0_REG 0x00014230 ++#define __HOST_SEMAPHORE 0x00000001 ++#define HOST_SEM1_REG 0x00014234 ++#define HOST_SEM2_REG 0x00014238 ++#define HOST_SEM3_REG 0x0001423c ++#define HOST_SEM0_INFO_REG 0x00014240 ++#define HOST_SEM1_INFO_REG 0x00014244 ++#define HOST_SEM2_INFO_REG 0x00014248 ++#define HOST_SEM3_INFO_REG 0x0001424c ++#define HOSTFN0_LPU0_CMD_STAT 0x00019000 ++#define __HOSTFN0_LPU0_MBOX_INFO_MK 0xfffffffe ++#define __HOSTFN0_LPU0_MBOX_INFO_SH 1 ++#define __HOSTFN0_LPU0_MBOX_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX_INFO_SH) ++#define __HOSTFN0_LPU0_MBOX_CMD_STATUS 0x00000001 ++#define LPU0_HOSTFN0_CMD_STAT 0x00019008 ++#define __LPU0_HOSTFN0_MBOX_INFO_MK 0xfffffffe ++#define __LPU0_HOSTFN0_MBOX_INFO_SH 1 ++#define __LPU0_HOSTFN0_MBOX_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX_INFO_SH) ++#define __LPU0_HOSTFN0_MBOX_CMD_STATUS 0x00000001 ++#define HOSTFN1_LPU1_CMD_STAT 0x00019014 ++#define __HOSTFN1_LPU1_MBOX_INFO_MK 0xfffffffe ++#define __HOSTFN1_LPU1_MBOX_INFO_SH 1 ++#define __HOSTFN1_LPU1_MBOX_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX_INFO_SH) ++#define __HOSTFN1_LPU1_MBOX_CMD_STATUS 0x00000001 ++#define LPU1_HOSTFN1_CMD_STAT 0x0001901c ++#define __LPU1_HOSTFN1_MBOX_INFO_MK 0xfffffffe ++#define __LPU1_HOSTFN1_MBOX_INFO_SH 1 ++#define __LPU1_HOSTFN1_MBOX_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX_INFO_SH) ++#define __LPU1_HOSTFN1_MBOX_CMD_STATUS 0x00000001 ++#define CPE_Q0_DEPTH 0x00010014 ++#define CPE_Q0_PI 0x0001001c ++#define CPE_Q0_CI 0x00010020 ++#define CPE_Q1_DEPTH 0x00010034 ++#define CPE_Q1_PI 0x0001003c ++#define CPE_Q1_CI 0x00010040 ++#define CPE_Q2_DEPTH 0x00010054 ++#define CPE_Q2_PI 0x0001005c ++#define CPE_Q2_CI 0x00010060 ++#define CPE_Q3_DEPTH 0x00010074 ++#define CPE_Q3_PI 0x0001007c ++#define CPE_Q3_CI 0x00010080 ++#define CPE_Q4_DEPTH 0x00010094 ++#define CPE_Q4_PI 0x0001009c ++#define CPE_Q4_CI 0x000100a0 ++#define CPE_Q5_DEPTH 0x000100b4 ++#define CPE_Q5_PI 0x000100bc ++#define CPE_Q5_CI 0x000100c0 ++#define CPE_Q6_DEPTH 0x000100d4 ++#define CPE_Q6_PI 0x000100dc ++#define CPE_Q6_CI 0x000100e0 ++#define CPE_Q7_DEPTH 0x000100f4 ++#define CPE_Q7_PI 0x000100fc ++#define CPE_Q7_CI 0x00010100 ++#define RME_Q0_DEPTH 0x00011014 ++#define RME_Q0_PI 0x0001101c ++#define RME_Q0_CI 0x00011020 ++#define RME_Q1_DEPTH 0x00011034 ++#define RME_Q1_PI 0x0001103c ++#define RME_Q1_CI 0x00011040 ++#define RME_Q2_DEPTH 0x00011054 ++#define RME_Q2_PI 0x0001105c ++#define RME_Q2_CI 0x00011060 ++#define RME_Q3_DEPTH 0x00011074 ++#define RME_Q3_PI 0x0001107c ++#define RME_Q3_CI 0x00011080 ++#define RME_Q4_DEPTH 0x00011094 ++#define RME_Q4_PI 0x0001109c ++#define RME_Q4_CI 0x000110a0 ++#define RME_Q5_DEPTH 0x000110b4 ++#define RME_Q5_PI 0x000110bc ++#define RME_Q5_CI 0x000110c0 ++#define RME_Q6_DEPTH 0x000110d4 ++#define RME_Q6_PI 0x000110dc ++#define RME_Q6_CI 0x000110e0 ++#define RME_Q7_DEPTH 0x000110f4 ++#define RME_Q7_PI 0x000110fc ++#define RME_Q7_CI 0x00011100 ++#define PSS_CTL_REG 0x00018800 ++#define __PSS_I2C_CLK_DIV_MK 0x00030000 ++#define __PSS_I2C_CLK_DIV_SH 16 ++#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH) ++#define __PSS_LMEM_INIT_DONE 0x00001000 ++#define __PSS_LMEM_RESET 0x00000200 ++#define __PSS_LMEM_INIT_EN 0x00000100 ++#define __PSS_LPU1_RESET 0x00000002 ++#define __PSS_LPU0_RESET 0x00000001 ++ ++ ++/* ++ * These definitions are either in error/missing in spec. Its auto-generated ++ * from hard coded values in regparse.pl. ++ */ ++#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c ++#define __EMPHPOST_AT_4G_SH_FIX 0x00000002 ++#define __EMPHPRE_AT_4G_FIX 0x00000003 ++#define __SFP_TXRATE_EN_FIX 0x00000100 ++#define __SFP_RXRATE_EN_FIX 0x00000080 ++ ++ ++/* ++ * These register definitions are auto-generated from hard coded values ++ * in regparse.pl. ++ */ ++#define HOSTFN0_LPU_MBOX0_0 0x00019200 ++#define HOSTFN1_LPU_MBOX0_8 0x00019260 ++#define LPU_HOSTFN0_MBOX0_0 0x00019280 ++#define LPU_HOSTFN1_MBOX0_8 0x000192e0 ++ ++ ++/* ++ * These register mapping definitions are auto-generated from mapping tables ++ * in regparse.pl. ++ */ ++#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG ++#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG ++#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG ++#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG ++#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG ++ ++#define CPE_Q_DEPTH(__n) \ ++ (CPE_Q0_DEPTH + (__n) * (CPE_Q1_DEPTH - CPE_Q0_DEPTH)) ++#define CPE_Q_PI(__n) \ ++ (CPE_Q0_PI + (__n) * (CPE_Q1_PI - CPE_Q0_PI)) ++#define CPE_Q_CI(__n) \ ++ (CPE_Q0_CI + (__n) * (CPE_Q1_CI - CPE_Q0_CI)) ++#define RME_Q_DEPTH(__n) \ ++ (RME_Q0_DEPTH + (__n) * (RME_Q1_DEPTH - RME_Q0_DEPTH)) ++#define RME_Q_PI(__n) \ ++ (RME_Q0_PI + (__n) * (RME_Q1_PI - RME_Q0_PI)) ++#define RME_Q_CI(__n) \ ++ (RME_Q0_CI + (__n) * (RME_Q1_CI - RME_Q0_CI)) ++ ++#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) ++#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) ++#define CPE_Q_MASK(__q) ((__q) & 0x3) ++#define RME_Q_MASK(__q) ((__q) & 0x3) ++ ++ ++/* ++ * PCI MSI-X vector defines ++ */ ++enum { ++ BFA_MSIX_CPE_Q0 = 0, ++ BFA_MSIX_CPE_Q1 = 1, ++ BFA_MSIX_CPE_Q2 = 2, ++ BFA_MSIX_CPE_Q3 = 3, ++ BFA_MSIX_CPE_Q4 = 4, ++ BFA_MSIX_CPE_Q5 = 5, ++ BFA_MSIX_CPE_Q6 = 6, ++ BFA_MSIX_CPE_Q7 = 7, ++ BFA_MSIX_RME_Q0 = 8, ++ BFA_MSIX_RME_Q1 = 9, ++ BFA_MSIX_RME_Q2 = 10, ++ BFA_MSIX_RME_Q3 = 11, ++ BFA_MSIX_RME_Q4 = 12, ++ BFA_MSIX_RME_Q5 = 13, ++ BFA_MSIX_RME_Q6 = 14, ++ BFA_MSIX_RME_Q7 = 15, ++ BFA_MSIX_ERR_EMC = 16, ++ BFA_MSIX_ERR_LPU0 = 17, ++ BFA_MSIX_ERR_LPU1 = 18, ++ BFA_MSIX_ERR_PSS = 19, ++ BFA_MSIX_MBOX_LPU0 = 20, ++ BFA_MSIX_MBOX_LPU1 = 21, ++ BFA_MSIX_CB_MAX = 22, ++}; ++ ++/* ++ * And corresponding host interrupt status bit field defines ++ */ ++#define __HFN_INT_CPE_Q0 0x00000001U ++#define __HFN_INT_CPE_Q1 0x00000002U ++#define __HFN_INT_CPE_Q2 0x00000004U ++#define __HFN_INT_CPE_Q3 0x00000008U ++#define __HFN_INT_CPE_Q4 0x00000010U ++#define __HFN_INT_CPE_Q5 0x00000020U ++#define __HFN_INT_CPE_Q6 0x00000040U ++#define __HFN_INT_CPE_Q7 0x00000080U ++#define __HFN_INT_RME_Q0 0x00000100U ++#define __HFN_INT_RME_Q1 0x00000200U ++#define __HFN_INT_RME_Q2 0x00000400U ++#define __HFN_INT_RME_Q3 0x00000800U ++#define __HFN_INT_RME_Q4 0x00001000U ++#define __HFN_INT_RME_Q5 0x00002000U ++#define __HFN_INT_RME_Q6 0x00004000U ++#define __HFN_INT_RME_Q7 0x00008000U ++#define __HFN_INT_ERR_EMC 0x00010000U ++#define __HFN_INT_ERR_LPU0 0x00020000U ++#define __HFN_INT_ERR_LPU1 0x00040000U ++#define __HFN_INT_ERR_PSS 0x00080000U ++#define __HFN_INT_MBOX_LPU0 0x00100000U ++#define __HFN_INT_MBOX_LPU1 0x00200000U ++#define __HFN_INT_MBOX1_LPU0 0x00400000U ++#define __HFN_INT_MBOX1_LPU1 0x00800000U ++#define __HFN_INT_CPE_MASK 0x000000ffU ++#define __HFN_INT_RME_MASK 0x0000ff00U ++ ++ ++/* ++ * crossbow memory map. ++ */ ++#define PSS_SMEM_PAGE_START 0x8000 ++#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15)) ++#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff) ++ ++/* ++ * End of crossbow memory map ++ */ ++ ++ ++#endif /* __BFI_CBREG_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_cee.h b/drivers/scsi/bfa/include/bfi/bfi_cee.h +new file mode 100644 +index 0000000..0970596 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_cee.h +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++/** ++ * Copyright (c) 2006-2009 Brocade Communications Systems, Inc. ++ * All rights reserved. ++ * ++ * bfi_dcbx.h BFI Interface (Mailbox commands and related structures) ++ * between host driver and DCBX/LLDP firmware module. ++ * ++**/ ++ ++#ifndef __BFI_CEE_H__ ++#define __BFI_CEE_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++ ++enum bfi_cee_h2i_msgs_e { ++ BFI_CEE_H2I_GET_CFG_REQ = 1, ++ BFI_CEE_H2I_RESET_STATS = 2, ++ BFI_CEE_H2I_GET_STATS_REQ = 3, ++}; ++ ++ ++enum bfi_cee_i2h_msgs_e { ++ BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1), ++ BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2), ++ BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3), ++}; ++ ++ ++/* Data structures */ ++ ++/* ++ * BFI_CEE_H2I_RESET_STATS ++ */ ++struct bfi_lldp_reset_stats_s { ++ struct bfi_mhdr_s mh; ++}; ++ ++/* ++ * BFI_CEE_H2I_RESET_STATS ++ */ ++struct bfi_cee_reset_stats_s { ++ struct bfi_mhdr_s mh; ++}; ++ ++/* ++ * BFI_CEE_H2I_GET_CFG_REQ ++ */ ++struct bfi_cee_get_req_s { ++ struct bfi_mhdr_s mh; ++ union bfi_addr_u dma_addr; ++}; ++ ++ ++/* ++ * BFI_CEE_I2H_GET_CFG_RSP ++ */ ++struct bfi_cee_get_rsp_s { ++ struct bfi_mhdr_s mh; ++ u8 cmd_status; ++ u8 rsvd[3]; ++}; ++ ++/* ++ * BFI_CEE_H2I_GET_STATS_REQ ++ */ ++struct bfi_cee_stats_req_s { ++ struct bfi_mhdr_s mh; ++ union bfi_addr_u dma_addr; ++}; ++ ++ ++/* ++ * BFI_CEE_I2H_GET_STATS_RSP ++ */ ++struct bfi_cee_stats_rsp_s { ++ struct bfi_mhdr_s mh; ++ u8 cmd_status; ++ u8 rsvd[3]; ++}; ++ ++ ++ ++union bfi_cee_h2i_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_cee_get_req_s get_req; ++ struct bfi_cee_stats_req_s stats_req; ++}; ++ ++ ++union bfi_cee_i2h_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_cee_get_rsp_s get_rsp; ++ struct bfi_cee_stats_rsp_s stats_rsp; ++}; ++ ++#pragma pack() ++ ++ ++#endif /* __BFI_CEE_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +new file mode 100644 +index 0000000..d3caa58 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h +@@ -0,0 +1,611 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* ++ * bfi_ctreg.h catapult host block register definitions ++ * ++ * !!! Do not edit. Auto generated. !!! ++ */ ++ ++#ifndef __BFI_CTREG_H__ ++#define __BFI_CTREG_H__ ++ ++ ++#define HOSTFN0_LPU_MBOX0_0 0x00019200 ++#define HOSTFN1_LPU_MBOX0_8 0x00019260 ++#define LPU_HOSTFN0_MBOX0_0 0x00019280 ++#define LPU_HOSTFN1_MBOX0_8 0x000192e0 ++#define HOSTFN2_LPU_MBOX0_0 0x00019400 ++#define HOSTFN3_LPU_MBOX0_8 0x00019460 ++#define LPU_HOSTFN2_MBOX0_0 0x00019480 ++#define LPU_HOSTFN3_MBOX0_8 0x000194e0 ++#define HOSTFN0_INT_STATUS 0x00014000 ++#define __HOSTFN0_HALT_OCCURRED 0x01000000 ++#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000 ++#define __HOSTFN0_INT_STATUS_LVL_SH 20 ++#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH) ++#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000 ++#define __HOSTFN0_INT_STATUS_P_SH 16 ++#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH) ++#define __HOSTFN0_INT_STATUS_F 0x0000ffff ++#define HOSTFN0_INT_MSK 0x00014004 ++#define HOST_PAGE_NUM_FN0 0x00014008 ++#define __HOST_PAGE_NUM_FN 0x000001ff ++#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c ++#define __MSIX_ERR_INDEX_FN 0x000001ff ++#define HOSTFN1_INT_STATUS 0x00014100 ++#define __HOSTFN1_HALT_OCCURRED 0x01000000 ++#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000 ++#define __HOSTFN1_INT_STATUS_LVL_SH 20 ++#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH) ++#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000 ++#define __HOSTFN1_INT_STATUS_P_SH 16 ++#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH) ++#define __HOSTFN1_INT_STATUS_F 0x0000ffff ++#define HOSTFN1_INT_MSK 0x00014104 ++#define HOST_PAGE_NUM_FN1 0x00014108 ++#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c ++#define APP_PLL_425_CTL_REG 0x00014204 ++#define __P_425_PLL_LOCK 0x80000000 ++#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000 ++#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000 ++#define __APP_PLL_425_RESET_TIMER_SH 17 ++#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH) ++#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000 ++#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000 ++#define __APP_PLL_425_CNTLMT0_1_SH 14 ++#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH) ++#define __APP_PLL_425_JITLMT0_1_MK 0x00003000 ++#define __APP_PLL_425_JITLMT0_1_SH 12 ++#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH) ++#define __APP_PLL_425_HREF 0x00000800 ++#define __APP_PLL_425_HDIV 0x00000400 ++#define __APP_PLL_425_P0_1_MK 0x00000300 ++#define __APP_PLL_425_P0_1_SH 8 ++#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH) ++#define __APP_PLL_425_Z0_2_MK 0x000000e0 ++#define __APP_PLL_425_Z0_2_SH 5 ++#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH) ++#define __APP_PLL_425_RSEL200500 0x00000010 ++#define __APP_PLL_425_ENARST 0x00000008 ++#define __APP_PLL_425_BYPASS 0x00000004 ++#define __APP_PLL_425_LRESETN 0x00000002 ++#define __APP_PLL_425_ENABLE 0x00000001 ++#define APP_PLL_312_CTL_REG 0x00014208 ++#define __P_312_PLL_LOCK 0x80000000 ++#define __ENABLE_MAC_AHB_1 0x00800000 ++#define __ENABLE_MAC_AHB_0 0x00400000 ++#define __ENABLE_MAC_1 0x00200000 ++#define __ENABLE_MAC_0 0x00100000 ++#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000 ++#define __APP_PLL_312_RESET_TIMER_SH 17 ++#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH) ++#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000 ++#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000 ++#define __APP_PLL_312_CNTLMT0_1_SH 14 ++#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH) ++#define __APP_PLL_312_JITLMT0_1_MK 0x00003000 ++#define __APP_PLL_312_JITLMT0_1_SH 12 ++#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH) ++#define __APP_PLL_312_HREF 0x00000800 ++#define __APP_PLL_312_HDIV 0x00000400 ++#define __APP_PLL_312_P0_1_MK 0x00000300 ++#define __APP_PLL_312_P0_1_SH 8 ++#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH) ++#define __APP_PLL_312_Z0_2_MK 0x000000e0 ++#define __APP_PLL_312_Z0_2_SH 5 ++#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH) ++#define __APP_PLL_312_RSEL200500 0x00000010 ++#define __APP_PLL_312_ENARST 0x00000008 ++#define __APP_PLL_312_BYPASS 0x00000004 ++#define __APP_PLL_312_LRESETN 0x00000002 ++#define __APP_PLL_312_ENABLE 0x00000001 ++#define MBIST_CTL_REG 0x00014220 ++#define __EDRAM_BISTR_START 0x00000004 ++#define __MBIST_RESET 0x00000002 ++#define __MBIST_START 0x00000001 ++#define MBIST_STAT_REG 0x00014224 ++#define __EDRAM_BISTR_STATUS 0x00000008 ++#define __EDRAM_BISTR_DONE 0x00000004 ++#define __MEM_BIT_STATUS 0x00000002 ++#define __MBIST_DONE 0x00000001 ++#define HOST_SEM0_REG 0x00014230 ++#define __HOST_SEMAPHORE 0x00000001 ++#define HOST_SEM1_REG 0x00014234 ++#define HOST_SEM2_REG 0x00014238 ++#define HOST_SEM3_REG 0x0001423c ++#define HOST_SEM0_INFO_REG 0x00014240 ++#define HOST_SEM1_INFO_REG 0x00014244 ++#define HOST_SEM2_INFO_REG 0x00014248 ++#define HOST_SEM3_INFO_REG 0x0001424c ++#define ETH_MAC_SER_REG 0x00014288 ++#define __APP_EMS_CKBUFAMPIN 0x00000020 ++#define __APP_EMS_REFCLKSEL 0x00000010 ++#define __APP_EMS_CMLCKSEL 0x00000008 ++#define __APP_EMS_REFCKBUFEN2 0x00000004 ++#define __APP_EMS_REFCKBUFEN1 0x00000002 ++#define __APP_EMS_CHANNEL_SEL 0x00000001 ++#define HOSTFN2_INT_STATUS 0x00014300 ++#define __HOSTFN2_HALT_OCCURRED 0x01000000 ++#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000 ++#define __HOSTFN2_INT_STATUS_LVL_SH 20 ++#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH) ++#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000 ++#define __HOSTFN2_INT_STATUS_P_SH 16 ++#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH) ++#define __HOSTFN2_INT_STATUS_F 0x0000ffff ++#define HOSTFN2_INT_MSK 0x00014304 ++#define HOST_PAGE_NUM_FN2 0x00014308 ++#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c ++#define HOSTFN3_INT_STATUS 0x00014400 ++#define __HALT_OCCURRED 0x01000000 ++#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000 ++#define __HOSTFN3_INT_STATUS_LVL_SH 20 ++#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH) ++#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000 ++#define __HOSTFN3_INT_STATUS_P_SH 16 ++#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH) ++#define __HOSTFN3_INT_STATUS_F 0x0000ffff ++#define HOSTFN3_INT_MSK 0x00014404 ++#define HOST_PAGE_NUM_FN3 0x00014408 ++#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c ++#define FNC_ID_REG 0x00014600 ++#define __FUNCTION_NUMBER 0x00000007 ++#define FNC_PERS_REG 0x00014604 ++#define __F3_FUNCTION_ACTIVE 0x80000000 ++#define __F3_FUNCTION_MODE 0x40000000 ++#define __F3_PORT_MAP_MK 0x30000000 ++#define __F3_PORT_MAP_SH 28 ++#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH) ++#define __F3_VM_MODE 0x08000000 ++#define __F3_INTX_STATUS_MK 0x07000000 ++#define __F3_INTX_STATUS_SH 24 ++#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH) ++#define __F2_FUNCTION_ACTIVE 0x00800000 ++#define __F2_FUNCTION_MODE 0x00400000 ++#define __F2_PORT_MAP_MK 0x00300000 ++#define __F2_PORT_MAP_SH 20 ++#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH) ++#define __F2_VM_MODE 0x00080000 ++#define __F2_INTX_STATUS_MK 0x00070000 ++#define __F2_INTX_STATUS_SH 16 ++#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH) ++#define __F1_FUNCTION_ACTIVE 0x00008000 ++#define __F1_FUNCTION_MODE 0x00004000 ++#define __F1_PORT_MAP_MK 0x00003000 ++#define __F1_PORT_MAP_SH 12 ++#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH) ++#define __F1_VM_MODE 0x00000800 ++#define __F1_INTX_STATUS_MK 0x00000700 ++#define __F1_INTX_STATUS_SH 8 ++#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH) ++#define __F0_FUNCTION_ACTIVE 0x00000080 ++#define __F0_FUNCTION_MODE 0x00000040 ++#define __F0_PORT_MAP_MK 0x00000030 ++#define __F0_PORT_MAP_SH 4 ++#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH) ++#define __F0_VM_MODE 0x00000008 ++#define __F0_INTX_STATUS 0x00000007 ++enum { ++ __F0_INTX_STATUS_MSIX = 0x0, ++ __F0_INTX_STATUS_INTA = 0x1, ++ __F0_INTX_STATUS_INTB = 0x2, ++ __F0_INTX_STATUS_INTC = 0x3, ++ __F0_INTX_STATUS_INTD = 0x4, ++}; ++#define OP_MODE 0x0001460c ++#define __APP_ETH_CLK_LOWSPEED 0x00000004 ++#define __GLOBAL_CORECLK_HALFSPEED 0x00000002 ++#define __GLOBAL_FCOE_MODE 0x00000001 ++#define HOST_SEM4_REG 0x00014610 ++#define HOST_SEM5_REG 0x00014614 ++#define HOST_SEM6_REG 0x00014618 ++#define HOST_SEM7_REG 0x0001461c ++#define HOST_SEM4_INFO_REG 0x00014620 ++#define HOST_SEM5_INFO_REG 0x00014624 ++#define HOST_SEM6_INFO_REG 0x00014628 ++#define HOST_SEM7_INFO_REG 0x0001462c ++#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000 ++#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1 ++#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH) ++#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004 ++#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1 ++#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH) ++#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001 ++#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008 ++#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe ++#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1 ++#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH) ++#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 ++#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c ++#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe ++#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1 ++#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH) ++#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010 ++#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1 ++#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH) ++#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014 ++#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1 ++#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH) ++#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001 ++#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018 ++#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe ++#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1 ++#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH) ++#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 ++#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c ++#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe ++#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1 ++#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH) ++#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150 ++#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1 ++#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH) ++#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154 ++#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1 ++#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH) ++#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001 ++#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158 ++#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe ++#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1 ++#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH) ++#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 ++#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c ++#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe ++#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1 ++#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH) ++#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160 ++#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1 ++#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH) ++#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001 ++#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164 ++#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe ++#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1 ++#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH) ++#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001 ++#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168 ++#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe ++#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1 ++#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH) ++#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 ++#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c ++#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe ++#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1 ++#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH) ++#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 ++#define FW_INIT_HALT_P0 0x000191ac ++#define __FW_INIT_HALT_P 0x00000001 ++#define FW_INIT_HALT_P1 0x000191bc ++#define CPE_PI_PTR_Q0 0x00038000 ++#define __CPE_PI_UNUSED_MK 0xffff0000 ++#define __CPE_PI_UNUSED_SH 16 ++#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH) ++#define __CPE_PI_PTR 0x0000ffff ++#define CPE_PI_PTR_Q1 0x00038040 ++#define CPE_CI_PTR_Q0 0x00038004 ++#define __CPE_CI_UNUSED_MK 0xffff0000 ++#define __CPE_CI_UNUSED_SH 16 ++#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH) ++#define __CPE_CI_PTR 0x0000ffff ++#define CPE_CI_PTR_Q1 0x00038044 ++#define CPE_DEPTH_Q0 0x00038008 ++#define __CPE_DEPTH_UNUSED_MK 0xf8000000 ++#define __CPE_DEPTH_UNUSED_SH 27 ++#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH) ++#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000 ++#define __CPE_MSIX_VEC_INDEX_SH 16 ++#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH) ++#define __CPE_DEPTH 0x0000ffff ++#define CPE_DEPTH_Q1 0x00038048 ++#define CPE_QCTRL_Q0 0x0003800c ++#define __CPE_CTRL_UNUSED30_MK 0xfc000000 ++#define __CPE_CTRL_UNUSED30_SH 26 ++#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH) ++#define __CPE_FUNC_INT_CTRL_MK 0x03000000 ++#define __CPE_FUNC_INT_CTRL_SH 24 ++#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH) ++enum { ++ __CPE_FUNC_INT_CTRL_DISABLE = 0x0, ++ __CPE_FUNC_INT_CTRL_F2NF = 0x1, ++ __CPE_FUNC_INT_CTRL_3QUART = 0x2, ++ __CPE_FUNC_INT_CTRL_HALF = 0x3, ++}; ++#define __CPE_CTRL_UNUSED20_MK 0x00f00000 ++#define __CPE_CTRL_UNUSED20_SH 20 ++#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH) ++#define __CPE_SCI_TH_MK 0x000f0000 ++#define __CPE_SCI_TH_SH 16 ++#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH) ++#define __CPE_CTRL_UNUSED10_MK 0x0000c000 ++#define __CPE_CTRL_UNUSED10_SH 14 ++#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH) ++#define __CPE_ACK_PENDING 0x00002000 ++#define __CPE_CTRL_UNUSED40_MK 0x00001c00 ++#define __CPE_CTRL_UNUSED40_SH 10 ++#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH) ++#define __CPE_PCIEID_MK 0x00000300 ++#define __CPE_PCIEID_SH 8 ++#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH) ++#define __CPE_CTRL_UNUSED00_MK 0x000000fe ++#define __CPE_CTRL_UNUSED00_SH 1 ++#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH) ++#define __CPE_ESIZE 0x00000001 ++#define CPE_QCTRL_Q1 0x0003804c ++#define __CPE_CTRL_UNUSED31_MK 0xfc000000 ++#define __CPE_CTRL_UNUSED31_SH 26 ++#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH) ++#define __CPE_CTRL_UNUSED21_MK 0x00f00000 ++#define __CPE_CTRL_UNUSED21_SH 20 ++#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH) ++#define __CPE_CTRL_UNUSED11_MK 0x0000c000 ++#define __CPE_CTRL_UNUSED11_SH 14 ++#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH) ++#define __CPE_CTRL_UNUSED41_MK 0x00001c00 ++#define __CPE_CTRL_UNUSED41_SH 10 ++#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH) ++#define __CPE_CTRL_UNUSED01_MK 0x000000fe ++#define __CPE_CTRL_UNUSED01_SH 1 ++#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH) ++#define RME_PI_PTR_Q0 0x00038020 ++#define __LATENCY_TIME_STAMP_MK 0xffff0000 ++#define __LATENCY_TIME_STAMP_SH 16 ++#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH) ++#define __RME_PI_PTR 0x0000ffff ++#define RME_PI_PTR_Q1 0x00038060 ++#define RME_CI_PTR_Q0 0x00038024 ++#define __DELAY_TIME_STAMP_MK 0xffff0000 ++#define __DELAY_TIME_STAMP_SH 16 ++#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH) ++#define __RME_CI_PTR 0x0000ffff ++#define RME_CI_PTR_Q1 0x00038064 ++#define RME_DEPTH_Q0 0x00038028 ++#define __RME_DEPTH_UNUSED_MK 0xf8000000 ++#define __RME_DEPTH_UNUSED_SH 27 ++#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH) ++#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000 ++#define __RME_MSIX_VEC_INDEX_SH 16 ++#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH) ++#define __RME_DEPTH 0x0000ffff ++#define RME_DEPTH_Q1 0x00038068 ++#define RME_QCTRL_Q0 0x0003802c ++#define __RME_INT_LATENCY_TIMER_MK 0xff000000 ++#define __RME_INT_LATENCY_TIMER_SH 24 ++#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH) ++#define __RME_INT_DELAY_TIMER_MK 0x00ff0000 ++#define __RME_INT_DELAY_TIMER_SH 16 ++#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH) ++#define __RME_INT_DELAY_DISABLE 0x00008000 ++#define __RME_DLY_DELAY_DISABLE 0x00004000 ++#define __RME_ACK_PENDING 0x00002000 ++#define __RME_FULL_INTERRUPT_DISABLE 0x00001000 ++#define __RME_CTRL_UNUSED10_MK 0x00000c00 ++#define __RME_CTRL_UNUSED10_SH 10 ++#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH) ++#define __RME_PCIEID_MK 0x00000300 ++#define __RME_PCIEID_SH 8 ++#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH) ++#define __RME_CTRL_UNUSED00_MK 0x000000fe ++#define __RME_CTRL_UNUSED00_SH 1 ++#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH) ++#define __RME_ESIZE 0x00000001 ++#define RME_QCTRL_Q1 0x0003806c ++#define __RME_CTRL_UNUSED11_MK 0x00000c00 ++#define __RME_CTRL_UNUSED11_SH 10 ++#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH) ++#define __RME_CTRL_UNUSED01_MK 0x000000fe ++#define __RME_CTRL_UNUSED01_SH 1 ++#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH) ++#define PSS_CTL_REG 0x00018800 ++#define __PSS_I2C_CLK_DIV_MK 0x007f0000 ++#define __PSS_I2C_CLK_DIV_SH 16 ++#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH) ++#define __PSS_LMEM_INIT_DONE 0x00001000 ++#define __PSS_LMEM_RESET 0x00000200 ++#define __PSS_LMEM_INIT_EN 0x00000100 ++#define __PSS_LPU1_RESET 0x00000002 ++#define __PSS_LPU0_RESET 0x00000001 ++#define HQM_QSET0_RXQ_DRBL_P0 0x00038000 ++#define __RXQ0_ADD_VECTORS_P 0x80000000 ++#define __RXQ0_STOP_P 0x40000000 ++#define __RXQ0_PRD_PTR_P 0x0000ffff ++#define HQM_QSET1_RXQ_DRBL_P0 0x00038080 ++#define __RXQ1_ADD_VECTORS_P 0x80000000 ++#define __RXQ1_STOP_P 0x40000000 ++#define __RXQ1_PRD_PTR_P 0x0000ffff ++#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000 ++#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080 ++#define HQM_QSET0_TXQ_DRBL_P0 0x00038020 ++#define __TXQ0_ADD_VECTORS_P 0x80000000 ++#define __TXQ0_STOP_P 0x40000000 ++#define __TXQ0_PRD_PTR_P 0x0000ffff ++#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0 ++#define __TXQ1_ADD_VECTORS_P 0x80000000 ++#define __TXQ1_STOP_P 0x40000000 ++#define __TXQ1_PRD_PTR_P 0x0000ffff ++#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020 ++#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0 ++#define HQM_QSET0_IB_DRBL_1_P0 0x00038040 ++#define __IB1_0_ACK_P 0x80000000 ++#define __IB1_0_DISABLE_P 0x40000000 ++#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff ++#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0 ++#define __IB1_1_ACK_P 0x80000000 ++#define __IB1_1_DISABLE_P 0x40000000 ++#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff ++#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040 ++#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0 ++#define HQM_QSET0_IB_DRBL_2_P0 0x00038060 ++#define __IB2_0_ACK_P 0x80000000 ++#define __IB2_0_DISABLE_P 0x40000000 ++#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff ++#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0 ++#define __IB2_1_ACK_P 0x80000000 ++#define __IB2_1_DISABLE_P 0x40000000 ++#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff ++#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060 ++#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0 ++ ++ ++/* ++ * These definitions are either in error/missing in spec. Its auto-generated ++ * from hard coded values in regparse.pl. ++ */ ++#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c ++#define __EMPHPOST_AT_4G_SH_FIX 0x00000002 ++#define __EMPHPRE_AT_4G_FIX 0x00000003 ++#define __SFP_TXRATE_EN_FIX 0x00000100 ++#define __SFP_RXRATE_EN_FIX 0x00000080 ++ ++ ++/* ++ * These register definitions are auto-generated from hard coded values ++ * in regparse.pl. ++ */ ++ ++ ++/* ++ * These register mapping definitions are auto-generated from mapping tables ++ * in regparse.pl. ++ */ ++#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG ++#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG ++#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG ++#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG ++#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG ++ ++#define CPE_DEPTH_Q(__n) \ ++ (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0)) ++#define CPE_QCTRL_Q(__n) \ ++ (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0)) ++#define CPE_PI_PTR_Q(__n) \ ++ (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0)) ++#define CPE_CI_PTR_Q(__n) \ ++ (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0)) ++#define RME_DEPTH_Q(__n) \ ++ (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0)) ++#define RME_QCTRL_Q(__n) \ ++ (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0)) ++#define RME_PI_PTR_Q(__n) \ ++ (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0)) ++#define RME_CI_PTR_Q(__n) \ ++ (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0)) ++#define HQM_QSET_RXQ_DRBL_P0(__n) \ ++ (HQM_QSET0_RXQ_DRBL_P0 + (__n) * (HQM_QSET1_RXQ_DRBL_P0 - \ ++ HQM_QSET0_RXQ_DRBL_P0)) ++#define HQM_QSET_TXQ_DRBL_P0(__n) \ ++ (HQM_QSET0_TXQ_DRBL_P0 + (__n) * (HQM_QSET1_TXQ_DRBL_P0 - \ ++ HQM_QSET0_TXQ_DRBL_P0)) ++#define HQM_QSET_IB_DRBL_1_P0(__n) \ ++ (HQM_QSET0_IB_DRBL_1_P0 + (__n) * (HQM_QSET1_IB_DRBL_1_P0 - \ ++ HQM_QSET0_IB_DRBL_1_P0)) ++#define HQM_QSET_IB_DRBL_2_P0(__n) \ ++ (HQM_QSET0_IB_DRBL_2_P0 + (__n) * (HQM_QSET1_IB_DRBL_2_P0 - \ ++ HQM_QSET0_IB_DRBL_2_P0)) ++#define HQM_QSET_RXQ_DRBL_P1(__n) \ ++ (HQM_QSET0_RXQ_DRBL_P1 + (__n) * (HQM_QSET1_RXQ_DRBL_P1 - \ ++ HQM_QSET0_RXQ_DRBL_P1)) ++#define HQM_QSET_TXQ_DRBL_P1(__n) \ ++ (HQM_QSET0_TXQ_DRBL_P1 + (__n) * (HQM_QSET1_TXQ_DRBL_P1 - \ ++ HQM_QSET0_TXQ_DRBL_P1)) ++#define HQM_QSET_IB_DRBL_1_P1(__n) \ ++ (HQM_QSET0_IB_DRBL_1_P1 + (__n) * (HQM_QSET1_IB_DRBL_1_P1 - \ ++ HQM_QSET0_IB_DRBL_1_P1)) ++#define HQM_QSET_IB_DRBL_2_P1(__n) \ ++ (HQM_QSET0_IB_DRBL_2_P1 + (__n) * (HQM_QSET1_IB_DRBL_2_P1 - \ ++ HQM_QSET0_IB_DRBL_2_P1)) ++ ++#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) ++#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) ++#define CPE_Q_MASK(__q) ((__q) & 0x3) ++#define RME_Q_MASK(__q) ((__q) & 0x3) ++ ++ ++/* ++ * PCI MSI-X vector defines ++ */ ++enum { ++ BFA_MSIX_CPE_Q0 = 0, ++ BFA_MSIX_CPE_Q1 = 1, ++ BFA_MSIX_CPE_Q2 = 2, ++ BFA_MSIX_CPE_Q3 = 3, ++ BFA_MSIX_RME_Q0 = 4, ++ BFA_MSIX_RME_Q1 = 5, ++ BFA_MSIX_RME_Q2 = 6, ++ BFA_MSIX_RME_Q3 = 7, ++ BFA_MSIX_LPU_ERR = 8, ++ BFA_MSIX_CT_MAX = 9, ++}; ++ ++/* ++ * And corresponding host interrupt status bit field defines ++ */ ++#define __HFN_INT_CPE_Q0 0x00000001U ++#define __HFN_INT_CPE_Q1 0x00000002U ++#define __HFN_INT_CPE_Q2 0x00000004U ++#define __HFN_INT_CPE_Q3 0x00000008U ++#define __HFN_INT_CPE_Q4 0x00000010U ++#define __HFN_INT_CPE_Q5 0x00000020U ++#define __HFN_INT_CPE_Q6 0x00000040U ++#define __HFN_INT_CPE_Q7 0x00000080U ++#define __HFN_INT_RME_Q0 0x00000100U ++#define __HFN_INT_RME_Q1 0x00000200U ++#define __HFN_INT_RME_Q2 0x00000400U ++#define __HFN_INT_RME_Q3 0x00000800U ++#define __HFN_INT_RME_Q4 0x00001000U ++#define __HFN_INT_RME_Q5 0x00002000U ++#define __HFN_INT_RME_Q6 0x00004000U ++#define __HFN_INT_RME_Q7 0x00008000U ++#define __HFN_INT_ERR_EMC 0x00010000U ++#define __HFN_INT_ERR_LPU0 0x00020000U ++#define __HFN_INT_ERR_LPU1 0x00040000U ++#define __HFN_INT_ERR_PSS 0x00080000U ++#define __HFN_INT_MBOX_LPU0 0x00100000U ++#define __HFN_INT_MBOX_LPU1 0x00200000U ++#define __HFN_INT_MBOX1_LPU0 0x00400000U ++#define __HFN_INT_MBOX1_LPU1 0x00800000U ++#define __HFN_INT_CPE_MASK 0x000000ffU ++#define __HFN_INT_RME_MASK 0x0000ff00U ++ ++ ++/* ++ * catapult memory map. ++ */ ++#define LL_PGN_HQM0 0x0096 ++#define LL_PGN_HQM1 0x0097 ++#define PSS_SMEM_PAGE_START 0x8000 ++#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15)) ++#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff) ++ ++/* ++ * End of catapult memory map ++ */ ++ ++ ++#endif /* __BFI_CTREG_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_fabric.h b/drivers/scsi/bfa/include/bfi/bfi_fabric.h +new file mode 100644 +index 0000000..c0669ed +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_fabric.h +@@ -0,0 +1,92 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_FABRIC_H__ ++#define __BFI_FABRIC_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum bfi_fabric_h2i_msgs { ++ BFI_FABRIC_H2I_CREATE_REQ = 1, ++ BFI_FABRIC_H2I_DELETE_REQ = 2, ++ BFI_FABRIC_H2I_SETAUTH = 3, ++}; ++ ++enum bfi_fabric_i2h_msgs { ++ BFI_FABRIC_I2H_CREATE_RSP = BFA_I2HM(1), ++ BFI_FABRIC_I2H_DELETE_RSP = BFA_I2HM(2), ++ BFI_FABRIC_I2H_SETAUTH_RSP = BFA_I2HM(3), ++ BFI_FABRIC_I2H_ONLINE = BFA_I2HM(4), ++ BFI_FABRIC_I2H_OFFLINE = BFA_I2HM(5), ++}; ++ ++struct bfi_fabric_create_req_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u8 vf_en; /* virtual fabric enable */ ++ u8 rsvd; ++ u16 vf_id; /* virtual fabric ID */ ++ wwn_t pwwn; /* port name */ ++ wwn_t nwwn; /* node name */ ++}; ++ ++struct bfi_fabric_create_rsp_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 bfa_handle; /* host fabric handle */ ++ u8 status; /* fabric create status */ ++ u8 rsvd; ++}; ++ ++struct bfi_fabric_delete_req_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 fw_handle; /* firmware fabric handle */ ++ u16 rsvd; ++}; ++ ++struct bfi_fabric_delete_rsp_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 bfa_handle; /* host fabric handle */ ++ u8 status; /* fabric deletion status */ ++ u8 rsvd; ++}; ++ ++#define BFI_FABRIC_AUTHSECRET_LEN 64 ++struct bfi_fabric_setauth_req_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 fw_handle; /* f/w handle of fabric */ ++ u8 algorithm; ++ u8 group; ++ u8 secret[BFI_FABRIC_AUTHSECRET_LEN]; ++}; ++ ++union bfi_fabric_h2i_msg_u { ++ bfi_msg_t *msg; ++ struct bfi_fabric_create_req_s *create_req; ++ struct bfi_fabric_delete_req_s *delete_req; ++}; ++ ++union bfi_fabric_i2h_msg_u { ++ bfi_msg_t *msg; ++ struct bfi_fabric_create_rsp_s *create_rsp; ++ struct bfi_fabric_delete_rsp_s *delete_rsp; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_FABRIC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcpim.h b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h +new file mode 100644 +index 0000000..52c059f +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h +@@ -0,0 +1,301 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_FCPIM_H__ ++#define __BFI_FCPIM_H__ ++ ++#include "bfi.h" ++#include ++ ++#pragma pack(1) ++ ++/* ++ * Initiator mode I-T nexus interface defines. ++ */ ++ ++enum bfi_itnim_h2i { ++ BFI_ITNIM_H2I_CREATE_REQ = 1, /* i-t nexus creation */ ++ BFI_ITNIM_H2I_DELETE_REQ = 2, /* i-t nexus deletion */ ++}; ++ ++enum bfi_itnim_i2h { ++ BFI_ITNIM_I2H_CREATE_RSP = BFA_I2HM(1), ++ BFI_ITNIM_I2H_DELETE_RSP = BFA_I2HM(2), ++ BFI_ITNIM_I2H_SLER_EVENT = BFA_I2HM(3), ++}; ++ ++struct bfi_itnim_create_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 fw_handle; /* f/w handle for itnim */ ++ u8 class; /* FC class for IO */ ++ u8 seq_rec; /* sequence recovery support */ ++ u8 msg_no; /* seq id of the msg */ ++}; ++ ++struct bfi_itnim_create_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* bfa handle for itnim */ ++ u8 status; /* fcp request status */ ++ u8 seq_id; /* seq id of the msg */ ++}; ++ ++struct bfi_itnim_delete_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 fw_handle; /* f/w itnim handle */ ++ u8 seq_id; /* seq id of the msg */ ++ u8 rsvd; ++}; ++ ++struct bfi_itnim_delete_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* bfa handle for itnim */ ++ u8 status; /* fcp request status */ ++ u8 seq_id; /* seq id of the msg */ ++}; ++ ++struct bfi_itnim_sler_event_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* bfa handle for itnim */ ++ u16 rsvd; ++}; ++ ++union bfi_itnim_h2i_msg_u { ++ struct bfi_itnim_create_req_s *create_req; ++ struct bfi_itnim_delete_req_s *delete_req; ++ struct bfi_msg_s *msg; ++}; ++ ++union bfi_itnim_i2h_msg_u { ++ struct bfi_itnim_create_rsp_s *create_rsp; ++ struct bfi_itnim_delete_rsp_s *delete_rsp; ++ struct bfi_itnim_sler_event_s *sler_event; ++ struct bfi_msg_s *msg; ++}; ++ ++/* ++ * Initiator mode IO interface defines. ++ */ ++ ++enum bfi_ioim_h2i { ++ BFI_IOIM_H2I_IOABORT_REQ = 1, /* IO abort request */ ++ BFI_IOIM_H2I_IOCLEANUP_REQ = 2, /* IO cleanup request */ ++}; ++ ++enum bfi_ioim_i2h { ++ BFI_IOIM_I2H_IO_RSP = BFA_I2HM(1), /* non-fp IO response */ ++ BFI_IOIM_I2H_IOABORT_RSP = BFA_I2HM(2),/* ABORT rsp */ ++}; ++ ++/** ++ * IO command DIF info ++ */ ++struct bfi_ioim_dif_s { ++ u32 dif_info[4]; ++}; ++ ++/** ++ * FCP IO messages overview ++ * ++ * @note ++ * - Max CDB length supported is 64 bytes. ++ * - SCSI Linked commands and SCSI bi-directional Commands not ++ * supported. ++ * ++ */ ++struct bfi_ioim_req_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 io_tag; /* I/O tag */ ++ u16 rport_hdl; /* itnim/rport firmware handle */ ++ struct fcp_cmnd_s cmnd; /* IO request info */ ++ ++ /** ++ * SG elements array within the IO request must be double word ++ * aligned. This aligment is required to optimize SGM setup for the IO. ++ */ ++ struct bfi_sge_s sges[BFI_SGE_INLINE_MAX]; ++ u8 io_timeout; ++ u8 dif_en; ++ u8 rsvd_a[2]; ++ struct bfi_ioim_dif_s dif; ++}; ++ ++/** ++ * This table shows various IO status codes from firmware and their ++ * meaning. Host driver can use these status codes to further process ++ * IO completions. ++ * ++ * BFI_IOIM_STS_OK : IO completed with error free SCSI & ++ * transport status. ++ * - io-tag can be reused. ++ * ++ * BFA_IOIM_STS_SCSI_ERR : IO completed with scsi error. ++ * - io-tag can be reused. ++ * ++ * BFI_IOIM_STS_HOST_ABORTED : IO was aborted successfully due to ++ * host request. ++ * - io-tag cannot be reused yet. ++ * ++ * BFI_IOIM_STS_ABORTED : IO was aborted successfully ++ * internally by f/w. ++ * - io-tag cannot be reused yet. ++ * ++ * BFI_IOIM_STS_TIMEDOUT : IO timedout and ABTS/RRQ is happening ++ * in the firmware and ++ * - io-tag cannot be reused yet. ++ * ++ * BFI_IOIM_STS_SQER_NEEDED : Firmware could not recover the IO ++ * with sequence level error ++ * logic and hence host needs to retry ++ * this IO with a different IO tag ++ * - io-tag cannot be used yet. ++ * ++ * BFI_IOIM_STS_NEXUS_ABORT : Second Level Error Recovery from host ++ * is required because 2 consecutive ABTS ++ * timedout and host needs logout and ++ * re-login with the target ++ * - io-tag cannot be used yet. ++ * ++ * BFI_IOIM_STS_UNDERRUN : IO completed with SCSI status good, ++ * but the data tranferred is less than ++ * the fcp data length in the command. ++ * ex. SCSI INQUIRY where transferred ++ * data length and residue count in FCP ++ * response accounts for total fcp-dl ++ * - io-tag can be reused. ++ * ++ * BFI_IOIM_STS_OVERRUN : IO completed with SCSI status good, ++ * but the data transerred is more than ++ * fcp data length in the command. ex. ++ * TAPE IOs where blocks can of unequal ++ * lengths. ++ * - io-tag can be reused. ++ * ++ * BFI_IOIM_STS_RES_FREE : Firmware has completed using io-tag ++ * during abort process ++ * - io-tag can be reused. ++ * ++ * BFI_IOIM_STS_PROTO_ERR : Firmware detected a protocol error. ++ * ex target sent more data than ++ * requested, or there was data frame ++ * loss and other reasons ++ * - io-tag cannot be used yet. ++ * ++ * BFI_IOIM_STS_DIF_ERR : Firwmare detected DIF error. ex: DIF ++ * CRC err or Ref Tag err or App tag err. ++ * - io-tag can be reused. ++ * ++ * BFA_IOIM_STS_TSK_MGT_ABORT : IO was aborted because of Task ++ * Management command from the host ++ * - io-tag can be reused. ++ * ++ * BFI_IOIM_STS_UTAG : Firmware does not know about this ++ * io_tag. ++ * - io-tag can be reused. ++ */ ++enum bfi_ioim_status { ++ BFI_IOIM_STS_OK = 0, ++ BFI_IOIM_STS_HOST_ABORTED = 1, ++ BFI_IOIM_STS_ABORTED = 2, ++ BFI_IOIM_STS_TIMEDOUT = 3, ++ BFI_IOIM_STS_RES_FREE = 4, ++ BFI_IOIM_STS_SQER_NEEDED = 5, ++ BFI_IOIM_STS_PROTO_ERR = 6, ++ BFI_IOIM_STS_UTAG = 7, ++ BFI_IOIM_STS_PATHTOV = 8, ++}; ++ ++#define BFI_IOIM_SNSLEN (256) ++/** ++ * I/O response message ++ */ ++struct bfi_ioim_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 io_tag; /* completed IO tag */ ++ u16 bfa_rport_hndl; /* releated rport handle */ ++ u8 io_status; /* IO completion status */ ++ u8 reuse_io_tag; /* IO tag can be reused */ ++ u16 abort_tag; /* host abort request tag */ ++ u8 scsi_status; /* scsi status from target */ ++ u8 sns_len; /* scsi sense length */ ++ u8 resid_flags; /* IO residue flags */ ++ u8 rsvd_a; ++ u32 residue; /* IO residual length in bytes */ ++ u32 rsvd_b[3]; ++}; ++ ++struct bfi_ioim_abort_req_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 io_tag; /* I/O tag */ ++ u16 abort_tag; /* unique request tag */ ++}; ++ ++/* ++ * Initiator mode task management command interface defines. ++ */ ++ ++enum bfi_tskim_h2i { ++ BFI_TSKIM_H2I_TM_REQ = 1, /* task-mgmt command */ ++ BFI_TSKIM_H2I_ABORT_REQ = 2, /* task-mgmt command */ ++}; ++ ++enum bfi_tskim_i2h { ++ BFI_TSKIM_I2H_TM_RSP = BFA_I2HM(1), ++}; ++ ++struct bfi_tskim_req_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 tsk_tag; /* task management tag */ ++ u16 itn_fhdl; /* itn firmware handle */ ++ lun_t lun; /* LU number */ ++ u8 tm_flags; /* see fcp_tm_cmnd_t */ ++ u8 t_secs; /* Timeout value in seconds */ ++ u8 rsvd[2]; ++}; ++ ++struct bfi_tskim_abortreq_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 tsk_tag; /* task management tag */ ++ u16 rsvd; ++}; ++ ++enum bfi_tskim_status { ++ /* ++ * Following are FCP-4 spec defined status codes, ++ * **DO NOT CHANGE THEM ** ++ */ ++ BFI_TSKIM_STS_OK = 0, ++ BFI_TSKIM_STS_NOT_SUPP = 4, ++ BFI_TSKIM_STS_FAILED = 5, ++ ++ /** ++ * Defined by BFA ++ */ ++ BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */ ++ BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */ ++}; ++ ++struct bfi_tskim_rsp_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 tsk_tag; /* task mgmt cmnd tag */ ++ u8 tsk_status; /* @ref bfi_tskim_status */ ++ u8 rsvd; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_FCPIM_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcxp.h b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h +new file mode 100644 +index 0000000..e0e995a +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_FCXP_H__ ++#define __BFI_FCXP_H__ ++ ++#include "bfi.h" ++ ++#pragma pack(1) ++ ++enum bfi_fcxp_h2i { ++ BFI_FCXP_H2I_SEND_REQ = 1, ++}; ++ ++enum bfi_fcxp_i2h { ++ BFI_FCXP_I2H_SEND_RSP = BFA_I2HM(1), ++}; ++ ++#define BFA_FCXP_MAX_SGES 2 ++ ++/** ++ * FCXP send request structure ++ */ ++struct bfi_fcxp_send_req_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 fcxp_tag; /* driver request tag */ ++ u16 max_frmsz; /* max send frame size */ ++ u16 vf_id; /* vsan tag if applicable */ ++ u16 rport_fw_hndl; /* FW Handle for the remote port */ ++ u8 class; /* FC class used for req/rsp */ ++ u8 rsp_timeout; /* timeout in secs, 0-no response */ ++ u8 cts; /* continue sequence */ ++ u8 lp_tag; /* lport tag */ ++ struct fchs_s fchs; /* request FC header structure */ ++ u32 req_len; /* request payload length */ ++ u32 rsp_maxlen; /* max response length expected */ ++ struct bfi_sge_s req_sge[BFA_FCXP_MAX_SGES]; /* request buf */ ++ struct bfi_sge_s rsp_sge[BFA_FCXP_MAX_SGES]; /* response buf */ ++}; ++ ++/** ++ * FCXP send response structure ++ */ ++struct bfi_fcxp_send_rsp_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 fcxp_tag; /* send request tag */ ++ u8 req_status; /* request status */ ++ u8 rsvd; ++ u32 rsp_len; /* actual response length */ ++ u32 residue_len; /* residual response length */ ++ struct fchs_s fchs; /* response FC header structure */ ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_FCXP_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h +new file mode 100644 +index 0000000..026e9c0 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h +@@ -0,0 +1,202 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_IOC_H__ ++#define __BFI_IOC_H__ ++ ++#include "bfi.h" ++#include ++ ++#pragma pack(1) ++ ++enum bfi_ioc_h2i_msgs { ++ BFI_IOC_H2I_ENABLE_REQ = 1, ++ BFI_IOC_H2I_DISABLE_REQ = 2, ++ BFI_IOC_H2I_GETATTR_REQ = 3, ++ BFI_IOC_H2I_DBG_SYNC = 4, ++ BFI_IOC_H2I_DBG_DUMP = 5, ++}; ++ ++enum bfi_ioc_i2h_msgs { ++ BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1), ++ BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2), ++ BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3), ++ BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4), ++ BFI_IOC_I2H_HBEAT = BFA_I2HM(5), ++}; ++ ++/** ++ * BFI_IOC_H2I_GETATTR_REQ message ++ */ ++struct bfi_ioc_getattr_req_s { ++ struct bfi_mhdr_s mh; ++ union bfi_addr_u attr_addr; ++}; ++ ++struct bfi_ioc_attr_s { ++ wwn_t mfg_wwn; ++ mac_t mfg_mac; ++ u16 rsvd_a; ++ char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; ++ u8 pcie_gen; ++ u8 pcie_lanes_orig; ++ u8 pcie_lanes; ++ u8 rx_bbcredit; /* receive buffer credits */ ++ u32 adapter_prop; /* adapter properties */ ++ u16 maxfrsize; /* max receive frame size */ ++ char asic_rev; ++ u8 rsvd_b; ++ char fw_version[BFA_VERSION_LEN]; ++ char optrom_version[BFA_VERSION_LEN]; ++ struct bfa_mfg_vpd_s vpd; ++}; ++ ++/** ++ * BFI_IOC_I2H_GETATTR_REPLY message ++ */ ++struct bfi_ioc_getattr_reply_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u8 status; /* cfg reply status */ ++ u8 rsvd[3]; ++}; ++ ++/** ++ * Firmware memory page offsets ++ */ ++#define BFI_IOC_SMEM_PG0_CB (0x40) ++#define BFI_IOC_SMEM_PG0_CT (0x180) ++ ++/** ++ * Firmware trace offset ++ */ ++#define BFI_IOC_TRC_OFF (0x4b00) ++#define BFI_IOC_TRC_ENTS 256 ++ ++#define BFI_IOC_FW_SIGNATURE (0xbfadbfad) ++#define BFI_IOC_MD5SUM_SZ 4 ++struct bfi_ioc_image_hdr_s { ++ u32 signature; /* constant signature */ ++ u32 rsvd_a; ++ u32 exec; /* exec vector */ ++ u32 param; /* parameters */ ++ u32 rsvd_b[4]; ++ u32 md5sum[BFI_IOC_MD5SUM_SZ]; ++}; ++ ++/** ++ * BFI_IOC_I2H_READY_EVENT message ++ */ ++struct bfi_ioc_rdy_event_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 init_status; /* init event status */ ++ u8 rsvd[3]; ++}; ++ ++struct bfi_ioc_hbeat_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u32 hb_count; /* current heart beat count */ ++}; ++ ++/** ++ * IOC hardware/firmware state ++ */ ++enum bfi_ioc_state { ++ BFI_IOC_UNINIT = 0, /* not initialized */ ++ BFI_IOC_INITING = 1, /* h/w is being initialized */ ++ BFI_IOC_HWINIT = 2, /* h/w is initialized */ ++ BFI_IOC_CFG = 3, /* IOC configuration in progress */ ++ BFI_IOC_OP = 4, /* IOC is operational */ ++ BFI_IOC_DISABLING = 5, /* IOC is being disabled */ ++ BFI_IOC_DISABLED = 6, /* IOC is disabled */ ++ BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */ ++ BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */ ++ BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */ ++}; ++ ++#define BFI_IOC_ENDIAN_SIG 0x12345678 ++ ++enum { ++ BFI_ADAPTER_TYPE_FC = 0x01, /* FC adapters */ ++ BFI_ADAPTER_TYPE_MK = 0x0f0000, /* adapter type mask */ ++ BFI_ADAPTER_TYPE_SH = 16, /* adapter type shift */ ++ BFI_ADAPTER_NPORTS_MK = 0xff00, /* number of ports mask */ ++ BFI_ADAPTER_NPORTS_SH = 8, /* number of ports shift */ ++ BFI_ADAPTER_SPEED_MK = 0xff, /* adapter speed mask */ ++ BFI_ADAPTER_SPEED_SH = 0, /* adapter speed shift */ ++ BFI_ADAPTER_PROTO = 0x100000, /* prototype adapaters */ ++ BFI_ADAPTER_TTV = 0x200000, /* TTV debug capable */ ++ BFI_ADAPTER_UNSUPP = 0x400000, /* unknown adapter type */ ++}; ++ ++#define BFI_ADAPTER_GETP(__prop,__adap_prop) \ ++ (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \ ++ BFI_ADAPTER_ ## __prop ## _SH) ++#define BFI_ADAPTER_SETP(__prop, __val) \ ++ ((__val) << BFI_ADAPTER_ ## __prop ## _SH) ++#define BFI_ADAPTER_IS_PROTO(__adap_type) \ ++ ((__adap_type) & BFI_ADAPTER_PROTO) ++#define BFI_ADAPTER_IS_TTV(__adap_type) \ ++ ((__adap_type) & BFI_ADAPTER_TTV) ++#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \ ++ ((__adap_type) & BFI_ADAPTER_UNSUPP) ++#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \ ++ ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \ ++ BFI_ADAPTER_UNSUPP)) ++ ++/** ++ * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages ++ */ ++struct bfi_ioc_ctrl_req_s { ++ struct bfi_mhdr_s mh; ++ u8 ioc_class; ++ u8 rsvd[3]; ++}; ++ ++/** ++ * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages ++ */ ++struct bfi_ioc_ctrl_reply_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u8 status; /* enable/disable status */ ++ u8 rsvd[3]; ++}; ++ ++#define BFI_IOC_MSGSZ 8 ++/** ++ * H2I Messages ++ */ ++union bfi_ioc_h2i_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_ioc_ctrl_req_s enable_req; ++ struct bfi_ioc_ctrl_req_s disable_req; ++ struct bfi_ioc_getattr_req_s getattr_req; ++ u32 mboxmsg[BFI_IOC_MSGSZ]; ++}; ++ ++/** ++ * I2H Messages ++ */ ++union bfi_ioc_i2h_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_ioc_rdy_event_s rdy_event; ++ u32 mboxmsg[BFI_IOC_MSGSZ]; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_IOC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_iocfc.h b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h +new file mode 100644 +index 0000000..c3760df +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h +@@ -0,0 +1,177 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_IOCFC_H__ ++#define __BFI_IOCFC_H__ ++ ++#include "bfi.h" ++#include ++#include ++#include ++ ++#pragma pack(1) ++ ++enum bfi_iocfc_h2i_msgs { ++ BFI_IOCFC_H2I_CFG_REQ = 1, ++ BFI_IOCFC_H2I_GET_STATS_REQ = 2, ++ BFI_IOCFC_H2I_CLEAR_STATS_REQ = 3, ++ BFI_IOCFC_H2I_SET_INTR_REQ = 4, ++ BFI_IOCFC_H2I_UPDATEQ_REQ = 5, ++}; ++ ++enum bfi_iocfc_i2h_msgs { ++ BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1), ++ BFI_IOCFC_I2H_GET_STATS_RSP = BFA_I2HM(2), ++ BFI_IOCFC_I2H_CLEAR_STATS_RSP = BFA_I2HM(3), ++ BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(5), ++}; ++ ++struct bfi_iocfc_cfg_s { ++ u8 num_cqs; /* Number of CQs to be used */ ++ u8 sense_buf_len; /* SCSI sense length */ ++ u8 trunk_enabled; /* port trunking enabled */ ++ u8 trunk_ports; /* trunk ports bit map */ ++ u32 endian_sig; /* endian signature of host */ ++ ++ /** ++ * Request and response circular queue base addresses, size and ++ * shadow index pointers. ++ */ ++ union bfi_addr_u req_cq_ba[BFI_IOC_MAX_CQS]; ++ union bfi_addr_u req_shadow_ci[BFI_IOC_MAX_CQS]; ++ u16 req_cq_elems[BFI_IOC_MAX_CQS]; ++ union bfi_addr_u rsp_cq_ba[BFI_IOC_MAX_CQS]; ++ union bfi_addr_u rsp_shadow_pi[BFI_IOC_MAX_CQS]; ++ u16 rsp_cq_elems[BFI_IOC_MAX_CQS]; ++ ++ union bfi_addr_u stats_addr; /* DMA-able address for stats */ ++ union bfi_addr_u cfgrsp_addr; /* config response dma address */ ++ union bfi_addr_u ioim_snsbase; /* IO sense buffer base address */ ++ struct bfa_iocfc_intr_attr_s intr_attr; /* IOC interrupt attributes */ ++}; ++ ++/** ++ * Boot target wwn information for this port. This contains either the stored ++ * or discovered boot target port wwns for the port. ++ */ ++struct bfi_iocfc_bootwwns { ++ wwn_t wwn[BFA_BOOT_BOOTLUN_MAX]; ++ u8 nwwns; ++ u8 rsvd[7]; ++}; ++ ++struct bfi_iocfc_cfgrsp_s { ++ struct bfa_iocfc_fwcfg_s fwcfg; ++ struct bfa_iocfc_intr_attr_s intr_attr; ++ struct bfi_iocfc_bootwwns bootwwns; ++}; ++ ++/** ++ * BFI_IOCFC_H2I_CFG_REQ message ++ */ ++struct bfi_iocfc_cfg_req_s { ++ struct bfi_mhdr_s mh; ++ union bfi_addr_u ioc_cfg_dma_addr; ++}; ++ ++/** ++ * BFI_IOCFC_I2H_CFG_REPLY message ++ */ ++struct bfi_iocfc_cfg_reply_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u8 cfg_success; /* cfg reply status */ ++ u8 lpu_bm; /* LPUs assigned for this IOC */ ++ u8 rsvd[2]; ++}; ++ ++/** ++ * BFI_IOCFC_H2I_GET_STATS_REQ & BFI_IOCFC_H2I_CLEAR_STATS_REQ messages ++ */ ++struct bfi_iocfc_stats_req_s { ++ struct bfi_mhdr_s mh; /* msg header */ ++ u32 msgtag; /* msgtag for reply */ ++}; ++ ++/** ++ * BFI_IOCFC_I2H_GET_STATS_RSP & BFI_IOCFC_I2H_CLEAR_STATS_RSP messages ++ */ ++struct bfi_iocfc_stats_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 status; /* reply status */ ++ u8 rsvd[3]; ++ u32 msgtag; /* msgtag for reply */ ++}; ++ ++/** ++ * BFI_IOCFC_H2I_SET_INTR_REQ message ++ */ ++struct bfi_iocfc_set_intr_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 coalesce; /* enable intr coalescing*/ ++ u8 rsvd[3]; ++ u16 delay; /* delay timer 0..1125us */ ++ u16 latency; /* latency timer 0..225us */ ++}; ++ ++/** ++ * BFI_IOCFC_H2I_UPDATEQ_REQ message ++ */ ++struct bfi_iocfc_updateq_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u32 reqq_ba; /* reqq base addr */ ++ u32 rspq_ba; /* rspq base addr */ ++ u32 reqq_sci; /* reqq shadow ci */ ++ u32 rspq_spi; /* rspq shadow pi */ ++}; ++ ++/** ++ * BFI_IOCFC_I2H_UPDATEQ_RSP message ++ */ ++struct bfi_iocfc_updateq_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 status; /* updateq status */ ++ u8 rsvd[3]; ++}; ++ ++/** ++ * H2I Messages ++ */ ++union bfi_iocfc_h2i_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_iocfc_cfg_req_s cfg_req; ++ struct bfi_iocfc_stats_req_s stats_get; ++ struct bfi_iocfc_stats_req_s stats_clr; ++ struct bfi_iocfc_updateq_req_s updateq_req; ++ u32 mboxmsg[BFI_IOC_MSGSZ]; ++}; ++ ++/** ++ * I2H Messages ++ */ ++union bfi_iocfc_i2h_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_iocfc_cfg_reply_s cfg_reply; ++ struct bfi_iocfc_stats_rsp_s stats_get_rsp; ++ struct bfi_iocfc_stats_rsp_s stats_clr_rsp; ++ struct bfi_iocfc_updateq_rsp_s updateq_rsp; ++ u32 mboxmsg[BFI_IOC_MSGSZ]; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_IOCFC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_lport.h b/drivers/scsi/bfa/include/bfi/bfi_lport.h +new file mode 100644 +index 0000000..2901061 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_lport.h +@@ -0,0 +1,89 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_LPORT_H__ ++#define __BFI_LPORT_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum bfi_lport_h2i_msgs { ++ BFI_LPORT_H2I_CREATE_REQ = 1, ++ BFI_LPORT_H2I_DELETE_REQ = 2, ++}; ++ ++enum bfi_lport_i2h_msgs { ++ BFI_LPORT_I2H_CREATE_RSP = BFA_I2HM(1), ++ BFI_LPORT_I2H_DELETE_RSP = BFA_I2HM(2), ++ BFI_LPORT_I2H_ONLINE = BFA_I2HM(3), ++ BFI_LPORT_I2H_OFFLINE = BFA_I2HM(4), ++}; ++ ++#define BFI_LPORT_MAX_SYNNAME 64 ++ ++enum bfi_lport_role_e { ++ BFI_LPORT_ROLE_FCPIM = 1, ++ BFI_LPORT_ROLE_FCPTM = 2, ++ BFI_LPORT_ROLE_IPFC = 4, ++}; ++ ++struct bfi_lport_create_req_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 fabric_fwhdl; /* parent fabric instance */ ++ u8 roles; /* lport FC-4 roles */ ++ u8 rsvd; ++ wwn_t pwwn; /* port name */ ++ wwn_t nwwn; /* node name */ ++ u8 symname[BFI_LPORT_MAX_SYNNAME]; ++}; ++ ++struct bfi_lport_create_rsp_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u8 status; /* lport creation status */ ++ u8 rsvd[3]; ++}; ++ ++struct bfi_lport_delete_req_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 fw_handle; /* firmware lport handle */ ++ u16 rsvd; ++}; ++ ++struct bfi_lport_delete_rsp_s { ++ bfi_mhdr_t mh; /* common msg header */ ++ u16 bfa_handle; /* host lport handle */ ++ u8 status; /* lport deletion status */ ++ u8 rsvd; ++}; ++ ++union bfi_lport_h2i_msg_u { ++ bfi_msg_t *msg; ++ struct bfi_lport_create_req_s *create_req; ++ struct bfi_lport_delete_req_s *delete_req; ++}; ++ ++union bfi_lport_i2h_msg_u { ++ bfi_msg_t *msg; ++ struct bfi_lport_create_rsp_s *create_rsp; ++ struct bfi_lport_delete_rsp_s *delete_rsp; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_LPORT_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h +new file mode 100644 +index 0000000..414b0e3 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_LPS_H__ ++#define __BFI_LPS_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum bfi_lps_h2i_msgs { ++ BFI_LPS_H2I_LOGIN_REQ = 1, ++ BFI_LPS_H2I_LOGOUT_REQ = 2, ++}; ++ ++enum bfi_lps_i2h_msgs { ++ BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), ++ BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), ++}; ++ ++struct bfi_lps_login_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 lp_tag; ++ u8 alpa; ++ u16 pdu_size; ++ wwn_t pwwn; ++ wwn_t nwwn; ++ u8 fdisc; ++ u8 auth_en; ++ u8 rsvd[2]; ++}; ++ ++struct bfi_lps_login_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 lp_tag; ++ u8 status; ++ u8 lsrjt_rsn; ++ u8 lsrjt_expl; ++ wwn_t port_name; ++ wwn_t node_name; ++ u16 bb_credit; ++ u8 f_port; ++ u8 npiv_en; ++ u32 lp_pid : 24; ++ u32 auth_req : 8; ++ mac_t lp_mac; ++ mac_t fcf_mac; ++ u8 ext_status; ++ u8 brcd_switch;/* attached peer is brcd switch */ ++}; ++ ++struct bfi_lps_logout_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 lp_tag; ++ u8 rsvd[3]; ++ wwn_t port_name; ++}; ++ ++struct bfi_lps_logout_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 lp_tag; ++ u8 status; ++ u8 rsvd[2]; ++}; ++ ++union bfi_lps_h2i_msg_u { ++ struct bfi_mhdr_s *msg; ++ struct bfi_lps_login_req_s *login_req; ++ struct bfi_lps_logout_req_s *logout_req; ++}; ++ ++union bfi_lps_i2h_msg_u { ++ struct bfi_msg_s *msg; ++ struct bfi_lps_login_rsp_s *login_rsp; ++ struct bfi_lps_logout_rsp_s *logout_rsp; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_LPS_H__ */ ++ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_port.h b/drivers/scsi/bfa/include/bfi/bfi_port.h +new file mode 100644 +index 0000000..3ec3bea +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_port.h +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFI_PORT_H__ ++#define __BFI_PORT_H__ ++ ++#include ++#include ++ ++#pragma pack(1) ++ ++enum bfi_port_h2i { ++ BFI_PORT_H2I_ENABLE_REQ = (1), ++ BFI_PORT_H2I_DISABLE_REQ = (2), ++ BFI_PORT_H2I_GET_STATS_REQ = (3), ++ BFI_PORT_H2I_CLEAR_STATS_REQ = (4), ++}; ++ ++enum bfi_port_i2h { ++ BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1), ++ BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2), ++ BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3), ++ BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), ++}; ++ ++/** ++ * Generic REQ type ++ */ ++struct bfi_port_generic_req_s { ++ struct bfi_mhdr_s mh; /* msg header */ ++ u32 msgtag; /* msgtag for reply */ ++ u32 rsvd; ++}; ++ ++/** ++ * Generic RSP type ++ */ ++struct bfi_port_generic_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 status; /* port enable status */ ++ u8 rsvd[3]; ++ u32 msgtag; /* msgtag for reply */ ++}; ++ ++/** ++ * @todo ++ * BFI_PORT_H2I_ENABLE_REQ ++ */ ++ ++/** ++ * @todo ++ * BFI_PORT_I2H_ENABLE_RSP ++ */ ++ ++/** ++ * BFI_PORT_H2I_DISABLE_REQ ++ */ ++ ++/** ++ * BFI_PORT_I2H_DISABLE_RSP ++ */ ++ ++/** ++ * BFI_PORT_H2I_GET_STATS_REQ ++ */ ++struct bfi_port_get_stats_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ union bfi_addr_u dma_addr; ++}; ++ ++/** ++ * BFI_PORT_I2H_GET_STATS_RSP ++ */ ++ ++/** ++ * BFI_PORT_H2I_CLEAR_STATS_REQ ++ */ ++ ++/** ++ * BFI_PORT_I2H_CLEAR_STATS_RSP ++ */ ++ ++union bfi_port_h2i_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_port_generic_req_s enable_req; ++ struct bfi_port_generic_req_s disable_req; ++ struct bfi_port_get_stats_req_s getstats_req; ++ struct bfi_port_generic_req_s clearstats_req; ++}; ++ ++union bfi_port_i2h_msg_u { ++ struct bfi_mhdr_s mh; ++ struct bfi_port_generic_rsp_s enable_rsp; ++ struct bfi_port_generic_rsp_s disable_rsp; ++ struct bfi_port_generic_rsp_s getstats_rsp; ++ struct bfi_port_generic_rsp_s clearstats_rsp; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_PORT_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h +new file mode 100644 +index 0000000..c96d246 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h +@@ -0,0 +1,184 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFI_PPORT_H__ ++#define __BFI_PPORT_H__ ++ ++#include ++#include ++ ++#pragma pack(1) ++ ++enum bfi_pport_h2i { ++ BFI_PPORT_H2I_ENABLE_REQ = (1), ++ BFI_PPORT_H2I_DISABLE_REQ = (2), ++ BFI_PPORT_H2I_GET_STATS_REQ = (3), ++ BFI_PPORT_H2I_CLEAR_STATS_REQ = (4), ++ BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5), ++ BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6), ++ BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7), ++ BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8), ++ BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9), ++}; ++ ++enum bfi_pport_i2h { ++ BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1), ++ BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2), ++ BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3), ++ BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), ++ BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5), ++ BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6), ++ BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7), ++ BFI_PPORT_I2H_EVENT = BFA_I2HM(8), ++ BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9), ++ BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10), ++}; ++ ++/** ++ * Generic REQ type ++ */ ++struct bfi_pport_generic_req_s { ++ struct bfi_mhdr_s mh; /* msg header */ ++ u32 msgtag; /* msgtag for reply */ ++}; ++ ++/** ++ * Generic RSP type ++ */ ++struct bfi_pport_generic_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 status; /* port enable status */ ++ u8 rsvd[3]; ++ u32 msgtag; /* msgtag for reply */ ++}; ++ ++/** ++ * BFI_PPORT_H2I_ENABLE_REQ ++ */ ++struct bfi_pport_enable_req_s { ++ struct bfi_mhdr_s mh; /* msg header */ ++ u32 rsvd1; ++ wwn_t nwwn; /* node wwn of physical port */ ++ wwn_t pwwn; /* port wwn of physical port */ ++ struct bfa_pport_cfg_s port_cfg; /* port configuration */ ++ union bfi_addr_u stats_dma_addr; /* DMA address for stats */ ++ u32 msgtag; /* msgtag for reply */ ++ u32 rsvd2; ++}; ++ ++/** ++ * BFI_PPORT_I2H_ENABLE_RSP ++ */ ++#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_DISABLE_REQ ++ */ ++#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s ++ ++/** ++ * BFI_PPORT_I2H_DISABLE_RSP ++ */ ++#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_GET_STATS_REQ ++ */ ++#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s ++ ++/** ++ * BFI_PPORT_I2H_GET_STATS_RSP ++ */ ++#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_CLEAR_STATS_REQ ++ */ ++#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s ++ ++/** ++ * BFI_PPORT_I2H_CLEAR_STATS_RSP ++ */ ++#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_GET_QOS_STATS_REQ ++ */ ++#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s ++ ++/** ++ * BFI_PPORT_H2I_GET_QOS_STATS_RSP ++ */ ++#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ ++ */ ++#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s ++ ++/** ++ * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP ++ */ ++#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s ++ ++/** ++ * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ ++ */ ++struct bfi_pport_set_svc_params_req_s { ++ struct bfi_mhdr_s mh; /* msg header */ ++ u16 tx_bbcredit; /* Tx credits */ ++ u16 rsvd; ++}; ++ ++/** ++ * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP ++ */ ++ ++/** ++ * BFI_PPORT_I2H_EVENT ++ */ ++struct bfi_pport_event_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ struct bfa_pport_link_s link_state; ++}; ++ ++union bfi_pport_h2i_msg_u { ++ struct bfi_mhdr_s *mhdr; ++ struct bfi_pport_enable_req_s *penable; ++ struct bfi_pport_generic_req_s *pdisable; ++ struct bfi_pport_generic_req_s *pgetstats; ++ struct bfi_pport_generic_req_s *pclearstats; ++ struct bfi_pport_set_svc_params_req_s *psetsvcparams; ++ struct bfi_pport_get_qos_stats_req_s *pgetqosstats; ++ struct bfi_pport_generic_req_s *pclearqosstats; ++}; ++ ++union bfi_pport_i2h_msg_u { ++ struct bfi_msg_s *msg; ++ struct bfi_pport_generic_rsp_s *enable_rsp; ++ struct bfi_pport_disable_rsp_s *disable_rsp; ++ struct bfi_pport_generic_rsp_s *getstats_rsp; ++ struct bfi_pport_clear_stats_rsp_s *clearstats_rsp; ++ struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp; ++ struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp; ++ struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp; ++ struct bfi_pport_event_s *event; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_PPORT_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_rport.h b/drivers/scsi/bfa/include/bfi/bfi_rport.h +new file mode 100644 +index 0000000..3520f55 +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_rport.h +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_RPORT_H__ ++#define __BFI_RPORT_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum bfi_rport_h2i_msgs { ++ BFI_RPORT_H2I_CREATE_REQ = 1, ++ BFI_RPORT_H2I_DELETE_REQ = 2, ++ BFI_RPORT_H2I_SET_SPEED_REQ = 3, ++}; ++ ++enum bfi_rport_i2h_msgs { ++ BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1), ++ BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2), ++ BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3), ++}; ++ ++struct bfi_rport_create_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* host rport handle */ ++ u16 max_frmsz; /* max rcv pdu size */ ++ u32 pid : 24, /* remote port ID */ ++ lp_tag : 8; /* local port tag */ ++ u32 local_pid : 24, /* local port ID */ ++ cisc : 8; ++ u8 fc_class; /* supported FC classes */ ++ u8 vf_en; /* virtual fabric enable */ ++ u16 vf_id; /* virtual fabric ID */ ++}; ++ ++struct bfi_rport_create_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u8 status; /* rport creation status */ ++ u8 rsvd[3]; ++ u16 bfa_handle; /* host rport handle */ ++ u16 fw_handle; /* firmware rport handle */ ++ struct bfa_rport_qos_attr_s qos_attr; /* QoS Attributes */ ++}; ++ ++struct bfa_rport_speed_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 fw_handle; /* firmware rport handle */ ++ u8 speed; /*! rport's speed via RPSC */ ++ u8 rsvd; ++}; ++ ++struct bfi_rport_delete_req_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 fw_handle; /* firmware rport handle */ ++ u16 rsvd; ++}; ++ ++struct bfi_rport_delete_rsp_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* host rport handle */ ++ u8 status; /* rport deletion status */ ++ u8 rsvd; ++}; ++ ++struct bfi_rport_qos_scn_s { ++ struct bfi_mhdr_s mh; /* common msg header */ ++ u16 bfa_handle; /* host rport handle */ ++ u16 rsvd; ++ struct bfa_rport_qos_attr_s old_qos_attr; /* Old QoS Attributes */ ++ struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */ ++}; ++ ++union bfi_rport_h2i_msg_u { ++ struct bfi_msg_s *msg; ++ struct bfi_rport_create_req_s *create_req; ++ struct bfi_rport_delete_req_s *delete_req; ++ struct bfi_rport_speed_req_s *speed_req; ++}; ++ ++union bfi_rport_i2h_msg_u { ++ struct bfi_msg_s *msg; ++ struct bfi_rport_create_rsp_s *create_rsp; ++ struct bfi_rport_delete_rsp_s *delete_rsp; ++ struct bfi_rport_qos_scn_s *qos_scn_evt; ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_RPORT_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/bfi/bfi_uf.h b/drivers/scsi/bfa/include/bfi/bfi_uf.h +new file mode 100644 +index 0000000..f328a9e +--- /dev/null ++++ b/drivers/scsi/bfa/include/bfi/bfi_uf.h +@@ -0,0 +1,52 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFI_UF_H__ ++#define __BFI_UF_H__ ++ ++#include "bfi.h" ++ ++#pragma pack(1) ++ ++enum bfi_uf_h2i { ++ BFI_UF_H2I_BUF_POST = 1, ++}; ++ ++enum bfi_uf_i2h { ++ BFI_UF_I2H_FRM_RCVD = BFA_I2HM(1), ++}; ++ ++#define BFA_UF_MAX_SGES 2 ++ ++struct bfi_uf_buf_post_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 buf_tag; /* buffer tag */ ++ u16 buf_len; /* total buffer length */ ++ struct bfi_sge_s sge[BFA_UF_MAX_SGES]; /* buffer DMA SGEs */ ++}; ++ ++struct bfi_uf_frm_rcvd_s { ++ struct bfi_mhdr_s mh; /* Common msg header */ ++ u16 buf_tag; /* buffer tag */ ++ u16 rsvd; ++ u16 frm_len; /* received frame length */ ++ u16 xfr_len; /* tranferred length */ ++}; ++ ++#pragma pack() ++ ++#endif /* __BFI_UF_H__ */ +diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h +new file mode 100644 +index 0000000..43ba706 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_cna_trcmod.h CNA trace modules ++ */ ++ ++#ifndef __BFA_CNA_TRCMOD_H__ ++#define __BFA_CNA_TRCMOD_H__ ++ ++#include ++ ++/* ++ * !!! Only append to the enums defined here to avoid any versioning ++ * !!! needed between trace utility and driver version ++ */ ++enum { ++ BFA_TRC_CNA_CEE = 1, ++ BFA_TRC_CNA_PORT = 2, ++}; ++ ++#endif /* __BFA_CNA_TRCMOD_H__ */ +diff --git a/drivers/scsi/bfa/include/cna/cee/bfa_cee.h b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h +new file mode 100644 +index 0000000..77f297f +--- /dev/null ++++ b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h +@@ -0,0 +1,77 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_CEE_H__ ++#define __BFA_CEE_H__ ++ ++#include ++#include ++#include ++#include ++ ++typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, bfa_status_t status); ++typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, bfa_status_t status); ++typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, bfa_status_t status); ++typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, bfa_status_t status); ++ ++struct bfa_cee_cbfn_s { ++ bfa_cee_get_attr_cbfn_t get_attr_cbfn; ++ void *get_attr_cbarg; ++ bfa_cee_get_stats_cbfn_t get_stats_cbfn; ++ void *get_stats_cbarg; ++ bfa_cee_reset_stats_cbfn_t reset_stats_cbfn; ++ void *reset_stats_cbarg; ++}; ++ ++struct bfa_cee_s { ++ void *dev; ++ bfa_boolean_t get_attr_pending; ++ bfa_boolean_t get_stats_pending; ++ bfa_boolean_t reset_stats_pending; ++ bfa_status_t get_attr_status; ++ bfa_status_t get_stats_status; ++ bfa_status_t reset_stats_status; ++ struct bfa_cee_cbfn_s cbfn; ++ struct bfa_ioc_hbfail_notify_s hbfail; ++ struct bfa_trc_mod_s *trcmod; ++ struct bfa_log_mod_s *logmod; ++ struct bfa_cee_attr_s *attr; ++ struct bfa_cee_stats_s *stats; ++ struct bfa_dma_s attr_dma; ++ struct bfa_dma_s stats_dma; ++ struct bfa_ioc_s *ioc; ++ struct bfa_mbox_cmd_s get_cfg_mb; ++ struct bfa_mbox_cmd_s get_stats_mb; ++ struct bfa_mbox_cmd_s reset_stats_mb; ++}; ++ ++u32 bfa_cee_meminfo(void); ++void bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, ++ u64 dma_pa); ++void bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev, ++ struct bfa_trc_mod_s *trcmod, ++ struct bfa_log_mod_s *logmod); ++void bfa_cee_detach(struct bfa_cee_s *cee); ++bfa_status_t bfa_cee_get_attr(struct bfa_cee_s *cee, ++ struct bfa_cee_attr_s *attr, ++ bfa_cee_get_attr_cbfn_t cbfn, void *cbarg); ++bfa_status_t bfa_cee_get_stats(struct bfa_cee_s *cee, ++ struct bfa_cee_stats_s *stats, ++ bfa_cee_get_stats_cbfn_t cbfn, void *cbarg); ++bfa_status_t bfa_cee_reset_stats(struct bfa_cee_s *cee, ++ bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg); ++#endif /* __BFA_CEE_H__ */ +diff --git a/drivers/scsi/bfa/include/cna/port/bfa_port.h b/drivers/scsi/bfa/include/cna/port/bfa_port.h +new file mode 100644 +index 0000000..7cbf17d +--- /dev/null ++++ b/drivers/scsi/bfa/include/cna/port/bfa_port.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_PORT_H__ ++#define __BFA_PORT_H__ ++ ++#include ++#include ++#include ++#include ++ ++typedef void (*bfa_port_stats_cbfn_t) (void *dev, bfa_status_t status); ++typedef void (*bfa_port_endis_cbfn_t) (void *dev, bfa_status_t status); ++ ++struct bfa_port_s { ++ void *dev; ++ struct bfa_ioc_s *ioc; ++ struct bfa_trc_mod_s *trcmod; ++ struct bfa_log_mod_s *logmod; ++ u32 msgtag; ++ bfa_boolean_t stats_busy; ++ struct bfa_mbox_cmd_s stats_mb; ++ bfa_port_stats_cbfn_t stats_cbfn; ++ void *stats_cbarg; ++ bfa_status_t stats_status; ++ union bfa_pport_stats_u *stats; ++ struct bfa_dma_s stats_dma; ++ bfa_boolean_t endis_pending; ++ struct bfa_mbox_cmd_s endis_mb; ++ bfa_port_endis_cbfn_t endis_cbfn; ++ void *endis_cbarg; ++ bfa_status_t endis_status; ++ struct bfa_ioc_hbfail_notify_s hbfail; ++}; ++ ++void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, ++ void *dev, struct bfa_trc_mod_s *trcmod, ++ struct bfa_log_mod_s *logmod); ++void bfa_port_detach(struct bfa_port_s *port); ++void bfa_port_hbfail(void *arg); ++ ++bfa_status_t bfa_port_get_stats(struct bfa_port_s *port, ++ union bfa_pport_stats_u *stats, ++ bfa_port_stats_cbfn_t cbfn, void *cbarg); ++bfa_status_t bfa_port_clear_stats(struct bfa_port_s *port, ++ bfa_port_stats_cbfn_t cbfn, void *cbarg); ++bfa_status_t bfa_port_enable(struct bfa_port_s *port, ++ bfa_port_endis_cbfn_t cbfn, void *cbarg); ++bfa_status_t bfa_port_disable(struct bfa_port_s *port, ++ bfa_port_endis_cbfn_t cbfn, void *cbarg); ++u32 bfa_port_meminfo(void); ++void bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, ++ u64 dma_pa); ++ ++#endif /* __BFA_PORT_H__ */ +diff --git a/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h +new file mode 100644 +index 0000000..1563ee5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved. ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __ETHPORT_DEFS_H__ ++#define __ETHPORT_DEFS_H__ ++ ++struct bnad_drv_stats { ++ u64 netif_queue_stop; ++ u64 netif_queue_wakeup; ++ u64 tso4; ++ u64 tso6; ++ u64 tso_err; ++ u64 tcpcsum_offload; ++ u64 udpcsum_offload; ++ u64 csum_help; ++ u64 csum_help_err; ++ ++ u64 hw_stats_updates; ++ u64 netif_rx_schedule; ++ u64 netif_rx_complete; ++ u64 netif_rx_dropped; ++}; ++#endif +diff --git a/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h +new file mode 100644 +index 0000000..eb75480 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h +@@ -0,0 +1,218 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved. ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __PHYPORT_DEFS_H__ ++#define __PHYPORT_DEFS_H__ ++ ++#define BNA_TXF_ID_MAX 64 ++#define BNA_RXF_ID_MAX 64 ++ ++/* ++ * Statistics ++ */ ++ ++/* ++ * TxF Frame Statistics ++ */ ++struct bna_stats_txf { ++ u64 ucast_octets; ++ u64 ucast; ++ u64 ucast_vlan; ++ ++ u64 mcast_octets; ++ u64 mcast; ++ u64 mcast_vlan; ++ ++ u64 bcast_octets; ++ u64 bcast; ++ u64 bcast_vlan; ++ ++ u64 errors; ++ u64 filter_vlan; /* frames filtered due to VLAN */ ++ u64 filter_mac_sa; /* frames filtered due to SA check */ ++}; ++ ++/* ++ * RxF Frame Statistics ++ */ ++struct bna_stats_rxf { ++ u64 ucast_octets; ++ u64 ucast; ++ u64 ucast_vlan; ++ ++ u64 mcast_octets; ++ u64 mcast; ++ u64 mcast_vlan; ++ ++ u64 bcast_octets; ++ u64 bcast; ++ u64 bcast_vlan; ++ u64 frame_drops; ++}; ++ ++/* ++ * FC Tx Frame Statistics ++ */ ++struct bna_stats_fc_tx { ++ u64 txf_ucast_octets; ++ u64 txf_ucast; ++ u64 txf_ucast_vlan; ++ ++ u64 txf_mcast_octets; ++ u64 txf_mcast; ++ u64 txf_mcast_vlan; ++ ++ u64 txf_bcast_octets; ++ u64 txf_bcast; ++ u64 txf_bcast_vlan; ++ ++ u64 txf_parity_errors; ++ u64 txf_timeout; ++ u64 txf_fid_parity_errors; ++}; ++ ++/* ++ * FC Rx Frame Statistics ++ */ ++struct bna_stats_fc_rx { ++ u64 rxf_ucast_octets; ++ u64 rxf_ucast; ++ u64 rxf_ucast_vlan; ++ ++ u64 rxf_mcast_octets; ++ u64 rxf_mcast; ++ u64 rxf_mcast_vlan; ++ ++ u64 rxf_bcast_octets; ++ u64 rxf_bcast; ++ u64 rxf_bcast_vlan; ++}; ++ ++/* ++ * RAD Frame Statistics ++ */ ++struct cna_stats_rad { ++ u64 rx_frames; ++ u64 rx_octets; ++ u64 rx_vlan_frames; ++ ++ u64 rx_ucast; ++ u64 rx_ucast_octets; ++ u64 rx_ucast_vlan; ++ ++ u64 rx_mcast; ++ u64 rx_mcast_octets; ++ u64 rx_mcast_vlan; ++ ++ u64 rx_bcast; ++ u64 rx_bcast_octets; ++ u64 rx_bcast_vlan; ++ ++ u64 rx_drops; ++}; ++ ++/* ++ * BPC Tx Registers ++ */ ++struct cna_stats_bpc_tx { ++ u64 tx_pause[8]; ++ u64 tx_zero_pause[8]; /* Pause cancellation */ ++ u64 tx_first_pause[8]; /* Pause initiation rather ++ *than retention */ ++}; ++ ++/* ++ * BPC Rx Registers ++ */ ++struct cna_stats_bpc_rx { ++ u64 rx_pause[8]; ++ u64 rx_zero_pause[8]; /* Pause cancellation */ ++ u64 rx_first_pause[8]; /* Pause initiation rather ++ *than retention */ ++}; ++ ++/* ++ * MAC Rx Statistics ++ */ ++struct cna_stats_mac_rx { ++ u64 frame_64; /* both rx and tx counter */ ++ u64 frame_65_127; /* both rx and tx counter */ ++ u64 frame_128_255; /* both rx and tx counter */ ++ u64 frame_256_511; /* both rx and tx counter */ ++ u64 frame_512_1023; /* both rx and tx counter */ ++ u64 frame_1024_1518; /* both rx and tx counter */ ++ u64 frame_1518_1522; /* both rx and tx counter */ ++ u64 rx_bytes; ++ u64 rx_packets; ++ u64 rx_fcs_error; ++ u64 rx_multicast; ++ u64 rx_broadcast; ++ u64 rx_control_frames; ++ u64 rx_pause; ++ u64 rx_unknown_opcode; ++ u64 rx_alignment_error; ++ u64 rx_frame_length_error; ++ u64 rx_code_error; ++ u64 rx_carrier_sense_error; ++ u64 rx_undersize; ++ u64 rx_oversize; ++ u64 rx_fragments; ++ u64 rx_jabber; ++ u64 rx_drop; ++}; ++ ++/* ++ * MAC Tx Statistics ++ */ ++struct cna_stats_mac_tx { ++ u64 tx_bytes; ++ u64 tx_packets; ++ u64 tx_multicast; ++ u64 tx_broadcast; ++ u64 tx_pause; ++ u64 tx_deferral; ++ u64 tx_excessive_deferral; ++ u64 tx_single_collision; ++ u64 tx_muliple_collision; ++ u64 tx_late_collision; ++ u64 tx_excessive_collision; ++ u64 tx_total_collision; ++ u64 tx_pause_honored; ++ u64 tx_drop; ++ u64 tx_jabber; ++ u64 tx_fcs_error; ++ u64 tx_control_frame; ++ u64 tx_oversize; ++ u64 tx_undersize; ++ u64 tx_fragments; ++}; ++ ++/* ++ * Complete statistics ++ */ ++struct bna_stats { ++ struct cna_stats_mac_rx mac_rx_stats; ++ struct cna_stats_bpc_rx bpc_rx_stats; ++ struct cna_stats_rad rad_stats; ++ struct bna_stats_fc_rx fc_rx_stats; ++ struct cna_stats_mac_tx mac_tx_stats; ++ struct cna_stats_bpc_tx bpc_tx_stats; ++ struct bna_stats_fc_tx fc_tx_stats; ++ struct bna_stats_rxf rxf_stats[BNA_TXF_ID_MAX]; ++ struct bna_stats_txf txf_stats[BNA_RXF_ID_MAX]; ++}; ++ ++#endif +diff --git a/drivers/scsi/bfa/include/cs/bfa_checksum.h b/drivers/scsi/bfa/include/cs/bfa_checksum.h +new file mode 100644 +index 0000000..af8c1d5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_checksum.h +@@ -0,0 +1,60 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_checksum.h BFA checksum utilities ++ */ ++ ++#ifndef __BFA_CHECKSUM_H__ ++#define __BFA_CHECKSUM_H__ ++ ++static inline u32 ++bfa_checksum_u32(u32 *buf, int sz) ++{ ++ int i, m = sz >> 2; ++ u32 sum = 0; ++ ++ for (i = 0; i < m; i++) ++ sum ^= buf[i]; ++ ++ return (sum); ++} ++ ++static inline u16 ++bfa_checksum_u16(u16 *buf, int sz) ++{ ++ int i, m = sz >> 1; ++ u16 sum = 0; ++ ++ for (i = 0; i < m; i++) ++ sum ^= buf[i]; ++ ++ return (sum); ++} ++ ++static inline u8 ++bfa_checksum_u8(u8 *buf, int sz) ++{ ++ int i; ++ u8 sum = 0; ++ ++ for (i = 0; i < sz; i++) ++ sum ^= buf[i]; ++ ++ return (sum); ++} ++#endif +diff --git a/drivers/scsi/bfa/include/cs/bfa_debug.h b/drivers/scsi/bfa/include/cs/bfa_debug.h +new file mode 100644 +index 0000000..441be86 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_debug.h +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_debug.h BFA debug interfaces ++ */ ++ ++#ifndef __BFA_DEBUG_H__ ++#define __BFA_DEBUG_H__ ++ ++#define bfa_assert(__cond) do { \ ++ if (!(__cond)) \ ++ bfa_panic(__LINE__, __FILE__, #__cond); \ ++} while (0) ++ ++#define bfa_sm_fault(__mod, __event) do { \ ++ bfa_sm_panic((__mod)->logm, __LINE__, __FILE__, __event); \ ++} while (0) ++ ++#ifndef BFA_PERF_BUILD ++#define bfa_assert_fp(__cond) bfa_assert(__cond) ++#else ++#define bfa_assert_fp(__cond) ++#endif ++ ++struct bfa_log_mod_s; ++void bfa_panic(int line, char *file, char *panicstr); ++void bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event); ++ ++#endif /* __BFA_DEBUG_H__ */ +diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h +new file mode 100644 +index 0000000..761cbe2 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_log.h +@@ -0,0 +1,184 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_log.h BFA log library data structure and function definition ++ */ ++ ++#ifndef __BFA_LOG_H__ ++#define __BFA_LOG_H__ ++ ++#include ++#include ++#include ++ ++/* ++ * BFA log module definition ++ * ++ * To create a new module id: ++ * Add a #define at the end of the list below. Select a value for your ++ * definition so that it is one (1) greater than the previous ++ * definition. Modify the definition of BFA_LOG_MODULE_ID_MAX to become ++ * your new definition. ++ * Should have no gaps in between the values because this is used in arrays. ++ * IMPORTANT: AEN_IDs must be at the begining, otherwise update bfa_defs_aen.h ++ */ ++ ++enum bfa_log_module_id { ++ BFA_LOG_UNUSED_ID = 0, ++ ++ /* AEN defs begin */ ++ BFA_LOG_AEN_MIN = BFA_LOG_UNUSED_ID, ++ ++ BFA_LOG_AEN_ID_ADAPTER = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ADAPTER,/* 1 */ ++ BFA_LOG_AEN_ID_PORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_PORT, /* 2 */ ++ BFA_LOG_AEN_ID_LPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_LPORT, /* 3 */ ++ BFA_LOG_AEN_ID_RPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_RPORT, /* 4 */ ++ BFA_LOG_AEN_ID_ITNIM = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ITNIM, /* 5 */ ++ BFA_LOG_AEN_ID_TIN = BFA_LOG_AEN_MIN + BFA_AEN_CAT_TIN, /* 6 */ ++ BFA_LOG_AEN_ID_IPFC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IPFC, /* 7 */ ++ BFA_LOG_AEN_ID_AUDIT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_AUDIT, /* 8 */ ++ BFA_LOG_AEN_ID_IOC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IOC, /* 9 */ ++ BFA_LOG_AEN_ID_ETHPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ETHPORT,/* 10 */ ++ ++ BFA_LOG_AEN_MAX = BFA_LOG_AEN_ID_ETHPORT, ++ /* AEN defs end */ ++ ++ BFA_LOG_MODULE_ID_MIN = BFA_LOG_AEN_MAX, ++ ++ BFA_LOG_FW_ID = BFA_LOG_MODULE_ID_MIN + 1, ++ BFA_LOG_HAL_ID = BFA_LOG_MODULE_ID_MIN + 2, ++ BFA_LOG_FCS_ID = BFA_LOG_MODULE_ID_MIN + 3, ++ BFA_LOG_WDRV_ID = BFA_LOG_MODULE_ID_MIN + 4, ++ BFA_LOG_LINUX_ID = BFA_LOG_MODULE_ID_MIN + 5, ++ BFA_LOG_SOLARIS_ID = BFA_LOG_MODULE_ID_MIN + 6, ++ ++ BFA_LOG_MODULE_ID_MAX = BFA_LOG_SOLARIS_ID, ++ ++ /* Not part of any arrays */ ++ BFA_LOG_MODULE_ID_ALL = BFA_LOG_MODULE_ID_MAX + 1, ++ BFA_LOG_AEN_ALL = BFA_LOG_MODULE_ID_MAX + 2, ++ BFA_LOG_DRV_ALL = BFA_LOG_MODULE_ID_MAX + 3, ++}; ++ ++/* ++ * BFA log catalog name ++ */ ++#define BFA_LOG_CAT_NAME "BFA" ++ ++/* ++ * bfa log severity values ++ */ ++enum bfa_log_severity { ++ BFA_LOG_INVALID = 0, ++ BFA_LOG_CRITICAL = 1, ++ BFA_LOG_ERROR = 2, ++ BFA_LOG_WARNING = 3, ++ BFA_LOG_INFO = 4, ++ BFA_LOG_NONE = 5, ++ BFA_LOG_LEVEL_MAX = BFA_LOG_NONE ++}; ++ ++#define BFA_LOG_MODID_OFFSET 16 ++ ++ ++struct bfa_log_msgdef_s { ++ u32 msg_id; /* message id */ ++ int attributes; /* attributes */ ++ int severity; /* severity level */ ++ char *msg_value; ++ /* msg string */ ++ char *message; ++ /* msg format string */ ++ int arg_type; /* argument type */ ++ int arg_num; /* number of argument */ ++}; ++ ++/* ++ * supported argument type ++ */ ++enum bfa_log_arg_type { ++ BFA_LOG_S = 0, /* string */ ++ BFA_LOG_D, /* decimal */ ++ BFA_LOG_I, /* integer */ ++ BFA_LOG_O, /* oct number */ ++ BFA_LOG_U, /* unsigned integer */ ++ BFA_LOG_X, /* hex number */ ++ BFA_LOG_F, /* floating */ ++ BFA_LOG_C, /* character */ ++ BFA_LOG_L, /* double */ ++ BFA_LOG_P /* pointer */ ++}; ++ ++#define BFA_LOG_ARG_TYPE 2 ++#define BFA_LOG_ARG0 (0 * BFA_LOG_ARG_TYPE) ++#define BFA_LOG_ARG1 (1 * BFA_LOG_ARG_TYPE) ++#define BFA_LOG_ARG2 (2 * BFA_LOG_ARG_TYPE) ++#define BFA_LOG_ARG3 (3 * BFA_LOG_ARG_TYPE) ++ ++#define BFA_LOG_GET_MOD_ID(msgid) ((msgid >> BFA_LOG_MODID_OFFSET) & 0xff) ++#define BFA_LOG_GET_MSG_IDX(msgid) (msgid & 0xffff) ++#define BFA_LOG_GET_MSG_ID(msgdef) ((msgdef)->msg_id) ++#define BFA_LOG_GET_MSG_FMT_STRING(msgdef) ((msgdef)->message) ++#define BFA_LOG_GET_SEVERITY(msgdef) ((msgdef)->severity) ++ ++/* ++ * Event attributes ++ */ ++#define BFA_LOG_ATTR_NONE 0 ++#define BFA_LOG_ATTR_AUDIT 1 ++#define BFA_LOG_ATTR_LOG 2 ++#define BFA_LOG_ATTR_FFDC 4 ++ ++#define BFA_LOG_CREATE_ID(msw, lsw) \ ++ (((u32)msw << BFA_LOG_MODID_OFFSET) | lsw) ++ ++struct bfa_log_mod_s; ++ ++/** ++ * callback function ++ */ ++typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id, ++ const char *format, ...); ++ ++ ++struct bfa_log_mod_s { ++ char instance_info[16]; /* instance info */ ++ int log_level[BFA_LOG_MODULE_ID_MAX + 1]; ++ /* log level for modules */ ++ bfa_log_cb_t cbfn; /* callback function */ ++}; ++ ++extern int bfa_log_init(struct bfa_log_mod_s *log_mod, ++ char *instance_name, bfa_log_cb_t cbfn); ++extern int bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...); ++extern bfa_status_t bfa_log_set_level(struct bfa_log_mod_s *log_mod, ++ int mod_id, enum bfa_log_severity log_level); ++extern bfa_status_t bfa_log_set_level_all(struct bfa_log_mod_s *log_mod, ++ enum bfa_log_severity log_level); ++extern bfa_status_t bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod, ++ enum bfa_log_severity log_level); ++extern enum bfa_log_severity bfa_log_get_level(struct bfa_log_mod_s *log_mod, ++ int mod_id); ++extern enum bfa_log_severity bfa_log_get_msg_level( ++ struct bfa_log_mod_s *log_mod, u32 msg_id); ++/* ++ * array of messages generated from xml files ++ */ ++extern struct bfa_log_msgdef_s bfa_log_msg_array[]; ++ ++#endif +diff --git a/drivers/scsi/bfa/include/cs/bfa_perf.h b/drivers/scsi/bfa/include/cs/bfa_perf.h +new file mode 100644 +index 0000000..45aa5f9 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_perf.h +@@ -0,0 +1,34 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFAD_PERF_H__ ++#define __BFAD_PERF_H__ ++ ++#ifdef BFAD_PERF_BUILD ++ ++#undef bfa_trc ++#undef bfa_trc32 ++#undef bfa_assert ++#undef BFA_TRC_FILE ++ ++#define bfa_trc(_trcp, _data) ++#define bfa_trc32(_trcp, _data) ++#define bfa_assert(__cond) ++#define BFA_TRC_FILE(__mod, __submod) ++ ++#endif ++ ++#endif /* __BFAD_PERF_H__ */ +diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h +new file mode 100644 +index 0000000..670f86e +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_plog.h +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_PORTLOG_H__ ++#define __BFA_PORTLOG_H__ ++ ++#include "protocol/fc.h" ++#include ++ ++#define BFA_PL_NLOG_ENTS 256 ++#define BFA_PL_LOG_REC_INCR(_x) ((_x)++, (_x) %= BFA_PL_NLOG_ENTS) ++ ++#define BFA_PL_STRING_LOG_SZ 32 /* number of chars in string log */ ++#define BFA_PL_INT_LOG_SZ 8 /* number of integers in the integer log */ ++ ++enum bfa_plog_log_type { ++ BFA_PL_LOG_TYPE_INVALID = 0, ++ BFA_PL_LOG_TYPE_INT = 1, ++ BFA_PL_LOG_TYPE_STRING = 2, ++}; ++ ++/* ++ * the (fixed size) record format for each entry in the portlog ++ */ ++struct bfa_plog_rec_s { ++ u32 tv; /* Filled by the portlog driver when the * ++ * entry is added to the circular log. */ ++ u8 port; /* Source port that logged this entry. CM ++ * entities will use 0xFF */ ++ u8 mid; /* Integer value to be used by all entities * ++ * while logging. The module id to string * ++ * conversion will be done by BFAL. See ++ * enum bfa_plog_mid */ ++ u8 eid; /* indicates Rx, Tx, IOCTL, etc. See ++ * enum bfa_plog_eid */ ++ u8 log_type; /* indicates string log or integer log. ++ * see bfa_plog_log_type_t */ ++ u8 log_num_ints; ++ /* ++ * interpreted only if log_type is INT_LOG. indicates number of ++ * integers in the int_log[] (0-PL_INT_LOG_SZ). ++ */ ++ u8 rsvd; ++ u16 misc; /* can be used to indicate fc frame length, ++ *etc.. */ ++ union { ++ char string_log[BFA_PL_STRING_LOG_SZ]; ++ u32 int_log[BFA_PL_INT_LOG_SZ]; ++ } log_entry; ++ ++}; ++ ++/* ++ * the following #defines will be used by the logging entities to indicate ++ * their module id. BFAL will convert the integer value to string format ++ * ++* process to be used while changing the following #defines: ++ * - Always add new entries at the end ++ * - define corresponding string in BFAL ++ * - Do not remove any entry or rearrange the order. ++ */ ++enum bfa_plog_mid { ++ BFA_PL_MID_INVALID = 0, ++ BFA_PL_MID_DEBUG = 1, ++ BFA_PL_MID_DRVR = 2, ++ BFA_PL_MID_HAL = 3, ++ BFA_PL_MID_HAL_FCXP = 4, ++ BFA_PL_MID_HAL_UF = 5, ++ BFA_PL_MID_FCS = 6, ++ BFA_PL_MID_MAX = 7 ++}; ++ ++#define BFA_PL_MID_STRLEN 8 ++struct bfa_plog_mid_strings_s { ++ char m_str[BFA_PL_MID_STRLEN]; ++}; ++ ++/* ++ * the following #defines will be used by the logging entities to indicate ++ * their event type. BFAL will convert the integer value to string format ++ * ++* process to be used while changing the following #defines: ++ * - Always add new entries at the end ++ * - define corresponding string in BFAL ++ * - Do not remove any entry or rearrange the order. ++ */ ++enum bfa_plog_eid { ++ BFA_PL_EID_INVALID = 0, ++ BFA_PL_EID_IOC_DISABLE = 1, ++ BFA_PL_EID_IOC_ENABLE = 2, ++ BFA_PL_EID_PORT_DISABLE = 3, ++ BFA_PL_EID_PORT_ENABLE = 4, ++ BFA_PL_EID_PORT_ST_CHANGE = 5, ++ BFA_PL_EID_TX = 6, ++ BFA_PL_EID_TX_ACK1 = 7, ++ BFA_PL_EID_TX_RJT = 8, ++ BFA_PL_EID_TX_BSY = 9, ++ BFA_PL_EID_RX = 10, ++ BFA_PL_EID_RX_ACK1 = 11, ++ BFA_PL_EID_RX_RJT = 12, ++ BFA_PL_EID_RX_BSY = 13, ++ BFA_PL_EID_CT_IN = 14, ++ BFA_PL_EID_CT_OUT = 15, ++ BFA_PL_EID_DRIVER_START = 16, ++ BFA_PL_EID_RSCN = 17, ++ BFA_PL_EID_DEBUG = 18, ++ BFA_PL_EID_MISC = 19, ++ BFA_PL_EID_MAX = 20 ++}; ++ ++#define BFA_PL_ENAME_STRLEN 8 ++struct bfa_plog_eid_strings_s { ++ char e_str[BFA_PL_ENAME_STRLEN]; ++}; ++ ++#define BFA_PL_SIG_LEN 8 ++#define BFA_PL_SIG_STR "12pl123" ++ ++/* ++ * per port circular log buffer ++ */ ++struct bfa_plog_s { ++ char plog_sig[BFA_PL_SIG_LEN]; /* Start signature */ ++ u8 plog_enabled; ++ u8 rsvd[7]; ++ u32 ticks; ++ u16 head; ++ u16 tail; ++ struct bfa_plog_rec_s plog_recs[BFA_PL_NLOG_ENTS]; ++}; ++ ++void bfa_plog_init(struct bfa_plog_s *plog); ++void bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, u16 misc, char *log_str); ++void bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, u16 misc, ++ u32 *intarr, u32 num_ints); ++void bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, u16 misc, ++ struct fchs_s *fchdr); ++void bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, u16 misc, ++ struct fchs_s *fchdr, u32 pld_w0); ++void bfa_plog_clear(struct bfa_plog_s *plog); ++void bfa_plog_enable(struct bfa_plog_s *plog); ++void bfa_plog_disable(struct bfa_plog_s *plog); ++bfa_boolean_t bfa_plog_get_setting(struct bfa_plog_s *plog); ++ ++#endif /* __BFA_PORTLOG_H__ */ +diff --git a/drivers/scsi/bfa/include/cs/bfa_q.h b/drivers/scsi/bfa/include/cs/bfa_q.h +new file mode 100644 +index 0000000..ea895fa +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_q.h +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_q.h Circular queue definitions. ++ */ ++ ++#ifndef __BFA_Q_H__ ++#define __BFA_Q_H__ ++ ++#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next)) ++#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next) ++#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev) ++ ++/* ++ * bfa_q_qe_init - to initialize a queue element ++ */ ++#define bfa_q_qe_init(_qe) { \ ++ bfa_q_next(_qe) = (struct list_head *) NULL; \ ++ bfa_q_prev(_qe) = (struct list_head *) NULL; \ ++} ++ ++/* ++ * bfa_q_deq - dequeue an element from head of the queue ++ */ ++#define bfa_q_deq(_q, _qe) { \ ++ if (!list_empty(_q)) { \ ++ (*((struct list_head **) (_qe))) = bfa_q_next(_q); \ ++ bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \ ++ (struct list_head *) (_q); \ ++ bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \ ++ BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \ ++ } else { \ ++ *((struct list_head **) (_qe)) = (struct list_head *) NULL; \ ++ } \ ++} ++ ++/* ++ * bfa_q_deq_tail - dequeue an element from tail of the queue ++ */ ++#define bfa_q_deq_tail(_q, _qe) { \ ++ if (!list_empty(_q)) { \ ++ *((struct list_head **) (_qe)) = bfa_q_prev(_q); \ ++ bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \ ++ (struct list_head *) (_q); \ ++ bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe); \ ++ BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \ ++ } else { \ ++ *((struct list_head **) (_qe)) = (struct list_head *) NULL; \ ++ } \ ++} ++ ++/* ++ * #ifdef BFA_DEBUG (Using bfa_assert to check for debug_build is not ++ * consistent across modules) ++ */ ++#ifndef BFA_PERF_BUILD ++#define BFA_Q_DBG_INIT(_qe) bfa_q_qe_init(_qe) ++#else ++#define BFA_Q_DBG_INIT(_qe) ++#endif ++ ++#define bfa_q_is_on_q(_q, _qe) \ ++ bfa_q_is_on_q_func(_q, (struct list_head *)(_qe)) ++extern int bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe); ++ ++#endif +diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h +new file mode 100644 +index 0000000..9877066 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_sm.h +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfasm.h State machine defines ++ */ ++ ++#ifndef __BFA_SM_H__ ++#define __BFA_SM_H__ ++ ++typedef void (*bfa_sm_t)(void *sm, int event); ++ ++#define bfa_sm_set_state(_sm, _state) (_sm)->sm = (bfa_sm_t)(_state) ++#define bfa_sm_send_event(_sm, _event) (_sm)->sm((_sm), (_event)) ++#define bfa_sm_get_state(_sm) ((_sm)->sm) ++#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state)) ++ ++/** ++ * For converting from state machine function to state encoding. ++ */ ++struct bfa_sm_table_s { ++ bfa_sm_t sm; /* state machine function */ ++ int state; /* state machine encoding */ ++ char *name; /* state name for display */ ++}; ++#define BFA_SM(_sm) ((bfa_sm_t)(_sm)) ++ ++int bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm); ++ ++/** ++ * State machine with entry actions. ++ */ ++typedef void (*bfa_fsm_t)(void *fsm, int event); ++ ++/** ++ * oc - object class eg. bfa_ioc ++ * st - state, eg. reset ++ * otype - object type, eg. struct bfa_ioc_s ++ * etype - object type, eg. enum ioc_event ++ */ ++#define bfa_fsm_state_decl(oc, st, otype, etype) \ ++ static void oc ## _sm_ ## st(otype * fsm, etype event); \ ++ static void oc ## _sm_ ## st ## _entry(otype * fsm) ++ ++#define bfa_fsm_set_state(_fsm, _state) do { \ ++ (_fsm)->fsm = (bfa_fsm_t)(_state); \ ++ _state ## _entry(_fsm); \ ++} while (0) ++ ++#define bfa_fsm_send_event(_fsm, _event) \ ++ (_fsm)->fsm((_fsm), (_event)) ++#define bfa_fsm_cmp_state(_fsm, _state) \ ++ ((_fsm)->fsm == (bfa_fsm_t)(_state)) ++ ++#endif +diff --git a/drivers/scsi/bfa/include/cs/bfa_trc.h b/drivers/scsi/bfa/include/cs/bfa_trc.h +new file mode 100644 +index 0000000..3e74392 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_trc.h +@@ -0,0 +1,176 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_TRC_H__ ++#define __BFA_TRC_H__ ++ ++#include ++ ++#ifndef BFA_TRC_MAX ++#define BFA_TRC_MAX (4 * 1024) ++#endif ++ ++#ifndef BFA_TRC_TS ++#define BFA_TRC_TS(_trcm) ((_trcm)->ticks ++) ++#endif ++ ++struct bfa_trc_s { ++#ifdef __BIGENDIAN ++ u16 fileno; ++ u16 line; ++#else ++ u16 line; ++ u16 fileno; ++#endif ++ u32 timestamp; ++ union { ++ struct { ++ u32 rsvd; ++ u32 u32; ++ } u32; ++ u64 u64; ++ } data; ++}; ++ ++ ++struct bfa_trc_mod_s { ++ u32 head; ++ u32 tail; ++ u32 ntrc; ++ u32 stopped; ++ u32 ticks; ++ u32 rsvd[3]; ++ struct bfa_trc_s trc[BFA_TRC_MAX]; ++}; ++ ++ ++enum { ++ BFA_TRC_FW = 1, /* firmware modules */ ++ BFA_TRC_HAL = 2, /* BFA modules */ ++ BFA_TRC_FCS = 3, /* BFA FCS modules */ ++ BFA_TRC_LDRV = 4, /* Linux driver modules */ ++ BFA_TRC_SDRV = 5, /* Solaris driver modules */ ++ BFA_TRC_VDRV = 6, /* vmware driver modules */ ++ BFA_TRC_WDRV = 7, /* windows driver modules */ ++ BFA_TRC_AEN = 8, /* AEN module */ ++ BFA_TRC_BIOS = 9, /* bios driver modules */ ++ BFA_TRC_EFI = 10, /* EFI driver modules */ ++ BNA_TRC_WDRV = 11, /* BNA windows driver modules */ ++ BNA_TRC_VDRV = 12, /* BNA vmware driver modules */ ++ BNA_TRC_SDRV = 13, /* BNA Solaris driver modules */ ++ BNA_TRC_LDRV = 14, /* BNA Linux driver modules */ ++ BNA_TRC_HAL = 15, /* BNA modules */ ++ BFA_TRC_CNA = 16, /* Common modules */ ++ BNA_TRC_IMDRV = 17 /* BNA windows intermediate driver modules */ ++}; ++#define BFA_TRC_MOD_SH 10 ++#define BFA_TRC_MOD(__mod) ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH) ++ ++/** ++ * Define a new tracing file (module). Module should match one defined above. ++ */ ++#define BFA_TRC_FILE(__mod, __submod) \ ++ static int __trc_fileno = ((BFA_TRC_ ## __mod ## _ ## __submod) | \ ++ BFA_TRC_MOD(__mod)) ++ ++ ++#define bfa_trc32(_trcp, _data) \ ++ __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data) ++ ++ ++#ifndef BFA_BOOT_BUILD ++#define bfa_trc(_trcp, _data) \ ++ __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u64)_data) ++#else ++void bfa_boot_trc(struct bfa_trc_mod_s *trcmod, u16 fileno, ++ u16 line, u32 data); ++#define bfa_trc(_trcp, _data) \ ++ bfa_boot_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data) ++#endif ++ ++ ++static inline void ++bfa_trc_init(struct bfa_trc_mod_s *trcm) ++{ ++ trcm->head = trcm->tail = trcm->stopped = 0; ++ trcm->ntrc = BFA_TRC_MAX; ++} ++ ++ ++static inline void ++bfa_trc_stop(struct bfa_trc_mod_s *trcm) ++{ ++ trcm->stopped = 1; ++} ++ ++#ifdef FWTRC ++extern void dc_flush(void *data); ++#else ++#define dc_flush(data) ++#endif ++ ++ ++static inline void ++__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data) ++{ ++ int tail = trcm->tail; ++ struct bfa_trc_s *trc = &trcm->trc[tail]; ++ ++ if (trcm->stopped) ++ return; ++ ++ trc->fileno = (u16) fileno; ++ trc->line = (u16) line; ++ trc->data.u64 = data; ++ trc->timestamp = BFA_TRC_TS(trcm); ++ dc_flush(trc); ++ ++ trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1); ++ if (trcm->tail == trcm->head) ++ trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1); ++ dc_flush(trcm); ++} ++ ++ ++static inline void ++__bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data) ++{ ++ int tail = trcm->tail; ++ struct bfa_trc_s *trc = &trcm->trc[tail]; ++ ++ if (trcm->stopped) ++ return; ++ ++ trc->fileno = (u16) fileno; ++ trc->line = (u16) line; ++ trc->data.u32.u32 = data; ++ trc->timestamp = BFA_TRC_TS(trcm); ++ dc_flush(trc); ++ ++ trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1); ++ if (trcm->tail == trcm->head) ++ trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1); ++ dc_flush(trcm); ++} ++ ++#ifndef BFA_PERF_BUILD ++#define bfa_trc_fp(_trcp, _data) bfa_trc(_trcp, _data) ++#else ++#define bfa_trc_fp(_trcp, _data) ++#endif ++ ++#endif /* __BFA_TRC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/cs/bfa_wc.h b/drivers/scsi/bfa/include/cs/bfa_wc.h +new file mode 100644 +index 0000000..0460bd4 +--- /dev/null ++++ b/drivers/scsi/bfa/include/cs/bfa_wc.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_wc.h Generic wait counter. ++ */ ++ ++#ifndef __BFA_WC_H__ ++#define __BFA_WC_H__ ++ ++typedef void (*bfa_wc_resume_t) (void *cbarg); ++ ++struct bfa_wc_s { ++ bfa_wc_resume_t wc_resume; ++ void *wc_cbarg; ++ int wc_count; ++}; ++ ++static inline void ++bfa_wc_up(struct bfa_wc_s *wc) ++{ ++ wc->wc_count++; ++} ++ ++static inline void ++bfa_wc_down(struct bfa_wc_s *wc) ++{ ++ wc->wc_count--; ++ if (wc->wc_count == 0) ++ wc->wc_resume(wc->wc_cbarg); ++} ++ ++/** ++ * Initialize a waiting counter. ++ */ ++static inline void ++bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg) ++{ ++ wc->wc_resume = wc_resume; ++ wc->wc_cbarg = wc_cbarg; ++ wc->wc_count = 0; ++ bfa_wc_up(wc); ++} ++ ++/** ++ * Wait for counter to reach zero ++ */ ++static inline void ++bfa_wc_wait(struct bfa_wc_s *wc) ++{ ++ bfa_wc_down(wc); ++} ++ ++#endif +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h +new file mode 100644 +index 0000000..8c208fc +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_ADAPTER_H__ ++#define __BFA_DEFS_ADAPTER_H__ ++ ++#include ++#include ++#include ++ ++/** ++ * BFA adapter level attributes. ++ */ ++enum { ++ BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE), ++ /* ++ *!< adapter serial num length ++ */ ++ BFA_ADAPTER_MODEL_NAME_LEN = 16, /* model name length */ ++ BFA_ADAPTER_MODEL_DESCR_LEN = 128, /* model description length */ ++ BFA_ADAPTER_MFG_NAME_LEN = 8, /* manufacturer name length */ ++ BFA_ADAPTER_SYM_NAME_LEN = 64, /* adapter symbolic name length */ ++ BFA_ADAPTER_OS_TYPE_LEN = 64, /* adapter os type length */ ++}; ++ ++struct bfa_adapter_attr_s { ++ char manufacturer[BFA_ADAPTER_MFG_NAME_LEN]; ++ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; ++ u32 rsvd1; ++ char model[BFA_ADAPTER_MODEL_NAME_LEN]; ++ char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; ++ wwn_t pwwn; ++ char node_symname[FC_SYMNAME_MAX]; ++ char hw_ver[BFA_VERSION_LEN]; ++ char fw_ver[BFA_VERSION_LEN]; ++ char optrom_ver[BFA_VERSION_LEN]; ++ char os_type[BFA_ADAPTER_OS_TYPE_LEN]; ++ struct bfa_mfg_vpd_s vpd; ++ struct mac_s mac; ++ ++ u8 nports; ++ u8 max_speed; ++ u8 prototype; ++ char asic_rev; ++ ++ u8 pcie_gen; ++ u8 pcie_lanes_orig; ++ u8 pcie_lanes; ++ u8 cna_capable; ++}; ++ ++/** ++ * BFA adapter level events ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_PORT_AEN_ADD: [in]: None [out]: serial_num, pwwn, nports ++ * BFA_PORT_AEN_REMOVE: [in]: pwwn [out]: serial_num, pwwn, nports ++ */ ++enum bfa_adapter_aen_event { ++ BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */ ++ BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */ ++}; ++ ++struct bfa_adapter_aen_data_s { ++ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; ++ u32 nports; /* Number of NPorts */ ++ wwn_t pwwn; /* WWN of one of its physical port */ ++}; ++ ++#endif /* __BFA_DEFS_ADAPTER_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h +new file mode 100644 +index 0000000..4c81a61 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_AEN_H__ ++#define __BFA_DEFS_AEN_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum bfa_aen_category { ++ BFA_AEN_CAT_ADAPTER = 1, ++ BFA_AEN_CAT_PORT = 2, ++ BFA_AEN_CAT_LPORT = 3, ++ BFA_AEN_CAT_RPORT = 4, ++ BFA_AEN_CAT_ITNIM = 5, ++ BFA_AEN_CAT_TIN = 6, ++ BFA_AEN_CAT_IPFC = 7, ++ BFA_AEN_CAT_AUDIT = 8, ++ BFA_AEN_CAT_IOC = 9, ++ BFA_AEN_CAT_ETHPORT = 10, ++ BFA_AEN_MAX_CAT = 10 ++}; ++ ++#pragma pack(1) ++union bfa_aen_data_u { ++ struct bfa_adapter_aen_data_s adapter; ++ struct bfa_port_aen_data_s port; ++ struct bfa_lport_aen_data_s lport; ++ struct bfa_rport_aen_data_s rport; ++ struct bfa_itnim_aen_data_s itnim; ++ struct bfa_audit_aen_data_s audit; ++ struct bfa_ioc_aen_data_s ioc; ++ struct bfa_ethport_aen_data_s ethport; ++}; ++ ++struct bfa_aen_entry_s { ++ enum bfa_aen_category aen_category; ++ int aen_type; ++ union bfa_aen_data_u aen_data; ++ struct bfa_timeval_s aen_tv; ++ s32 seq_num; ++ s32 bfad_num; ++ s32 rsvd[1]; ++}; ++ ++#pragma pack() ++ ++#define bfa_aen_event_t int ++ ++#endif /* __BFA_DEFS_AEN_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_audit.h b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h +new file mode 100644 +index 0000000..8e3a962 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h +@@ -0,0 +1,38 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_AUDIT_H__ ++#define __BFA_DEFS_AUDIT_H__ ++ ++#include ++ ++/** ++ * BFA audit events ++ */ ++enum bfa_audit_aen_event { ++ BFA_AUDIT_AEN_AUTH_ENABLE = 1, ++ BFA_AUDIT_AEN_AUTH_DISABLE = 2, ++}; ++ ++/** ++ * audit event data ++ */ ++struct bfa_audit_aen_data_s { ++ wwn_t pwwn; ++}; ++ ++#endif /* __BFA_DEFS_AUDIT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h +new file mode 100644 +index 0000000..dd19c83 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_AUTH_H__ ++#define __BFA_DEFS_AUTH_H__ ++ ++#include ++ ++#define PUBLIC_KEY 15409 ++#define PRIVATE_KEY 19009 ++#define KEY_LEN 32399 ++#define BFA_AUTH_SECRET_STRING_LEN 256 ++#define BFA_AUTH_FAIL_TIMEOUT 0xFF ++ ++/** ++ * Authentication status ++ */ ++enum bfa_auth_status { ++ BFA_AUTH_STATUS_NONE = 0, /* no authentication */ ++ BFA_AUTH_UNINIT = 1, /* state - uninit */ ++ BFA_AUTH_NEG_SEND = 2, /* state - negotiate send */ ++ BFA_AUTH_CHAL_WAIT = 3, /* state - challenge wait */ ++ BFA_AUTH_NEG_RETRY = 4, /* state - negotiate retry */ ++ BFA_AUTH_REPLY_SEND = 5, /* state - reply send */ ++ BFA_AUTH_STATUS_WAIT = 6, /* state - status wait */ ++ BFA_AUTH_SUCCESS = 7, /* state - success */ ++ BFA_AUTH_FAILED = 8, /* state - failed */ ++ BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */ ++}; ++ ++struct auth_proto_stats_s { ++ u32 auth_rjts; ++ u32 auth_negs; ++ u32 auth_dones; ++ ++ u32 dhchap_challenges; ++ u32 dhchap_replies; ++ u32 dhchap_successes; ++}; ++ ++/** ++ * Authentication related statistics ++ */ ++struct bfa_auth_stats_s { ++ u32 auth_failures; /* authentication failures */ ++ u32 auth_successes; /* authentication successes*/ ++ struct auth_proto_stats_s auth_rx_stats; /* Rx protocol stats */ ++ struct auth_proto_stats_s auth_tx_stats; /* Tx protocol stats */ ++}; ++ ++/** ++ * Authentication hash function algorithms ++ */ ++enum bfa_auth_algo { ++ BFA_AUTH_ALGO_MD5 = 1, /* Message-Digest algorithm 5 */ ++ BFA_AUTH_ALGO_SHA1 = 2, /* Secure Hash Algorithm 1 */ ++ BFA_AUTH_ALGO_MS = 3, /* MD5, then SHA-1 */ ++ BFA_AUTH_ALGO_SM = 4, /* SHA-1, then MD5 */ ++}; ++ ++/** ++ * DH Groups ++ * ++ * Current value could be combination of one or more of the following values ++ */ ++enum bfa_auth_group { ++ BFA_AUTH_GROUP_DHNULL = 0, /* DH NULL (value == 0) */ ++ BFA_AUTH_GROUP_DH768 = 1, /* DH group 768 (value == 1) */ ++ BFA_AUTH_GROUP_DH1024 = 2, /* DH group 1024 (value == 2) */ ++ BFA_AUTH_GROUP_DH1280 = 4, /* DH group 1280 (value == 3) */ ++ BFA_AUTH_GROUP_DH1536 = 8, /* DH group 1536 (value == 4) */ ++ ++ BFA_AUTH_GROUP_ALL = 256 /* Use default DH group order ++ * 0, 1, 2, 3, 4 */ ++}; ++ ++/** ++ * Authentication secret sources ++ */ ++enum bfa_auth_secretsource { ++ BFA_AUTH_SECSRC_LOCAL = 1, /* locally configured */ ++ BFA_AUTH_SECSRC_RADIUS = 2, /* use radius server */ ++ BFA_AUTH_SECSRC_TACACS = 3, /* TACACS server */ ++}; ++ ++/** ++ * Authentication attributes ++ */ ++struct bfa_auth_attr_s { ++ enum bfa_auth_status status; ++ enum bfa_auth_algo algo; ++ enum bfa_auth_group dh_grp; ++ u16 rjt_code; ++ u16 rjt_code_exp; ++ u8 secret_set; ++ u8 resv[7]; ++}; ++ ++#endif /* __BFA_DEFS_AUTH_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_boot.h b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h +new file mode 100644 +index 0000000..6f4aa52 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_BOOT_H__ ++#define __BFA_DEFS_BOOT_H__ ++ ++#include ++#include ++#include ++ ++enum { ++ BFA_BOOT_BOOTLUN_MAX = 4, /* maximum boot lun per IOC */ ++}; ++ ++#define BOOT_CFG_REV1 1 ++ ++/** ++ * Boot options setting. Boot options setting determines from where ++ * to get the boot lun information ++ */ ++enum bfa_boot_bootopt { ++ BFA_BOOT_AUTO_DISCOVER = 0, /* Boot from blun provided by fabric */ ++ BFA_BOOT_STORED_BLUN = 1, /* Boot from bluns stored in flash */ ++ BFA_BOOT_FIRST_LUN = 2, /* Boot from first discovered blun */ ++}; ++ ++/** ++ * Boot lun information. ++ */ ++struct bfa_boot_bootlun_s { ++ wwn_t pwwn; /* port wwn of target */ ++ lun_t lun; /* 64-bit lun */ ++}; ++ ++/** ++ * BOOT boot configuraton ++ */ ++struct bfa_boot_cfg_s { ++ u8 version; ++ u8 rsvd1; ++ u16 chksum; ++ ++ u8 enable; /* enable/disable SAN boot */ ++ u8 speed; /* boot speed settings */ ++ u8 topology; /* boot topology setting */ ++ u8 bootopt; /* bfa_boot_bootopt_t */ ++ ++ u32 nbluns; /* number of boot luns */ ++ ++ u32 rsvd2; ++ ++ struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX]; ++ struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX]; ++}; ++ ++ ++#endif /* __BFA_DEFS_BOOT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h +new file mode 100644 +index 0000000..520a22f +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * bfa_defs_cee.h Interface declarations between host based ++ * BFAL and DCBX/LLDP module in Firmware ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_CEE_H__ ++#define __BFA_DEFS_CEE_H__ ++ ++#include ++#include ++#include ++ ++#pragma pack(1) ++ ++#define BFA_CEE_LLDP_MAX_STRING_LEN (128) ++ ++ ++/* FIXME: this is coming from the protocol spec. Can the host & apps share the ++ protocol .h files ? ++ */ ++#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 ++#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 ++#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 ++#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008 ++#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010 ++#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020 ++#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040 ++#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080 ++#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100 ++#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200 ++#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400 ++ ++ ++/* LLDP string type */ ++struct bfa_cee_lldp_str_s { ++ u8 sub_type; ++ u8 len; ++ u8 rsvd[2]; ++ u8 value[BFA_CEE_LLDP_MAX_STRING_LEN]; ++}; ++ ++ ++/* LLDP paramters */ ++struct bfa_cee_lldp_cfg_s { ++ struct bfa_cee_lldp_str_s chassis_id; ++ struct bfa_cee_lldp_str_s port_id; ++ struct bfa_cee_lldp_str_s port_desc; ++ struct bfa_cee_lldp_str_s sys_name; ++ struct bfa_cee_lldp_str_s sys_desc; ++ struct bfa_cee_lldp_str_s mgmt_addr; ++ u16 time_to_interval; ++ u16 enabled_system_cap; ++}; ++ ++enum bfa_cee_dcbx_version_e { ++ DCBX_PROTOCOL_PRECEE = 1, ++ DCBX_PROTOCOL_CEE = 2, ++}; ++ ++enum bfa_cee_lls_e { ++ CEE_LLS_DOWN_NO_TLV = 0, /* LLS is down because the TLV not sent by ++ * the peer */ ++ CEE_LLS_DOWN = 1, /* LLS is down as advertised by the peer */ ++ CEE_LLS_UP = 2, ++}; ++ ++/* CEE/DCBX parameters */ ++struct bfa_cee_dcbx_cfg_s { ++ u8 pgid[8]; ++ u8 pg_percentage[8]; ++ u8 pfc_enabled; /* bitmap of priorties with PFC enabled */ ++ u8 fcoe_user_priority; /* bitmap of priorities used for FcoE ++ * traffic */ ++ u8 dcbx_version; /* operating version:CEE or preCEE */ ++ u8 lls_fcoe; /* FCoE Logical Link Status */ ++ u8 lls_lan; /* LAN Logical Link Status */ ++ u8 rsvd[3]; ++}; ++ ++/* CEE status */ ++/* Making this to tri-state for the benefit of port list command */ ++enum bfa_cee_status_e { ++ CEE_PHY_DOWN = 0, ++ CEE_PHY_UP = 1, ++ CEE_UP = 2, ++}; ++ ++/* CEE Query */ ++struct bfa_cee_attr_s { ++ u8 cee_status; ++ u8 error_reason; ++ struct bfa_cee_lldp_cfg_s lldp_remote; ++ struct bfa_cee_dcbx_cfg_s dcbx_remote; ++ mac_t src_mac; ++ u8 link_speed; ++ u8 filler[3]; ++}; ++ ++ ++ ++ ++/* LLDP/DCBX/CEE Statistics */ ++ ++struct bfa_cee_lldp_stats_s { ++ u32 frames_transmitted; ++ u32 frames_aged_out; ++ u32 frames_discarded; ++ u32 frames_in_error; ++ u32 frames_rcvd; ++ u32 tlvs_discarded; ++ u32 tlvs_unrecognized; ++}; ++ ++struct bfa_cee_dcbx_stats_s { ++ u32 subtlvs_unrecognized; ++ u32 negotiation_failed; ++ u32 remote_cfg_changed; ++ u32 tlvs_received; ++ u32 tlvs_invalid; ++ u32 seqno; ++ u32 ackno; ++ u32 recvd_seqno; ++ u32 recvd_ackno; ++}; ++ ++struct bfa_cee_cfg_stats_s { ++ u32 cee_status_down; ++ u32 cee_status_up; ++ u32 cee_hw_cfg_changed; ++ u32 recvd_invalid_cfg; ++}; ++ ++ ++struct bfa_cee_stats_s { ++ struct bfa_cee_lldp_stats_s lldp_stats; ++ struct bfa_cee_dcbx_stats_s dcbx_stats; ++ struct bfa_cee_cfg_stats_s cfg_stats; ++}; ++ ++#pragma pack() ++ ++ ++#endif /* __BFA_DEFS_CEE_H__ */ ++ ++ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h +new file mode 100644 +index 0000000..5704980 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_DRIVER_H__ ++#define __BFA_DEFS_DRIVER_H__ ++ ++/** ++ * Driver statistics ++ */ ++ u16 tm_io_abort; ++ u16 tm_io_abort_comp; ++ u16 tm_lun_reset; ++ u16 tm_lun_reset_comp; ++ u16 tm_target_reset; ++ u16 tm_bus_reset; ++ u16 ioc_restart; /* IOC restart count */ ++ u16 io_pending; /* outstanding io count per-IOC */ ++ u64 control_req; ++ u64 input_req; ++ u64 output_req; ++ u64 input_words; ++ u64 output_words; ++} bfa_driver_stats_t; ++ ++ ++#endif /* __BFA_DEFS_DRIVER_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h +new file mode 100644 +index 0000000..79f9b3e +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_ETHPORT_H__ ++#define __BFA_DEFS_ETHPORT_H__ ++ ++#include ++#include ++#include ++#include ++ ++struct bna_tx_info_s { ++ u32 miniport_state; ++ u32 adapter_state; ++ u64 tx_count; ++ u64 tx_wi; ++ u64 tx_sg; ++ u64 tx_tcp_chksum; ++ u64 tx_udp_chksum; ++ u64 tx_ip_chksum; ++ u64 tx_lsov1; ++ u64 tx_lsov2; ++ u64 tx_max_sg_len ; ++}; ++ ++struct bna_rx_queue_info_s { ++ u16 q_id ; ++ u16 buf_size ; ++ u16 buf_count ; ++ u16 rsvd ; ++ u64 rx_count ; ++ u64 rx_dropped ; ++ u64 rx_unsupported ; ++ u64 rx_internal_err ; ++ u64 rss_count ; ++ u64 vlan_count ; ++ u64 rx_tcp_chksum ; ++ u64 rx_udp_chksum ; ++ u64 rx_ip_chksum ; ++ u64 rx_hds ; ++}; ++ ++struct bna_rx_q_set_s { ++ u16 q_set_type; ++ u32 miniport_state; ++ u32 adapter_state; ++ struct bna_rx_queue_info_s rx_queue[2]; ++}; ++ ++struct bna_port_stats_s { ++ struct bna_tx_info_s tx_stats; ++ u16 qset_count ; ++ struct bna_rx_q_set_s rx_qset[8]; ++}; ++ ++struct bfa_ethport_stats_s { ++ struct bna_stats_txf txf_stats[1]; ++ struct bna_stats_rxf rxf_stats[1]; ++ struct bnad_drv_stats drv_stats; ++}; ++ ++/** ++ * Ethernet port events ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_PORT_AEN_ETH_LINKUP: [in]: mac [out]: mac ++ * BFA_PORT_AEN_ETH_LINKDOWN: [in]: mac [out]: mac ++ * BFA_PORT_AEN_ETH_ENABLE: [in]: mac [out]: mac ++ * BFA_PORT_AEN_ETH_DISABLE: [in]: mac [out]: mac ++ * ++ */ ++enum bfa_ethport_aen_event { ++ BFA_ETHPORT_AEN_LINKUP = 1, /* Base Port Ethernet link up event */ ++ BFA_ETHPORT_AEN_LINKDOWN = 2, /* Base Port Ethernet link down event */ ++ BFA_ETHPORT_AEN_ENABLE = 3, /* Base Port Ethernet link enable event */ ++ BFA_ETHPORT_AEN_DISABLE = 4, /* Base Port Ethernet link disable ++ * event */ ++}; ++ ++struct bfa_ethport_aen_data_s { ++ mac_t mac; /* MAC address of the physical port */ ++}; ++ ++ ++#endif /* __BFA_DEFS_ETHPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h +new file mode 100644 +index 0000000..c08f4f5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_FCPIM_H__ ++#define __BFA_DEFS_FCPIM_H__ ++ ++struct bfa_fcpim_stats_s { ++ u32 total_ios; /* Total IO count */ ++ u32 qresumes; /* IO waiting for CQ space */ ++ u32 no_iotags; /* NO IO contexts */ ++ u32 io_aborts; /* IO abort requests */ ++ u32 no_tskims; /* NO task management contexts */ ++ u32 iocomp_ok; /* IO completions with OK status */ ++ u32 iocomp_underrun; /* IO underrun (good) */ ++ u32 iocomp_overrun; /* IO overrun (good) */ ++ u32 iocomp_aborted; /* Aborted IO requests */ ++ u32 iocomp_timedout; /* IO timeouts */ ++ u32 iocom_nexus_abort; /* IO selection timeouts */ ++ u32 iocom_proto_err; /* IO protocol errors */ ++ u32 iocom_dif_err; /* IO SBC-3 protection errors */ ++ u32 iocom_tm_abort; /* IO aborted by TM requests */ ++ u32 iocom_sqer_needed; /* IO retry for SQ error ++ *recovery */ ++ u32 iocom_res_free; /* Delayed freeing of IO resources */ ++ u32 iocomp_scsierr; /* IO with non-good SCSI status */ ++ u32 iocom_hostabrts; /* Host IO abort requests */ ++ u32 iocom_utags; /* IO comp with unknown tags */ ++ u32 io_cleanups; /* IO implicitly aborted */ ++ u32 io_tmaborts; /* IO aborted due to TM commands */ ++ u32 rsvd; ++}; ++#endif /*__BFA_DEFS_FCPIM_H__*/ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h +new file mode 100644 +index 0000000..9ccf53b +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h +@@ -0,0 +1,32 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_IM_COMMON_H__ ++#define __BFA_DEFS_IM_COMMON_H__ ++ ++#define BFA_ADAPTER_NAME_LEN 256 ++#define BFA_ADAPTER_GUID_LEN 256 ++#define RESERVED_VLAN_NAME L"PORT VLAN" ++#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN" ++ ++ u64 tx_pkt_cnt; ++ u64 rx_pkt_cnt; ++ u32 duration; ++ u8 status; ++} bfa_im_stats_t, *pbfa_im_stats_t; ++ ++#endif /* __BFA_DEFS_IM_COMMON_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h +new file mode 100644 +index 0000000..a486a7e +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_IM_TEAM_H__ ++#define __BFA_DEFS_IM_TEAM_H__ ++ ++#include ++ ++#define BFA_TEAM_MAX_PORTS 8 ++#define BFA_TEAM_NAME_LEN 256 ++#define BFA_MAX_NUM_TEAMS 16 ++#define BFA_TEAM_INVALID_DELAY -1 ++ ++ BFA_LACP_RATE_SLOW = 1, ++ BFA_LACP_RATE_FAST ++} bfa_im_lacp_rate_t; ++ ++ BFA_TEAM_MODE_FAIL_OVER = 1, ++ BFA_TEAM_MODE_FAIL_BACK, ++ BFA_TEAM_MODE_LACP, ++ BFA_TEAM_MODE_NONE ++} bfa_im_team_mode_t; ++ ++ BFA_XMIT_POLICY_L2 = 1, ++ BFA_XMIT_POLICY_L3_L4 ++} bfa_im_xmit_policy_t; ++ ++ bfa_im_team_mode_t team_mode; ++ bfa_im_lacp_rate_t lacp_rate; ++ bfa_im_xmit_policy_t xmit_policy; ++ int delay; ++ wchar_t primary[BFA_ADAPTER_NAME_LEN]; ++ wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; ++ mac_t mac; ++ u16 num_ports; ++ u16 num_vlans; ++ u16 vlan_list[BFA_MAX_VLANS_PER_PORT]; ++ wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN]; ++ wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN]; ++} bfa_im_team_attr_t; ++ ++ wchar_t team_name[BFA_TEAM_NAME_LEN]; ++ bfa_im_xmit_policy_t xmit_policy; ++ int delay; ++ wchar_t primary[BFA_ADAPTER_NAME_LEN]; ++ wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN]; ++} bfa_im_team_edit_t, *pbfa_im_team_edit_t; ++ ++ wchar_t team_name[BFA_TEAM_NAME_LEN]; ++ bfa_im_team_mode_t team_mode; ++ mac_t mac; ++} bfa_im_team_info_t; ++ ++ bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS]; ++ u16 num_teams; ++} bfa_im_team_list_t, *pbfa_im_team_list_t; ++ ++#endif /* __BFA_DEFS_IM_TEAM_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h +new file mode 100644 +index 0000000..b1d532d +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h +@@ -0,0 +1,152 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_IOC_H__ ++#define __BFA_DEFS_IOC_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++enum { ++ BFA_IOC_DRIVER_LEN = 16, ++ BFA_IOC_CHIP_REV_LEN = 8, ++}; ++ ++/** ++ * Driver and firmware versions. ++ */ ++struct bfa_ioc_driver_attr_s { ++ char driver[BFA_IOC_DRIVER_LEN]; /* driver name */ ++ char driver_ver[BFA_VERSION_LEN]; /* driver version */ ++ char fw_ver[BFA_VERSION_LEN]; /* firmware version*/ ++ char bios_ver[BFA_VERSION_LEN]; /* bios version */ ++ char efi_ver[BFA_VERSION_LEN]; /* EFI version */ ++ char ob_ver[BFA_VERSION_LEN]; /* openboot version*/ ++}; ++ ++/** ++ * IOC PCI device attributes ++ */ ++struct bfa_ioc_pci_attr_s { ++ u16 vendor_id; /* PCI vendor ID */ ++ u16 device_id; /* PCI device ID */ ++ u16 ssid; /* subsystem ID */ ++ u16 ssvid; /* subsystem vendor ID */ ++ u32 pcifn; /* PCI device function */ ++ u32 rsvd; /* padding */ ++ u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */ ++}; ++ ++/** ++ * IOC states ++ */ ++enum bfa_ioc_state { ++ BFA_IOC_RESET = 1, /* IOC is in reset state */ ++ BFA_IOC_SEMWAIT = 2, /* Waiting for IOC hardware semaphore */ ++ BFA_IOC_HWINIT = 3, /* IOC hardware is being initialized */ ++ BFA_IOC_GETATTR = 4, /* IOC is being configured */ ++ BFA_IOC_OPERATIONAL = 5, /* IOC is operational */ ++ BFA_IOC_INITFAIL = 6, /* IOC hardware failure */ ++ BFA_IOC_HBFAIL = 7, /* IOC heart-beat failure */ ++ BFA_IOC_DISABLING = 8, /* IOC is being disabled */ ++ BFA_IOC_DISABLED = 9, /* IOC is disabled */ ++ BFA_IOC_FWMISMATCH = 10, /* IOC firmware different from drivers */ ++}; ++ ++/** ++ * IOC firmware stats ++ */ ++struct bfa_fw_ioc_stats_s { ++ u32 hb_count; ++ u32 cfg_reqs; ++ u32 enable_reqs; ++ u32 disable_reqs; ++ u32 stats_reqs; ++ u32 clrstats_reqs; ++ u32 unknown_reqs; ++ u32 ic_reqs; /* interrupt coalesce reqs */ ++}; ++ ++/** ++ * IOC driver stats ++ */ ++struct bfa_ioc_drv_stats_s { ++ u32 ioc_isrs; ++ u32 ioc_enables; ++ u32 ioc_disables; ++ u32 ioc_hbfails; ++ u32 ioc_boots; ++ u32 stats_tmos; ++ u32 hb_count; ++ u32 disable_reqs; ++ u32 enable_reqs; ++ u32 disable_replies; ++ u32 enable_replies; ++}; ++ ++/** ++ * IOC statistics ++ */ ++struct bfa_ioc_stats_s { ++ struct bfa_ioc_drv_stats_s drv_stats; /* driver IOC stats */ ++ struct bfa_fw_ioc_stats_s fw_stats; /* firmware IOC stats */ ++}; ++ ++ ++enum bfa_ioc_type_e { ++ BFA_IOC_TYPE_FC = 1, ++ BFA_IOC_TYPE_FCoE = 2, ++ BFA_IOC_TYPE_LL = 3, ++}; ++ ++/** ++ * IOC attributes returned in queries ++ */ ++struct bfa_ioc_attr_s { ++ enum bfa_ioc_type_e ioc_type; ++ enum bfa_ioc_state state; /* IOC state */ ++ struct bfa_adapter_attr_s adapter_attr; /* HBA attributes */ ++ struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */ ++ struct bfa_ioc_pci_attr_s pci_attr; ++ u8 port_id; /* port number */ ++}; ++ ++/** ++ * BFA IOC level events ++ */ ++enum bfa_ioc_aen_event { ++ BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */ ++ BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure event */ ++ BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */ ++ BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */ ++ BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */ ++}; ++ ++/** ++ * BFA IOC level event data, now just a place holder ++ */ ++struct bfa_ioc_aen_data_s { ++ enum bfa_ioc_type_e ioc_type; ++ wwn_t pwwn; ++ mac_t mac; ++}; ++ ++#endif /* __BFA_DEFS_IOC_H__ */ ++ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h +new file mode 100644 +index 0000000..d76bcbd +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h +@@ -0,0 +1,310 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_IOCFC_H__ ++#define __BFA_DEFS_IOCFC_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BFA_IOCFC_INTR_DELAY 1125 ++#define BFA_IOCFC_INTR_LATENCY 225 ++ ++/** ++ * Interrupt coalescing configuration. ++ */ ++struct bfa_iocfc_intr_attr_s { ++ bfa_boolean_t coalesce; /* enable/disable coalescing */ ++ u16 latency; /* latency in microseconds */ ++ u16 delay; /* delay in microseconds */ ++}; ++ ++/** ++ * IOC firmware configuraton ++ */ ++struct bfa_iocfc_fwcfg_s { ++ u16 num_fabrics; /* number of fabrics */ ++ u16 num_lports; /* number of local lports */ ++ u16 num_rports; /* number of remote ports */ ++ u16 num_ioim_reqs; /* number of IO reqs */ ++ u16 num_tskim_reqs; /* task management requests */ ++ u16 num_iotm_reqs; /* number of TM IO reqs */ ++ u16 num_tsktm_reqs; /* TM task management requests*/ ++ u16 num_fcxp_reqs; /* unassisted FC exchanges */ ++ u16 num_uf_bufs; /* unsolicited recv buffers */ ++ u8 num_cqs; ++ u8 rsvd; ++}; ++ ++struct bfa_iocfc_drvcfg_s { ++ u16 num_reqq_elems; /* number of req queue elements */ ++ u16 num_rspq_elems; /* number of rsp queue elements */ ++ u16 num_sgpgs; /* number of total SG pages */ ++ u16 num_sboot_tgts; /* number of SAN boot targets */ ++ u16 num_sboot_luns; /* number of SAN boot luns */ ++ u16 ioc_recover; /* IOC recovery mode */ ++ u16 min_cfg; /* minimum configuration */ ++ u16 path_tov; /* device path timeout */ ++ bfa_boolean_t delay_comp; /* delay completion of ++ failed inflight IOs */ ++ u32 rsvd; ++}; ++/** ++ * IOC configuration ++ */ ++struct bfa_iocfc_cfg_s { ++ struct bfa_iocfc_fwcfg_s fwcfg; /* firmware side config */ ++ struct bfa_iocfc_drvcfg_s drvcfg; /* driver side config */ ++}; ++ ++/** ++ * IOC firmware IO stats ++ */ ++struct bfa_fw_io_stats_s { ++ u32 host_abort; /* IO aborted by host driver*/ ++ u32 host_cleanup; /* IO clean up by host driver */ ++ ++ u32 fw_io_timeout; /* IOs timedout */ ++ u32 fw_frm_parse; /* frame parsed by f/w */ ++ u32 fw_frm_data; /* fcp_data frame parsed by f/w */ ++ u32 fw_frm_rsp; /* fcp_rsp frame parsed by f/w */ ++ u32 fw_frm_xfer_rdy; /* xfer_rdy frame parsed by f/w */ ++ u32 fw_frm_bls_acc; /* BLS ACC frame parsed by f/w */ ++ u32 fw_frm_tgt_abort; /* target ABTS parsed by f/w */ ++ u32 fw_frm_unknown; /* unknown parsed by f/w */ ++ u32 fw_data_dma; /* f/w DMA'ed the data frame */ ++ u32 fw_frm_drop; /* f/w drop the frame */ ++ ++ u32 rec_timeout; /* FW rec timed out */ ++ u32 error_rec; /* FW sending rec on ++ * an error condition*/ ++ u32 wait_for_si; /* FW wait for SI */ ++ u32 rec_rsp_inval; /* REC rsp invalid */ ++ u32 seqr_io_abort; /* target does not know cmd so abort */ ++ u32 seqr_io_retry; /* SEQR failed so retry IO */ ++ ++ u32 itn_cisc_upd_rsp; /* ITN cisc updated on fcp_rsp */ ++ u32 itn_cisc_upd_data; /* ITN cisc updated on fcp_data */ ++ u32 itn_cisc_upd_xfer_rdy; /* ITN cisc updated on fcp_data */ ++ ++ u32 fcp_data_lost; /* fcp data lost */ ++ ++ u32 ro_set_in_xfer_rdy; /* Target set RO in Xfer_rdy frame */ ++ u32 xfer_rdy_ooo_err; /* Out of order Xfer_rdy received */ ++ u32 xfer_rdy_unknown_err; /* unknown error in xfer_rdy frame */ ++ ++ u32 io_abort_timeout; /* ABTS timedout */ ++ u32 sler_initiated; /* SLER initiated */ ++ ++ u32 unexp_fcp_rsp; /* fcp response in wrong state */ ++ ++ u32 fcp_rsp_under_run; /* fcp rsp IO underrun */ ++ u32 fcp_rsp_under_run_wr; /* fcp rsp IO underrun for write */ ++ u32 fcp_rsp_under_run_err; /* fcp rsp IO underrun error */ ++ u32 fcp_rsp_resid_inval; /* invalid residue */ ++ u32 fcp_rsp_over_run; /* fcp rsp IO overrun */ ++ u32 fcp_rsp_over_run_err; /* fcp rsp IO overrun error */ ++ u32 fcp_rsp_proto_err; /* protocol error in fcp rsp */ ++ u32 fcp_rsp_sense_err; /* error in sense info in fcp rsp */ ++ u32 fcp_conf_req; /* FCP conf requested */ ++ ++ u32 tgt_aborted_io; /* target initiated abort */ ++ ++ u32 ioh_edtov_timeout_event;/* IOH edtov timer popped */ ++ u32 ioh_fcp_rsp_excp_event; /* IOH FCP_RSP exception */ ++ u32 ioh_fcp_conf_event; /* IOH FCP_CONF */ ++ u32 ioh_mult_frm_rsp_event; /* IOH multi_frame FCP_RSP */ ++ u32 ioh_hit_class2_event; /* IOH hit class2 */ ++ u32 ioh_miss_other_event; /* IOH miss other */ ++ u32 ioh_seq_cnt_err_event; /* IOH seq cnt error */ ++ u32 ioh_len_err_event; /* IOH len error - fcp_dl != ++ * bytes xfered */ ++ u32 ioh_seq_len_err_event; /* IOH seq len error */ ++ u32 ioh_data_oor_event; /* Data out of range */ ++ u32 ioh_ro_ooo_event; /* Relative offset out of range */ ++ u32 ioh_cpu_owned_event; /* IOH hit -iost owned by f/w */ ++ u32 ioh_unexp_frame_event; /* unexpected frame recieved ++ * count */ ++ u32 ioh_err_int; /* IOH error int during data-phase ++ * for scsi write ++ */ ++}; ++ ++/** ++ * IOC port firmware stats ++ */ ++ ++struct bfa_fw_port_fpg_stats_s { ++ u32 intr_evt; ++ u32 intr; ++ u32 intr_excess; ++ u32 intr_cause0; ++ u32 intr_other; ++ u32 intr_other_ign; ++ u32 sig_lost; ++ u32 sig_regained; ++ u32 sync_lost; ++ u32 sync_to; ++ u32 sync_regained; ++ u32 div2_overflow; ++ u32 div2_underflow; ++ u32 efifo_overflow; ++ u32 efifo_underflow; ++ u32 idle_rx; ++ u32 lrr_rx; ++ u32 lr_rx; ++ u32 ols_rx; ++ u32 nos_rx; ++ u32 lip_rx; ++ u32 arbf0_rx; ++ u32 mrk_rx; ++ u32 const_mrk_rx; ++ u32 prim_unknown; ++ u32 rsvd; ++}; ++ ++ ++struct bfa_fw_port_lksm_stats_s { ++ u32 hwsm_success; /* hwsm state machine success */ ++ u32 hwsm_fails; /* hwsm fails */ ++ u32 hwsm_wdtov; /* hwsm timed out */ ++ u32 swsm_success; /* swsm success */ ++ u32 swsm_fails; /* swsm fails */ ++ u32 swsm_wdtov; /* swsm timed out */ ++ u32 busybufs; /* link init failed due to busybuf */ ++ u32 buf_waits; /* bufwait state entries */ ++ u32 link_fails; /* link failures */ ++ u32 psp_errors; /* primitive sequence protocol errors */ ++ u32 lr_unexp; /* No. of times LR rx-ed unexpectedly */ ++ u32 lrr_unexp; /* No. of times LRR rx-ed unexpectedly */ ++ u32 lr_tx; /* No. of times LR tx started */ ++ u32 lrr_tx; /* No. of times LRR tx started */ ++ u32 ols_tx; /* No. of times OLS tx started */ ++ u32 nos_tx; /* No. of times NOS tx started */ ++}; ++ ++ ++struct bfa_fw_port_snsm_stats_s { ++ u32 hwsm_success; /* Successful hwsm terminations */ ++ u32 hwsm_fails; /* hwsm fail count */ ++ u32 hwsm_wdtov; /* hwsm timed out */ ++ u32 swsm_success; /* swsm success */ ++ u32 swsm_wdtov; /* swsm timed out */ ++ u32 error_resets; /* error resets initiated by upsm */ ++ u32 sync_lost; /* Sync loss count */ ++ u32 sig_lost; /* Signal loss count */ ++}; ++ ++ ++struct bfa_fw_port_physm_stats_s { ++ u32 module_inserts; /* Module insert count */ ++ u32 module_xtracts; /* Module extracts count */ ++ u32 module_invalids; /* Invalid module inserted count */ ++ u32 module_read_ign; /* Module validation status ignored */ ++ u32 laser_faults; /* Laser fault count */ ++ u32 rsvd; ++}; ++ ++ ++struct bfa_fw_fip_stats_s { ++ u32 disc_req; /* Discovery solicit requests */ ++ u32 disc_rsp; /* Discovery solicit response */ ++ u32 disc_err; /* Discovery advt. parse errors */ ++ u32 disc_unsol; /* Discovery unsolicited */ ++ u32 disc_timeouts; /* Discovery timeouts */ ++ u32 linksvc_unsupp; /* Unsupported link service req */ ++ u32 linksvc_err; /* Parse error in link service req */ ++ u32 logo_req; /* Number of FIP logos received */ ++ u32 clrvlink_req; /* Clear virtual link req */ ++ u32 op_unsupp; /* Unsupported FIP operation */ ++ u32 untagged; /* Untagged frames (ignored) */ ++ u32 rsvd; ++}; ++ ++ ++struct bfa_fw_lps_stats_s { ++ u32 mac_invalids; /* Invalid mac assigned */ ++ u32 rsvd; ++}; ++ ++ ++struct bfa_fw_fcoe_stats_s { ++ u32 cee_linkups; /* CEE link up count */ ++ u32 cee_linkdns; /* CEE link down count */ ++ u32 fip_linkups; /* FIP link up count */ ++ u32 fip_linkdns; /* FIP link up count */ ++ u32 fip_fails; /* FIP fail count */ ++ u32 mac_invalids; /* Invalid mac assigned */ ++}; ++ ++/** ++ * IOC firmware FCoE port stats ++ */ ++struct bfa_fw_fcoe_port_stats_s { ++ struct bfa_fw_fcoe_stats_s fcoe_stats; ++ struct bfa_fw_fip_stats_s fip_stats; ++}; ++ ++/** ++ * IOC firmware FC port stats ++ */ ++struct bfa_fw_fc_port_stats_s { ++ struct bfa_fw_port_fpg_stats_s fpg_stats; ++ struct bfa_fw_port_physm_stats_s physm_stats; ++ struct bfa_fw_port_snsm_stats_s snsm_stats; ++ struct bfa_fw_port_lksm_stats_s lksm_stats; ++}; ++ ++/** ++ * IOC firmware FC port stats ++ */ ++union bfa_fw_port_stats_s { ++ struct bfa_fw_fc_port_stats_s fc_stats; ++ struct bfa_fw_fcoe_port_stats_s fcoe_stats; ++}; ++ ++/** ++ * IOC firmware stats ++ */ ++struct bfa_fw_stats_s { ++ struct bfa_fw_ioc_stats_s ioc_stats; ++ struct bfa_fw_io_stats_s io_stats; ++ union bfa_fw_port_stats_s port_stats; ++}; ++ ++/** ++ * IOC statistics ++ */ ++struct bfa_iocfc_stats_s { ++ struct bfa_fw_stats_s fw_stats; /* firmware IOC stats */ ++}; ++ ++/** ++ * IOC attributes returned in queries ++ */ ++struct bfa_iocfc_attr_s { ++ struct bfa_iocfc_cfg_s config; /* IOCFC config */ ++ struct bfa_iocfc_intr_attr_s intr_attr; /* interrupt attr */ ++}; ++ ++#define BFA_IOCFC_PATHTOV_MAX 60 ++#define BFA_IOCFC_QDEPTH_MAX 2000 ++ ++#endif /* __BFA_DEFS_IOC_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h +new file mode 100644 +index 0000000..7cb63ea +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h +@@ -0,0 +1,70 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_IPFC_H__ ++#define __BFA_DEFS_IPFC_H__ ++ ++#include ++#include ++#include ++ ++/** ++ * FCS ip remote port states ++ */ ++enum bfa_iprp_state { ++ BFA_IPRP_UNINIT = 0, /* PORT is not yet initialized */ ++ BFA_IPRP_ONLINE = 1, /* process login is complete */ ++ BFA_IPRP_OFFLINE = 2, /* iprp is offline */ ++}; ++ ++/** ++ * FCS remote port statistics ++ */ ++struct bfa_iprp_stats_s { ++ u32 offlines; ++ u32 onlines; ++ u32 rscns; ++ u32 plogis; ++ u32 logos; ++ u32 plogi_timeouts; ++ u32 plogi_rejects; ++}; ++ ++/** ++ * FCS iprp attribute returned in queries ++ */ ++struct bfa_iprp_attr_s { ++ enum bfa_iprp_state state; ++}; ++ ++struct bfa_ipfc_stats_s { ++ u32 arp_sent; ++ u32 arp_recv; ++ u32 arp_reply_sent; ++ u32 arp_reply_recv; ++ u32 farp_sent; ++ u32 farp_recv; ++ u32 farp_reply_sent; ++ u32 farp_reply_recv; ++ u32 farp_reject_sent; ++ u32 farp_reject_recv; ++}; ++ ++struct bfa_ipfc_attr_s { ++ bfa_boolean_t enabled; ++}; ++ ++#endif /* __BFA_DEFS_IPFC_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h +new file mode 100644 +index 0000000..2ec7699 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h +@@ -0,0 +1,126 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_ITNIM_H__ ++#define __BFA_DEFS_ITNIM_H__ ++ ++#include ++#include ++ ++/** ++ * FCS itnim states ++ */ ++enum bfa_itnim_state { ++ BFA_ITNIM_OFFLINE = 0, /* offline */ ++ BFA_ITNIM_PRLI_SEND = 1, /* prli send */ ++ BFA_ITNIM_PRLI_SENT = 2, /* prli sent */ ++ BFA_ITNIM_PRLI_RETRY = 3, /* prli retry */ ++ BFA_ITNIM_HCB_ONLINE = 4, /* online callback */ ++ BFA_ITNIM_ONLINE = 5, /* online */ ++ BFA_ITNIM_HCB_OFFLINE = 6, /* offline callback */ ++ BFA_ITNIM_INITIATIOR = 7, /* initiator */ ++}; ++ ++struct bfa_itnim_hal_stats_s { ++ u32 onlines; /* ITN nexus onlines (PRLI done) */ ++ u32 offlines; /* ITN Nexus offlines */ ++ u32 creates; /* ITN create requests */ ++ u32 deletes; /* ITN delete requests */ ++ u32 create_comps; /* ITN create completions */ ++ u32 delete_comps; /* ITN delete completions */ ++ u32 sler_events; /* SLER (sequence level error ++ * recovery) events */ ++ u32 ioc_disabled; /* Num IOC disables */ ++ u32 cleanup_comps; /* ITN cleanup completions */ ++ u32 tm_cmnds; /* task management(TM) cmnds sent */ ++ u32 tm_fw_rsps; /* TM cmds firmware responses */ ++ u32 tm_success; /* TM successes */ ++ u32 tm_failures; /* TM failures */ ++ u32 tm_io_comps; /* TM IO completions */ ++ u32 tm_qresumes; /* TM queue resumes (after waiting ++ * for resources) ++ */ ++ u32 tm_iocdowns; /* TM cmnds affected by IOC down */ ++ u32 tm_cleanups; /* TM cleanups */ ++ u32 tm_cleanup_comps; ++ /* TM cleanup completions */ ++ u32 ios; /* IO requests */ ++ u32 io_comps; /* IO completions */ ++ u64 input_reqs; /* INPUT requests */ ++ u64 output_reqs; /* OUTPUT requests */ ++}; ++ ++/** ++ * FCS remote port statistics ++ */ ++struct bfa_itnim_stats_s { ++ u32 onlines; /* num rport online */ ++ u32 offlines; /* num rport offline */ ++ u32 prli_sent; /* num prli sent out */ ++ u32 fcxp_alloc_wait;/* num fcxp alloc waits */ ++ u32 prli_rsp_err; /* num prli rsp errors */ ++ u32 prli_rsp_acc; /* num prli rsp accepts */ ++ u32 initiator; /* rport is an initiator */ ++ u32 prli_rsp_parse_err; /* prli rsp parsing errors */ ++ u32 prli_rsp_rjt; /* num prli rsp rejects */ ++ u32 timeout; /* num timeouts detected */ ++ u32 sler; /* num sler notification from BFA */ ++ u32 rsvd; ++ struct bfa_itnim_hal_stats_s hal_stats; ++}; ++ ++/** ++ * FCS itnim attributes returned in queries ++ */ ++struct bfa_itnim_attr_s { ++ enum bfa_itnim_state state; /* FCS itnim state */ ++ u8 retry; /* data retransmision support */ ++ u8 task_retry_id; /* task retry ident support */ ++ u8 rec_support; /* REC supported */ ++ u8 conf_comp; /* confirmed completion supp */ ++}; ++ ++/** ++ * BFA ITNIM events. ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_ITNIM_AEN_NEW: [in]: None [out]: vf_id, lpwwn ++ * BFA_ITNIM_AEN_DELETE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets), ++ * [out]: vf_id, ppwwn, lpwwn, rpwwn ++ * BFA_ITNIM_AEN_ONLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets), ++ * [out]: vf_id, ppwwn, lpwwn, rpwwn ++ * BFA_ITNIM_AEN_OFFLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets), ++ * [out]: vf_id, ppwwn, lpwwn, rpwwn ++ * BFA_ITNIM_AEN_DISCONNECT:[in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets), ++ * [out]: vf_id, ppwwn, lpwwn, rpwwn ++ */ ++enum bfa_itnim_aen_event { ++ BFA_ITNIM_AEN_ONLINE = 1, /* Target online */ ++ BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */ ++ BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */ ++}; ++ ++/** ++ * BFA ITNIM event data structure. ++ */ ++struct bfa_itnim_aen_data_s { ++ u16 vf_id; /* vf_id of the IT nexus */ ++ u16 rsvd[3]; ++ wwn_t ppwwn; /* WWN of its physical port */ ++ wwn_t lpwwn; /* WWN of logical port */ ++ wwn_t rpwwn; /* WWN of remote(target) port */ ++}; ++ ++#endif /* __BFA_DEFS_ITNIM_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_led.h b/drivers/scsi/bfa/include/defs/bfa_defs_led.h +new file mode 100644 +index 0000000..6203927 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_led.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_LED_H__ ++#define __BFA_DEFS_LED_H__ ++ ++#define BFA_LED_MAX_NUM 3 ++ ++enum bfa_led_op { ++ BFA_LED_OFF = 0, ++ BFA_LED_ON = 1, ++ BFA_LED_FLICK = 2, ++ BFA_LED_BLINK = 3, ++}; ++ ++enum bfa_led_color { ++ BFA_LED_GREEN = 0, ++ BFA_LED_AMBER = 1, ++}; ++ ++#endif /* __BFA_DEFS_LED_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h +new file mode 100644 +index 0000000..7359f82 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h +@@ -0,0 +1,68 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_LPORT_H__ ++#define __BFA_DEFS_LPORT_H__ ++ ++#include ++#include ++ ++/** ++ * BFA AEN logical port events. ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_LPORT_AEN_NEW: [in]: None [out]: vf_id, ppwwn, lpwwn, roles ++ * BFA_LPORT_AEN_DELETE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_NEW_PROP: [in]: None [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_DELETE_PROP: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_NEW_STANDARD: [in]: None [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_DELETE_STANDARD: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_NPIV_DUP_WWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_NPIV_FABRIC_MAX: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ * BFA_LPORT_AEN_NPIV_UNKNOWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles ++ */ ++enum bfa_lport_aen_event { ++ BFA_LPORT_AEN_NEW = 1, /* LPort created event */ ++ BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */ ++ BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */ ++ BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */ ++ BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */ ++ BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */ ++ BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */ ++ BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */ ++ BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */ ++ BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort configured with ++ * duplicate WWN event ++ */ ++ BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */ ++ BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code event */ ++}; ++ ++/** ++ * BFA AEN event data structure ++ */ ++struct bfa_lport_aen_data_s { ++ u16 vf_id; /* vf_id of this logical port */ ++ u16 rsvd; ++ enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */ ++ wwn_t ppwwn; /* WWN of its physical port */ ++ wwn_t lpwwn; /* WWN of this logical port */ ++}; ++ ++#endif /* __BFA_DEFS_LPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h +new file mode 100644 +index 0000000..13fd4ab +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_MFG_H__ ++#define __BFA_DEFS_MFG_H__ ++ ++#include ++ ++/** ++ * Manufacturing block version ++ */ ++#define BFA_MFG_VERSION 1 ++ ++/** ++ * Manufacturing block format ++ */ ++#define BFA_MFG_SERIALNUM_SIZE 11 ++#define BFA_MFG_PARTNUM_SIZE 14 ++#define BFA_MFG_SUPPLIER_ID_SIZE 10 ++#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 ++#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 ++#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 ++#define STRSZ(_n) (((_n) + 4) & ~3) ++ ++/** ++ * VPD data length ++ */ ++#define BFA_MFG_VPD_LEN 256 ++ ++/** ++ * All numerical fields are in big-endian format. ++ */ ++struct bfa_mfg_vpd_s { ++ u8 version; /* vpd data version */ ++ u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */ ++ u8 chksum; /* u8 checksum */ ++ u8 vendor; /* vendor */ ++ u8 len; /* vpd data length excluding header */ ++ u8 rsv; ++ u8 data[BFA_MFG_VPD_LEN]; /* vpd data */ ++}; ++ ++#pragma pack(1) ++ ++#endif /* __BFA_DEFS_MFG_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pci.h b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h +new file mode 100644 +index 0000000..c9b8332 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_PCI_H__ ++#define __BFA_DEFS_PCI_H__ ++ ++/** ++ * PCI device and vendor ID information ++ */ ++enum { ++ BFA_PCI_VENDOR_ID_BROCADE = 0x1657, ++ BFA_PCI_DEVICE_ID_FC_8G2P = 0x13, ++ BFA_PCI_DEVICE_ID_FC_8G1P = 0x17, ++ BFA_PCI_DEVICE_ID_CT = 0x14, ++}; ++ ++/** ++ * PCI sub-system device and vendor ID information ++ */ ++enum { ++ BFA_PCI_FCOE_SSDEVICE_ID = 0x14, ++}; ++ ++#define BFA_PCI_ACCESS_RANGES 1 /* Maximum number of device address ranges ++ * mapped through different BAR(s). */ ++ ++#endif /* __BFA_DEFS_PCI_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pm.h b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h +new file mode 100644 +index 0000000..e8d6d95 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_PM_H__ ++#define __BFA_DEFS_PM_H__ ++ ++#include ++ ++/** ++ * BFA power management device states ++ */ ++enum bfa_pm_ds { ++ BFA_PM_DS_D0 = 0, /* full power mode */ ++ BFA_PM_DS_D1 = 1, /* power save state 1 */ ++ BFA_PM_DS_D2 = 2, /* power save state 2 */ ++ BFA_PM_DS_D3 = 3, /* power off state */ ++}; ++ ++#endif /* __BFA_DEFS_PM_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pom.h b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h +new file mode 100644 +index 0000000..d9fa278 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_POM_H__ ++#define __BFA_DEFS_POM_H__ ++ ++#include ++#include ++ ++/** ++ * POM health status levels for each attributes. ++ */ ++enum bfa_pom_entry_health { ++ BFA_POM_HEALTH_NOINFO = 1, /* no information */ ++ BFA_POM_HEALTH_NORMAL = 2, /* health is normal */ ++ BFA_POM_HEALTH_WARNING = 3, /* warning level */ ++ BFA_POM_HEALTH_ALARM = 4, /* alarming level */ ++}; ++ ++/** ++ * Reading of temperature/voltage/current/power ++ */ ++struct bfa_pom_entry_s { ++ enum bfa_pom_entry_health health; /* POM entry health */ ++ u32 curr_value; /* current value */ ++ u32 thr_warn_high; /* threshold warning high */ ++ u32 thr_warn_low; /* threshold warning low */ ++ u32 thr_alarm_low; /* threshold alaram low */ ++ u32 thr_alarm_high; /* threshold alarm high */ ++}; ++ ++/** ++ * POM attributes ++ */ ++struct bfa_pom_attr_s { ++ struct bfa_pom_entry_s temperature; /* centigrade */ ++ struct bfa_pom_entry_s voltage; /* volts */ ++ struct bfa_pom_entry_s curr; /* milli amps */ ++ struct bfa_pom_entry_s txpower; /* micro watts */ ++ struct bfa_pom_entry_s rxpower; /* micro watts */ ++}; ++ ++#endif /* __BFA_DEFS_POM_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h +new file mode 100644 +index 0000000..de0696c +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h +@@ -0,0 +1,245 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_PORT_H__ ++#define __BFA_DEFS_PORT_H__ ++ ++#include ++#include ++#include ++#include ++ ++#define BFA_FCS_FABRIC_IPADDR_SZ 16 ++ ++/** ++ * symbolic names for base port/virtual port ++ */ ++#define BFA_SYMNAME_MAXLEN 128 /* vmware/windows uses 128 bytes */ ++struct bfa_port_symname_s { ++ char symname[BFA_SYMNAME_MAXLEN]; ++}; ++ ++/** ++* Roles of FCS port: ++ * - FCP IM and FCP TM roles cannot be enabled together for a FCS port ++ * - Create multiple ports if both IM and TM functions required. ++ * - Atleast one role must be specified. ++ */ ++enum bfa_port_role { ++ BFA_PORT_ROLE_FCP_IM = 0x01, /* FCP initiator role */ ++ BFA_PORT_ROLE_FCP_TM = 0x02, /* FCP target role */ ++ BFA_PORT_ROLE_FCP_IPFC = 0x04, /* IP over FC role */ ++ BFA_PORT_ROLE_FCP_MAX = BFA_PORT_ROLE_FCP_IPFC | BFA_PORT_ROLE_FCP_IM ++}; ++ ++/** ++ * FCS port configuration. ++ */ ++struct bfa_port_cfg_s { ++ wwn_t pwwn; /* port wwn */ ++ wwn_t nwwn; /* node wwn */ ++ struct bfa_port_symname_s sym_name; /* vm port symbolic name */ ++ enum bfa_port_role roles; /* FCS port roles */ ++ u32 rsvd; ++ u8 tag[16]; /* opaque tag from application */ ++}; ++ ++/** ++ * FCS port states ++ */ ++enum bfa_port_state { ++ BFA_PORT_UNINIT = 0, /* PORT is not yet initialized */ ++ BFA_PORT_FDISC = 1, /* FDISC is in progress */ ++ BFA_PORT_ONLINE = 2, /* login to fabric is complete */ ++ BFA_PORT_OFFLINE = 3, /* No login to fabric */ ++}; ++ ++/** ++ * FCS port type. Required for VmWare. ++ */ ++enum bfa_port_type { ++ BFA_PORT_TYPE_PHYSICAL = 0, ++ BFA_PORT_TYPE_VIRTUAL, ++}; ++ ++/** ++ * FCS port offline reason. Required for VmWare. ++ */ ++enum bfa_port_offline_reason { ++ BFA_PORT_OFFLINE_UNKNOWN = 0, ++ BFA_PORT_OFFLINE_LINKDOWN, ++ BFA_PORT_OFFLINE_FAB_UNSUPPORTED, /* NPIV not supported by the ++ * fabric */ ++ BFA_PORT_OFFLINE_FAB_NORESOURCES, ++ BFA_PORT_OFFLINE_FAB_LOGOUT, ++}; ++ ++/** ++ * FCS lport info. Required for VmWare. ++ */ ++struct bfa_port_info_s { ++ u8 port_type; /* bfa_port_type_t : physical or ++ * virtual */ ++ u8 port_state; /* one of bfa_port_state values */ ++ u8 offline_reason; /* one of bfa_port_offline_reason_t ++ * values */ ++ wwn_t port_wwn; ++ wwn_t node_wwn; ++ ++ /* ++ * following 4 feilds are valid for Physical Ports only ++ */ ++ u32 max_vports_supp; /* Max supported vports */ ++ u32 num_vports_inuse; /* Num of in use vports */ ++ u32 max_rports_supp; /* Max supported rports */ ++ u32 num_rports_inuse; /* Num of doscovered rports */ ++ ++}; ++ ++/** ++ * FCS port statistics ++ */ ++struct bfa_port_stats_s { ++ u32 ns_plogi_sent; ++ u32 ns_plogi_rsp_err; ++ u32 ns_plogi_acc_err; ++ u32 ns_plogi_accepts; ++ u32 ns_rejects; /* NS command rejects */ ++ u32 ns_plogi_unknown_rsp; ++ u32 ns_plogi_alloc_wait; ++ ++ u32 ns_retries; /* NS command retries */ ++ u32 ns_timeouts; /* NS command timeouts */ ++ ++ u32 ns_rspnid_sent; ++ u32 ns_rspnid_accepts; ++ u32 ns_rspnid_rsp_err; ++ u32 ns_rspnid_rejects; ++ u32 ns_rspnid_alloc_wait; ++ ++ u32 ns_rftid_sent; ++ u32 ns_rftid_accepts; ++ u32 ns_rftid_rsp_err; ++ u32 ns_rftid_rejects; ++ u32 ns_rftid_alloc_wait; ++ ++ u32 ns_rffid_sent; ++ u32 ns_rffid_accepts; ++ u32 ns_rffid_rsp_err; ++ u32 ns_rffid_rejects; ++ u32 ns_rffid_alloc_wait; ++ ++ u32 ns_gidft_sent; ++ u32 ns_gidft_accepts; ++ u32 ns_gidft_rsp_err; ++ u32 ns_gidft_rejects; ++ u32 ns_gidft_unknown_rsp; ++ u32 ns_gidft_alloc_wait; ++ ++ /* ++ * Mgmt Server stats ++ */ ++ u32 ms_retries; /* MS command retries */ ++ u32 ms_timeouts; /* MS command timeouts */ ++ u32 ms_plogi_sent; ++ u32 ms_plogi_rsp_err; ++ u32 ms_plogi_acc_err; ++ u32 ms_plogi_accepts; ++ u32 ms_rejects; /* NS command rejects */ ++ u32 ms_plogi_unknown_rsp; ++ u32 ms_plogi_alloc_wait; ++ ++ u32 num_rscn; /* Num of RSCN received */ ++ u32 num_portid_rscn;/* Num portid format RSCN ++ * received */ ++ ++ u32 uf_recvs; /* unsolicited recv frames */ ++ u32 uf_recv_drops; /* dropped received frames */ ++ ++ u32 rsvd; /* padding for 64 bit alignment */ ++}; ++ ++/** ++ * BFA port attribute returned in queries ++ */ ++struct bfa_port_attr_s { ++ enum bfa_port_state state; /* port state */ ++ u32 pid; /* port ID */ ++ struct bfa_port_cfg_s port_cfg; /* port configuration */ ++ enum bfa_pport_type port_type; /* current topology */ ++ u32 loopback; /* cable is externally looped back */ ++ wwn_t fabric_name; /* attached switch's nwwn */ ++ u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached ++ * fabric's ip addr */ ++}; ++ ++/** ++ * BFA physical port Level events ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_PORT_AEN_ONLINE: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_OFFLINE: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_RLIR: [in]: None [out]: pwwn, rlir_data, rlir_len ++ * BFA_PORT_AEN_SFP_INSERT: [in]: pwwn [out]: port_id, pwwn ++ * BFA_PORT_AEN_SFP_REMOVE: [in]: pwwn [out]: port_id, pwwn ++ * BFA_PORT_AEN_SFP_POM: [in]: pwwn [out]: level, port_id, pwwn ++ * BFA_PORT_AEN_ENABLE: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_DISABLE: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_AUTH_ON: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_AUTH_OFF: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_DISCONNECT: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_QOS_NEG: [in]: pwwn [out]: pwwn ++ * BFA_PORT_AEN_FABRIC_NAME_CHANGE: [in]: pwwn, [out]: pwwn, fwwn ++ * ++ */ ++enum bfa_port_aen_event { ++ BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */ ++ BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */ ++ BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */ ++ BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */ ++ BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */ ++ BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */ ++ BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */ ++ BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */ ++ BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */ ++ BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */ ++ BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */ ++ BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */ ++ BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change ++ * event */ ++ BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */ ++ BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */ ++}; ++ ++enum bfa_port_aen_sfp_pom { ++ BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */ ++ BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */ ++ BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */ ++ BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED ++}; ++ ++struct bfa_port_aen_data_s { ++ enum bfa_ioc_type_e ioc_type; ++ wwn_t pwwn; /* WWN of the physical port */ ++ wwn_t fwwn; /* WWN of the fabric port */ ++ mac_t mac; /* MAC addres of the ethernet port, ++ * applicable to CNA port only */ ++ int phy_port_num; /*! For SFP related events */ ++ enum bfa_port_aen_sfp_pom level; /* Only transitions will ++ * be informed */ ++}; ++ ++#endif /* __BFA_DEFS_PORT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +new file mode 100644 +index 0000000..a000bc4 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h +@@ -0,0 +1,383 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_PPORT_H__ ++#define __BFA_DEFS_PPORT_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Modify char* port_stt[] in bfal_port.c if a new state was added */ ++enum bfa_pport_states { ++ BFA_PPORT_ST_UNINIT = 1, ++ BFA_PPORT_ST_ENABLING_QWAIT = 2, ++ BFA_PPORT_ST_ENABLING = 3, ++ BFA_PPORT_ST_LINKDOWN = 4, ++ BFA_PPORT_ST_LINKUP = 5, ++ BFA_PPORT_ST_DISABLING_QWAIT = 6, ++ BFA_PPORT_ST_DISABLING = 7, ++ BFA_PPORT_ST_DISABLED = 8, ++ BFA_PPORT_ST_STOPPED = 9, ++ BFA_PPORT_ST_IOCDOWN = 10, ++ BFA_PPORT_ST_IOCDIS = 11, ++ BFA_PPORT_ST_FWMISMATCH = 12, ++ BFA_PPORT_ST_MAX_STATE, ++}; ++ ++/** ++ * Port speed settings. Each specific speed is a bit field. Use multiple ++ * bits to specify speeds to be selected for auto-negotiation. ++ */ ++enum bfa_pport_speed { ++ BFA_PPORT_SPEED_UNKNOWN = 0, ++ BFA_PPORT_SPEED_1GBPS = 1, ++ BFA_PPORT_SPEED_2GBPS = 2, ++ BFA_PPORT_SPEED_4GBPS = 4, ++ BFA_PPORT_SPEED_8GBPS = 8, ++ BFA_PPORT_SPEED_10GBPS = 10, ++ BFA_PPORT_SPEED_AUTO = ++ (BFA_PPORT_SPEED_1GBPS | BFA_PPORT_SPEED_2GBPS | ++ BFA_PPORT_SPEED_4GBPS | BFA_PPORT_SPEED_8GBPS), ++}; ++ ++/** ++ * Port operational type (in sync with SNIA port type). ++ */ ++enum bfa_pport_type { ++ BFA_PPORT_TYPE_UNKNOWN = 1, /* port type is unkown */ ++ BFA_PPORT_TYPE_TRUNKED = 2, /* Trunked mode */ ++ BFA_PPORT_TYPE_NPORT = 5, /* P2P with switched fabric */ ++ BFA_PPORT_TYPE_NLPORT = 6, /* public loop */ ++ BFA_PPORT_TYPE_LPORT = 20, /* private loop */ ++ BFA_PPORT_TYPE_P2P = 21, /* P2P with no switched fabric */ ++ BFA_PPORT_TYPE_VPORT = 22, /* NPIV - virtual port */ ++}; ++ ++/** ++ * Port topology setting. A port's topology and fabric login status ++ * determine its operational type. ++ */ ++enum bfa_pport_topology { ++ BFA_PPORT_TOPOLOGY_NONE = 0, /* No valid topology */ ++ BFA_PPORT_TOPOLOGY_P2P = 1, /* P2P only */ ++ BFA_PPORT_TOPOLOGY_LOOP = 2, /* LOOP topology */ ++ BFA_PPORT_TOPOLOGY_AUTO = 3, /* auto topology selection */ ++}; ++ ++/** ++ * Physical port loopback types. ++ */ ++enum bfa_pport_opmode { ++ BFA_PPORT_OPMODE_NORMAL = 0x00, /* normal non-loopback mode */ ++ BFA_PPORT_OPMODE_LB_INT = 0x01, /* internal loop back */ ++ BFA_PPORT_OPMODE_LB_SLW = 0x02, /* serial link wrapback (serdes) */ ++ BFA_PPORT_OPMODE_LB_EXT = 0x04, /* external loop back (serdes) */ ++ BFA_PPORT_OPMODE_LB_CBL = 0x08, /* cabled loop back */ ++ BFA_PPORT_OPMODE_LB_NLINT = 0x20, /* NL_Port internal loopback */ ++}; ++ ++#define BFA_PPORT_OPMODE_LB_HARD(_mode) \ ++ ((_mode == BFA_PPORT_OPMODE_LB_INT) || \ ++ (_mode == BFA_PPORT_OPMODE_LB_SLW) || \ ++ (_mode == BFA_PPORT_OPMODE_LB_EXT)) ++ ++/** ++ Port State (in sync with SNIA port state). ++ */ ++enum bfa_pport_snia_state { ++ BFA_PPORT_STATE_UNKNOWN = 1, /* port is not initialized */ ++ BFA_PPORT_STATE_ONLINE = 2, /* port is ONLINE */ ++ BFA_PPORT_STATE_DISABLED = 3, /* port is disabled by user */ ++ BFA_PPORT_STATE_BYPASSED = 4, /* port is bypassed (in LOOP) */ ++ BFA_PPORT_STATE_DIAG = 5, /* port diagnostics is active */ ++ BFA_PPORT_STATE_LINKDOWN = 6, /* link is down */ ++ BFA_PPORT_STATE_LOOPBACK = 8, /* port is looped back */ ++}; ++ ++/** ++ * Port link state ++ */ ++enum bfa_pport_linkstate { ++ BFA_PPORT_LINKUP = 1, /* Physical port/Trunk link up */ ++ BFA_PPORT_LINKDOWN = 2, /* Physical port/Trunk link down */ ++ BFA_PPORT_TRUNK_LINKDOWN = 3, /* Trunk link down (new tmaster) */ ++}; ++ ++/** ++ * Port link state event ++ */ ++#define bfa_pport_event_t enum bfa_pport_linkstate ++ ++/** ++ * Port link state reason code ++ */ ++enum bfa_pport_linkstate_rsn { ++ BFA_PPORT_LINKSTATE_RSN_NONE = 0, ++ BFA_PPORT_LINKSTATE_RSN_DISABLED = 1, ++ BFA_PPORT_LINKSTATE_RSN_RX_NOS = 2, ++ BFA_PPORT_LINKSTATE_RSN_RX_OLS = 3, ++ BFA_PPORT_LINKSTATE_RSN_RX_LIP = 4, ++ BFA_PPORT_LINKSTATE_RSN_RX_LIPF7 = 5, ++ BFA_PPORT_LINKSTATE_RSN_SFP_REMOVED = 6, ++ BFA_PPORT_LINKSTATE_RSN_PORT_FAULT = 7, ++ BFA_PPORT_LINKSTATE_RSN_RX_LOS = 8, ++ BFA_PPORT_LINKSTATE_RSN_LOCAL_FAULT = 9, ++ BFA_PPORT_LINKSTATE_RSN_REMOTE_FAULT = 10, ++ BFA_PPORT_LINKSTATE_RSN_TIMEOUT = 11, ++ ++ ++ ++ /* CEE related reason codes/errors */ ++ CEE_LLDP_INFO_AGED_OUT = 20, ++ CEE_LLDP_SHUTDOWN_TLV_RCVD = 21, ++ CEE_PEER_NOT_ADVERTISE_DCBX = 22, ++ CEE_PEER_NOT_ADVERTISE_PG = 23, ++ CEE_PEER_NOT_ADVERTISE_PFC = 24, ++ CEE_PEER_NOT_ADVERTISE_FCOE = 25, ++ CEE_PG_NOT_COMPATIBLE = 26, ++ CEE_PFC_NOT_COMPATIBLE = 27, ++ CEE_FCOE_NOT_COMPATIBLE = 28, ++ CEE_BAD_PG_RCVD = 29, ++ CEE_BAD_BW_RCVD = 30, ++ CEE_BAD_PFC_RCVD = 31, ++ CEE_BAD_FCOE_PRI_RCVD = 32, ++ CEE_FCOE_PRI_PFC_OFF = 33, ++ CEE_DUP_CONTROL_TLV_RCVD = 34, ++ CEE_DUP_FEAT_TLV_RCVD = 35, ++ CEE_APPLY_NEW_CFG = 36, /* reason, not an error */ ++ CEE_PROTOCOL_INIT = 37, /* reason, not an error */ ++ CEE_PHY_LINK_DOWN = 38, ++ CEE_LLS_FCOE_ABSENT = 39, ++ CEE_LLS_FCOE_DOWN = 40 ++}; ++ ++/** ++ * Default Target Rate Limiting Speed. ++ */ ++#define BFA_PPORT_DEF_TRL_SPEED BFA_PPORT_SPEED_1GBPS ++ ++/** ++ * Physical port configuration ++ */ ++struct bfa_pport_cfg_s { ++ u8 topology; /* bfa_pport_topology */ ++ u8 speed; /* enum bfa_pport_speed */ ++ u8 trunked; /* trunked or not */ ++ u8 qos_enabled; /* qos enabled or not */ ++ u8 trunk_ports; /* bitmap of trunked ports */ ++ u8 cfg_hardalpa; /* is hard alpa configured */ ++ u16 maxfrsize; /* maximum frame size */ ++ u8 hardalpa; /* configured hard alpa */ ++ u8 rx_bbcredit; /* receive buffer credits */ ++ u8 tx_bbcredit; /* transmit buffer credits */ ++ u8 ratelimit; /* ratelimit enabled or not */ ++ u8 trl_def_speed; /* ratelimit default speed */ ++ u8 rsvd[3]; ++ u16 path_tov; /* device path timeout */ ++ u16 q_depth; /* SCSI Queue depth */ ++}; ++ ++/** ++ * Port attribute values. ++ */ ++struct bfa_pport_attr_s { ++ /* ++ * Static fields ++ */ ++ wwn_t nwwn; /* node wwn */ ++ wwn_t pwwn; /* port wwn */ ++ enum fc_cos cos_supported; /* supported class of services */ ++ u32 rsvd; ++ struct fc_symname_s port_symname; /* port symbolic name */ ++ enum bfa_pport_speed speed_supported; /* supported speeds */ ++ bfa_boolean_t pbind_enabled; /* Will be set if Persistent binding ++ * enabled. Relevant only in Windows ++ */ ++ ++ /* ++ * Configured values ++ */ ++ struct bfa_pport_cfg_s pport_cfg; /* pport cfg */ ++ ++ /* ++ * Dynamic field - info from BFA ++ */ ++ enum bfa_pport_states port_state; /* current port state */ ++ enum bfa_pport_speed speed; /* current speed */ ++ enum bfa_pport_topology topology; /* current topology */ ++ bfa_boolean_t beacon; /* current beacon status */ ++ bfa_boolean_t link_e2e_beacon;/* set if link beacon on */ ++ bfa_boolean_t plog_enabled; /* set if portlog is enabled*/ ++ ++ /* ++ * Dynamic field - info from FCS ++ */ ++ u32 pid; /* port ID */ ++ enum bfa_pport_type port_type; /* current topology */ ++ u32 loopback; /* external loopback */ ++ u32 rsvd1; ++ u32 rsvd2; /* padding for 64 bit */ ++}; ++ ++/** ++ * FC Port statistics. ++ */ ++struct bfa_pport_fc_stats_s { ++ u64 secs_reset; /* seconds since stats is reset */ ++ u64 tx_frames; /* transmitted frames */ ++ u64 tx_words; /* transmitted words */ ++ u64 rx_frames; /* received frames */ ++ u64 rx_words; /* received words */ ++ u64 lip_count; /* LIPs seen */ ++ u64 nos_count; /* NOS count */ ++ u64 error_frames; /* errored frames (sent?) */ ++ u64 dropped_frames; /* dropped frames */ ++ u64 link_failures; /* link failure count */ ++ u64 loss_of_syncs; /* loss of sync count */ ++ u64 loss_of_signals;/* loss of signal count */ ++ u64 primseq_errs; /* primitive sequence protocol */ ++ u64 bad_os_count; /* invalid ordered set */ ++ u64 err_enc_out; /* Encoding error outside frame */ ++ u64 invalid_crcs; /* frames received with invalid CRC*/ ++ u64 undersized_frm; /* undersized frames */ ++ u64 oversized_frm; /* oversized frames */ ++ u64 bad_eof_frm; /* frames with bad EOF */ ++ struct bfa_qos_stats_s qos_stats; /* QoS statistics */ ++}; ++ ++/** ++ * Eth Port statistics. ++ */ ++struct bfa_pport_eth_stats_s { ++ u64 secs_reset; /* seconds since stats is reset */ ++ u64 frame_64; /* both rx and tx counter */ ++ u64 frame_65_127; /* both rx and tx counter */ ++ u64 frame_128_255; /* both rx and tx counter */ ++ u64 frame_256_511; /* both rx and tx counter */ ++ u64 frame_512_1023; /* both rx and tx counter */ ++ u64 frame_1024_1518; /* both rx and tx counter */ ++ u64 frame_1519_1522; /* both rx and tx counter */ ++ ++ u64 tx_bytes; ++ u64 tx_packets; ++ u64 tx_mcast_packets; ++ u64 tx_bcast_packets; ++ u64 tx_control_frame; ++ u64 tx_drop; ++ u64 tx_jabber; ++ u64 tx_fcs_error; ++ u64 tx_fragments; ++ ++ u64 rx_bytes; ++ u64 rx_packets; ++ u64 rx_mcast_packets; ++ u64 rx_bcast_packets; ++ u64 rx_control_frames; ++ u64 rx_unknown_opcode; ++ u64 rx_drop; ++ u64 rx_jabber; ++ u64 rx_fcs_error; ++ u64 rx_alignment_error; ++ u64 rx_frame_length_error; ++ u64 rx_code_error; ++ u64 rx_fragments; ++ ++ u64 rx_pause; /* BPC */ ++ u64 rx_zero_pause; /* BPC Pause cancellation */ ++ u64 tx_pause; /* BPC */ ++ u64 tx_zero_pause; /* BPC Pause cancellation */ ++ u64 rx_fcoe_pause; /* BPC */ ++ u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */ ++ u64 tx_fcoe_pause; /* BPC */ ++ u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */ ++}; ++ ++/** ++ * Port statistics. ++ */ ++union bfa_pport_stats_u { ++ struct bfa_pport_fc_stats_s fc; ++ struct bfa_pport_eth_stats_s eth; ++}; ++ ++/** ++ * Port FCP mappings. ++ */ ++struct bfa_pport_fcpmap_s { ++ char osdevname[256]; ++ u32 bus; ++ u32 target; ++ u32 oslun; ++ u32 fcid; ++ wwn_t nwwn; ++ wwn_t pwwn; ++ u64 fcplun; ++ char luid[256]; ++}; ++ ++/** ++ * Port RNID info. ++ */ ++struct bfa_pport_rnid_s { ++ wwn_t wwn; ++ u32 unittype; ++ u32 portid; ++ u32 attached_nodes_num; ++ u16 ip_version; ++ u16 udp_port; ++ u8 ipaddr[16]; ++ u16 rsvd; ++ u16 topologydiscoveryflags; ++}; ++ ++/** ++ * Link state information ++ */ ++struct bfa_pport_link_s { ++ u8 linkstate; /* Link state bfa_pport_linkstate */ ++ u8 linkstate_rsn; /* bfa_pport_linkstate_rsn_t */ ++ u8 topology; /* P2P/LOOP bfa_pport_topology */ ++ u8 speed; /* Link speed (1/2/4/8 G) */ ++ u32 linkstate_opt; /* Linkstate optional data (debug) */ ++ u8 trunked; /* Trunked or not (1 or 0) */ ++ u8 resvd[3]; ++ struct bfa_qos_attr_s qos_attr; /* QoS Attributes */ ++ struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */ ++ union { ++ struct { ++ u8 tmaster;/* Trunk Master or ++ * not (1 or 0) */ ++ u8 tlinks; /* Trunk links bitmap ++ * (linkup) */ ++ u8 resv1; /* Reserved */ ++ } trunk_info; ++ ++ struct { ++ u8 myalpa; /* alpa claimed */ ++ u8 login_req; /* Login required or ++ * not (1 or 0) */ ++ u8 alpabm_val;/* alpa bitmap valid ++ * or not (1 or 0) */ ++ struct fc_alpabm_s alpabm; /* alpa bitmap */ ++ } loop_info; ++ } tl; ++}; ++ ++#endif /* __BFA_DEFS_PPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_qos.h b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h +new file mode 100644 +index 0000000..aadbacd +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h +@@ -0,0 +1,99 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_QOS_H__ ++#define __BFA_DEFS_QOS_H__ ++ ++/** ++ * QoS states ++ */ ++enum bfa_qos_state { ++ BFA_QOS_ONLINE = 1, /* QoS is online */ ++ BFA_QOS_OFFLINE = 2, /* QoS is offline */ ++}; ++ ++ ++/** ++ * QoS Priority levels. ++ */ ++enum bfa_qos_priority { ++ BFA_QOS_UNKNOWN = 0, ++ BFA_QOS_HIGH = 1, /* QoS Priority Level High */ ++ BFA_QOS_MED = 2, /* QoS Priority Level Medium */ ++ BFA_QOS_LOW = 3, /* QoS Priority Level Low */ ++}; ++ ++ ++/** ++ * QoS bandwidth allocation for each priority level ++ */ ++enum bfa_qos_bw_alloc { ++ BFA_QOS_BW_HIGH = 60, /* bandwidth allocation for High */ ++ BFA_QOS_BW_MED = 30, /* bandwidth allocation for Medium */ ++ BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */ ++}; ++ ++/** ++ * QoS attribute returned in QoS Query ++ */ ++struct bfa_qos_attr_s { ++ enum bfa_qos_state state; /* QoS current state */ ++ u32 total_bb_cr; /* Total BB Credits */ ++}; ++ ++/** ++ * These fields should be displayed only from the CLI. ++ * There will be a separate BFAL API (get_qos_vc_attr ?) ++ * to retrieve this. ++ * ++ */ ++#define BFA_QOS_MAX_VC 16 ++ ++struct bfa_qos_vc_info_s { ++ u8 vc_credit; ++ u8 borrow_credit; ++ u8 priority; ++ u8 resvd; ++}; ++ ++struct bfa_qos_vc_attr_s { ++ u16 total_vc_count; /* Total VC Count */ ++ u16 shared_credit; ++ u32 elp_opmode_flags; ++ struct bfa_qos_vc_info_s vc_info[BFA_QOS_MAX_VC]; /* as many as ++ * total_vc_count */ ++}; ++ ++/** ++ * QoS statistics ++ */ ++struct bfa_qos_stats_s { ++ u32 flogi_sent; /* QoS Flogi sent */ ++ u32 flogi_acc_recvd; /* QoS Flogi Acc received */ ++ u32 flogi_rjt_recvd; /* QoS Flogi rejects received */ ++ u32 flogi_retries; /* QoS Flogi retries */ ++ ++ u32 elp_recvd; /* QoS ELP received */ ++ u32 elp_accepted; /* QoS ELP Accepted */ ++ u32 elp_rejected; /* QoS ELP rejected */ ++ u32 elp_dropped; /* QoS ELP dropped */ ++ ++ u32 qos_rscn_recvd; /* QoS RSCN received */ ++ u32 rsvd; /* padding for 64 bit alignment */ ++}; ++ ++#endif /* __BFA_DEFS_QOS_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_rport.h b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h +new file mode 100644 +index 0000000..e0af59d +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h +@@ -0,0 +1,199 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_RPORT_H__ ++#define __BFA_DEFS_RPORT_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/** ++ * FCS remote port states ++ */ ++enum bfa_rport_state { ++ BFA_RPORT_UNINIT = 0, /* PORT is not yet initialized */ ++ BFA_RPORT_OFFLINE = 1, /* rport is offline */ ++ BFA_RPORT_PLOGI = 2, /* PLOGI to rport is in progress */ ++ BFA_RPORT_ONLINE = 3, /* login to rport is complete */ ++ BFA_RPORT_PLOGI_RETRY = 4, /* retrying login to rport */ ++ BFA_RPORT_NSQUERY = 5, /* nameserver query */ ++ BFA_RPORT_ADISC = 6, /* ADISC authentication */ ++ BFA_RPORT_LOGO = 7, /* logging out with rport */ ++ BFA_RPORT_LOGORCV = 8, /* handling LOGO from rport */ ++ BFA_RPORT_NSDISC = 9, /* re-discover rport */ ++}; ++ ++/** ++ * Rport Scsi Function : Initiator/Target. ++ */ ++enum bfa_rport_function { ++ BFA_RPORT_INITIATOR = 0x01, /* SCSI Initiator */ ++ BFA_RPORT_TARGET = 0x02, /* SCSI Target */ ++}; ++ ++/** ++ * port/node symbolic names for rport ++ */ ++#define BFA_RPORT_SYMNAME_MAXLEN 255 ++struct bfa_rport_symname_s { ++ char symname[BFA_RPORT_SYMNAME_MAXLEN]; ++}; ++ ++struct bfa_rport_hal_stats_s { ++ u32 sm_un_cr; /* uninit: create events */ ++ u32 sm_un_unexp; /* uninit: exception events */ ++ u32 sm_cr_on; /* created: online events */ ++ u32 sm_cr_del; /* created: delete events */ ++ u32 sm_cr_hwf; /* created: IOC down */ ++ u32 sm_cr_unexp; /* created: exception events */ ++ u32 sm_fwc_rsp; /* fw create: f/w responses */ ++ u32 sm_fwc_del; /* fw create: delete events */ ++ u32 sm_fwc_off; /* fw create: offline events */ ++ u32 sm_fwc_hwf; /* fw create: IOC down */ ++ u32 sm_fwc_unexp; /* fw create: exception events*/ ++ u32 sm_on_off; /* online: offline events */ ++ u32 sm_on_del; /* online: delete events */ ++ u32 sm_on_hwf; /* online: IOC down events */ ++ u32 sm_on_unexp; /* online: exception events */ ++ u32 sm_fwd_rsp; /* fw delete: fw responses */ ++ u32 sm_fwd_del; /* fw delete: delete events */ ++ u32 sm_fwd_hwf; /* fw delete: IOC down events */ ++ u32 sm_fwd_unexp; /* fw delete: exception events*/ ++ u32 sm_off_del; /* offline: delete events */ ++ u32 sm_off_on; /* offline: online events */ ++ u32 sm_off_hwf; /* offline: IOC down events */ ++ u32 sm_off_unexp; /* offline: exception events */ ++ u32 sm_del_fwrsp; /* delete: fw responses */ ++ u32 sm_del_hwf; /* delete: IOC down events */ ++ u32 sm_del_unexp; /* delete: exception events */ ++ u32 sm_delp_fwrsp; /* delete pend: fw responses */ ++ u32 sm_delp_hwf; /* delete pend: IOC downs */ ++ u32 sm_delp_unexp; /* delete pend: exceptions */ ++ u32 sm_offp_fwrsp; /* off-pending: fw responses */ ++ u32 sm_offp_del; /* off-pending: deletes */ ++ u32 sm_offp_hwf; /* off-pending: IOC downs */ ++ u32 sm_offp_unexp; /* off-pending: exceptions */ ++ u32 sm_iocd_off; /* IOC down: offline events */ ++ u32 sm_iocd_del; /* IOC down: delete events */ ++ u32 sm_iocd_on; /* IOC down: online events */ ++ u32 sm_iocd_unexp; /* IOC down: exceptions */ ++ u32 rsvd; ++}; ++ ++/** ++ * FCS remote port statistics ++ */ ++struct bfa_rport_stats_s { ++ u32 offlines; /* remote port offline count */ ++ u32 onlines; /* remote port online count */ ++ u32 rscns; /* RSCN affecting rport */ ++ u32 plogis; /* plogis sent */ ++ u32 plogi_accs; /* plogi accepts */ ++ u32 plogi_timeouts; /* plogi timeouts */ ++ u32 plogi_rejects; /* rcvd plogi rejects */ ++ u32 plogi_failed; /* local failure */ ++ u32 plogi_rcvd; /* plogis rcvd */ ++ u32 prli_rcvd; /* inbound PRLIs */ ++ u32 adisc_rcvd; /* ADISCs received */ ++ u32 adisc_rejects; /* recvd ADISC rejects */ ++ u32 adisc_sent; /* ADISC requests sent */ ++ u32 adisc_accs; /* ADISC accepted by rport */ ++ u32 adisc_failed; /* ADISC failed (no response) */ ++ u32 adisc_rejected; /* ADISC rejected by us */ ++ u32 logos; /* logos sent */ ++ u32 logo_accs; /* LOGO accepts from rport */ ++ u32 logo_failed; /* LOGO failures */ ++ u32 logo_rejected; /* LOGO rejects from rport */ ++ u32 logo_rcvd; /* LOGO from remote port */ ++ ++ u32 rpsc_rcvd; /* RPSC received */ ++ u32 rpsc_rejects; /* recvd RPSC rejects */ ++ u32 rpsc_sent; /* RPSC requests sent */ ++ u32 rpsc_accs; /* RPSC accepted by rport */ ++ u32 rpsc_failed; /* RPSC failed (no response) */ ++ u32 rpsc_rejected; /* RPSC rejected by us */ ++ ++ u32 rsvd; ++ struct bfa_rport_hal_stats_s hal_stats; /* BFA rport stats */ ++}; ++ ++/** ++ * Rport's QoS attributes ++ */ ++struct bfa_rport_qos_attr_s { ++ enum bfa_qos_priority qos_priority; /* rport's QoS priority */ ++ u32 qos_flow_id; /* QoS flow Id */ ++}; ++ ++/** ++ * FCS remote port attributes returned in queries ++ */ ++struct bfa_rport_attr_s { ++ wwn_t nwwn; /* node wwn */ ++ wwn_t pwwn; /* port wwn */ ++ enum fc_cos cos_supported; /* supported class of services */ ++ u32 pid; /* port ID */ ++ u32 df_sz; /* Max payload size */ ++ enum bfa_rport_state state; /* Rport State machine state */ ++ enum fc_cos fc_cos; /* FC classes of services */ ++ bfa_boolean_t cisc; /* CISC capable device */ ++ struct bfa_rport_symname_s symname; /* Symbolic Name */ ++ enum bfa_rport_function scsi_function; /* Initiator/Target */ ++ struct bfa_rport_qos_attr_s qos_attr; /* qos attributes */ ++ enum bfa_pport_speed curr_speed; /* operating speed got from ++ * RPSC ELS. UNKNOWN, if RPSC ++ * is not supported */ ++ bfa_boolean_t trl_enforced; /* TRL enforced ? TRUE/FALSE */ ++ enum bfa_pport_speed assigned_speed; /* Speed assigned by the user. ++ * will be used if RPSC is not ++ * supported by the rport */ ++}; ++ ++#define bfa_rport_aen_qos_data_t struct bfa_rport_qos_attr_s ++ ++/** ++ * BFA remote port events ++ * Arguments below are in BFAL context from Mgmt ++ * BFA_RPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn ++ * BFA_RPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn ++ * BFA_RPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn ++ * BFA_RPORT_AEN_QOS_PRIO: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn, prio ++ * BFA_RPORT_AEN_QOS_FLOWID:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn, flow_id ++ */ ++enum bfa_rport_aen_event { ++ BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */ ++ BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */ ++ BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */ ++ BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */ ++ BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */ ++}; ++ ++struct bfa_rport_aen_data_s { ++ u16 vf_id; /* vf_id of this logical port */ ++ u16 rsvd[3]; ++ wwn_t ppwwn; /* WWN of its physical port */ ++ wwn_t lpwwn; /* WWN of this logical port */ ++ wwn_t rpwwn; /* WWN of this remote port */ ++ union { ++ bfa_rport_aen_qos_data_t qos; ++ } priv; ++}; ++ ++#endif /* __BFA_DEFS_RPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h +new file mode 100644 +index 0000000..cdceaeb +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h +@@ -0,0 +1,255 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_STATUS_H__ ++#define __BFA_DEFS_STATUS_H__ ++ ++/** ++ * API status return values ++ * ++ * NOTE: The error msgs are auto generated from the comments. Only singe line ++ * comments are supported ++ */ ++enum bfa_status { ++ BFA_STATUS_OK = 0, /* Success */ ++ BFA_STATUS_FAILED = 1, /* Operation failed */ ++ BFA_STATUS_EINVAL = 2, /* Invalid params Check input ++ * parameters */ ++ BFA_STATUS_ENOMEM = 3, /* Out of resources */ ++ BFA_STATUS_ENOSYS = 4, /* Function not implemented */ ++ BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if ++ * persists, contact support */ ++ BFA_STATUS_EPROTOCOL = 6, /* Protocol error */ ++ BFA_STATUS_ENOFCPORTS = 7, /* No FC ports resources */ ++ BFA_STATUS_NOFLASH = 8, /* Flash not present */ ++ BFA_STATUS_BADFLASH = 9, /* Flash is corrupted or bad */ ++ BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */ ++ BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */ ++ BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted ++ * contact support */ ++ BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */ ++ BFA_STATUS_ABORTED = 14, /* Operation aborted */ ++ BFA_STATUS_NODEV = 15, /* Dev is not present */ ++ BFA_STATUS_HDMA_FAILED = 16, /* Host dma failed contact support */ ++ BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */ ++ BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */ ++ BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */ ++ BFA_STATUS_FCPT_LS_RJT = 20, /* Got LS_RJT for FC Pass ++ * through Req */ ++ BFA_STATUS_VPORT_EXISTS = 21, /* VPORT already exists */ ++ BFA_STATUS_VPORT_MAX = 22, /* Reached max VPORT supported ++ * limit */ ++ BFA_STATUS_UNSUPP_SPEED = 23, /* Invalid Speed Check speed ++ * setting */ ++ BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */ ++ BFA_STATUS_CNFG_FAILED = 25, /* Setting can not be persisted */ ++ BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */ ++ BFA_STATUS_NO_ADAPTER = 27, /* No Brocade Adapter Found */ ++ BFA_STATUS_LINKDOWN = 28, /* Link is down - Check or replace ++ * SFP/cable */ ++ BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */ ++ BFA_STATUS_UNKNOWN_VWWN = 30, /* VPORT PWWN not found */ ++ BFA_STATUS_NSLOGIN_FAILED = 31, /* Nameserver login failed */ ++ BFA_STATUS_NO_RPORTS = 32, /* No remote ports found */ ++ BFA_STATUS_NSQUERY_FAILED = 33, /* Nameserver query failed */ ++ BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */ ++ BFA_STATUS_RPORT_OFFLINE = 35, /* RPORT is not online */ ++ BFA_STATUS_TGTOPEN_FAILED = 36, /* Remote SCSI target open failed */ ++ BFA_STATUS_BAD_LUNS = 37, /* No valid LUNs found */ ++ BFA_STATUS_IO_FAILURE = 38, /* SCSI target IO failure */ ++ BFA_STATUS_NO_FABRIC = 39, /* No switched fabric present */ ++ BFA_STATUS_EBADF = 40, /* Bad file descriptor */ ++ BFA_STATUS_EINTR = 41, /* A signal was caught during ioctl */ ++ BFA_STATUS_EIO = 42, /* I/O error */ ++ BFA_STATUS_ENOTTY = 43, /* Inappropriate I/O control ++ * operation */ ++ BFA_STATUS_ENXIO = 44, /* No such device or address */ ++ BFA_STATUS_EFOPEN = 45, /* Failed to open file */ ++ BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */ ++ BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port ++ * first */ ++ BFA_STATUS_BADFRMHDR = 48, /* Bad frame header */ ++ BFA_STATUS_BADFRMSZ = 49, /* Bad frame size check and replace ++ * SFP/cable */ ++ BFA_STATUS_MISSINGFRM = 50, /* Missing frame check and replace ++ * SFP/cable */ ++ BFA_STATUS_LINKTIMEOUT = 51, /* Link timeout check and replace ++ * SFP/cable */ ++ BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the ++ * rport */ ++ BFA_STATUS_CHECKSUM_FAIL = 53, /* checksum failure */ ++ BFA_STATUS_GZME_FAILED = 54, /* Get zone member query failed */ ++ BFA_STATUS_SCSISTART_REQD = 55, /* SCSI disk require START command */ ++ BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists ++ * contact support */ ++ BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */ ++ BFA_STATUS_MISMATCH = 58, /* Version mismatch */ ++ BFA_STATUS_IOC_ENABLED = 59, /* IOC is already enabled */ ++ BFA_STATUS_ADAPTER_ENABLED = 60, /* Adapter is not disabled disable ++ * adapter first */ ++ BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational. Enable IOC ++ * and if it still fails, ++ * contact support */ ++ BFA_STATUS_ADDR_MAP_FAILURE = 62, /* PCI base address not mapped ++ * in OS */ ++ BFA_STATUS_SAME_NAME = 63, /* Name exists! use a different ++ * name */ ++ BFA_STATUS_PENDING = 64, /* API completes asynchronously */ ++ BFA_STATUS_8G_SPD = 65, /* Speed setting not valid for ++ * 8G HBA */ ++ BFA_STATUS_4G_SPD = 66, /* Speed setting not valid for ++ * 4G HBA */ ++ BFA_STATUS_AD_IS_ENABLE = 67, /* Adapter is already enabled */ ++ BFA_STATUS_EINVAL_TOV = 68, /* Invalid path failover TOV */ ++ BFA_STATUS_EINVAL_QDEPTH = 69, /* Invalid queue depth value */ ++ BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version ++ * mismatch */ ++ BFA_STATUS_DIAG_BUSY = 71, /* diag busy */ ++ BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */ ++ BFA_STATUS_BEACON_OFF = 73, /* Port Beacon already off */ ++ BFA_STATUS_LBEACON_ON = 74, /* Link End-to-End Beacon already ++ * on */ ++ BFA_STATUS_LBEACON_OFF = 75, /* Link End-to-End Beacon already ++ * off */ ++ BFA_STATUS_PORT_NOT_INITED = 76, /* Port not initialized */ ++ BFA_STATUS_RPSC_ENABLED = 77, /* Target has a valid speed */ ++ BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */ ++ BFA_STATUS_BAD_FILE = 79, /* Not a valid Brocade Boot Code ++ * file */ ++ BFA_STATUS_RLIM_EN = 80, /* Target rate limiting is already ++ * enabled */ ++ BFA_STATUS_RLIM_DIS = 81, /* Target rate limiting is already ++ * disabled */ ++ BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */ ++ BFA_STATUS_ADAPTER_DISABLED = 83, /* Adapter is already disabled */ ++ BFA_STATUS_BIOS_DISABLED = 84, /* Bios is already disabled */ ++ BFA_STATUS_AUTH_ENABLED = 85, /* Authentication is already ++ * enabled */ ++ BFA_STATUS_AUTH_DISABLED = 86, /* Authentication is already ++ * disabled */ ++ BFA_STATUS_ERROR_TRL_ENABLED = 87, /* Target rate limiting is ++ * enabled */ ++ BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */ ++ BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */ ++ BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact ++ * support */ ++ BFA_STATUS_INVALID_DEVID = 91, /* Invalid device id provided */ ++ BFA_STATUS_QOS_ENABLED = 92, /* QOS is already enabled */ ++ BFA_STATUS_QOS_DISABLED = 93, /* QOS is already disabled */ ++ BFA_STATUS_INCORRECT_DRV_CONFIG = 94, /* Check configuration ++ * key/value pair */ ++ BFA_STATUS_REG_FAIL = 95, /* Can't read windows registry */ ++ BFA_STATUS_IM_INV_CODE = 96, /* Invalid IOCTL code */ ++ BFA_STATUS_IM_INV_VLAN = 97, /* Invalid VLAN ID */ ++ BFA_STATUS_IM_INV_ADAPT_NAME = 98, /* Invalid adapter name */ ++ BFA_STATUS_IM_LOW_RESOURCES = 99, /* Memory allocation failure in ++ * driver */ ++ BFA_STATUS_IM_VLANID_IS_PVID = 100, /* Given VLAN id same as PVID */ ++ BFA_STATUS_IM_VLANID_EXISTS = 101, /* Given VLAN id already exists */ ++ BFA_STATUS_IM_FW_UPDATE_FAIL = 102, /* Updating firmware with new ++ * VLAN ID failed */ ++ BFA_STATUS_PORTLOG_ENABLED = 103, /* Port Log is already enabled */ ++ BFA_STATUS_PORTLOG_DISABLED = 104, /* Port Log is already disabled */ ++ BFA_STATUS_FILE_NOT_FOUND = 105, /* Specified file could not be ++ * found */ ++ BFA_STATUS_QOS_FC_ONLY = 106, /* QOS can be enabled for FC mode ++ * only */ ++ BFA_STATUS_RLIM_FC_ONLY = 107, /* RATELIM can be enabled for FC mode ++ * only */ ++ BFA_STATUS_CT_SPD = 108, /* Invalid speed selection for Catapult. */ ++ BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */ ++ BFA_STATUS_CEE_NOT_DN = 110, /* eth port is not at down state, please ++ * bring down first */ ++ BFA_STATUS_10G_SPD = 111, /* Speed setting not valid for 10G HBA */ ++ BFA_STATUS_IM_INV_TEAM_NAME = 112, /* Invalid team name */ ++ BFA_STATUS_IM_DUP_TEAM_NAME = 113, /* Given team name already ++ * exists */ ++ BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part ++ * of another team */ ++ BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured. ++ * Delete all VLANs before ++ * creating team */ ++ BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured ++ * for adapters */ ++ BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds ++ * configured for adapters */ ++ BFA_STATUS_IM_MTU_MISMATCH = 118, /* Mismatching MTUs configured for ++ * adapters */ ++ BFA_STATUS_IM_RSS_MISMATCH = 119, /* Mismatching RSS parameters ++ * configured for adapters */ ++ BFA_STATUS_IM_HDS_MISMATCH = 120, /* Mismatching HDS parameters ++ * configured for adapters */ ++ BFA_STATUS_IM_OFFLOAD_MISMATCH = 121, /* Mismatching offload ++ * parameters configured for ++ * adapters */ ++ BFA_STATUS_IM_PORT_PARAMS = 122, /* Error setting port parameters */ ++ BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123, /* Port is not part of team */ ++ BFA_STATUS_IM_CANNOT_REM_PRI = 124, /* Primary adapter cannot be ++ * removed. Change primary before ++ * removing */ ++ BFA_STATUS_IM_MAX_PORTS_REACHED = 125, /* Exceeding maximum ports ++ * per team */ ++ BFA_STATUS_IM_LAST_PORT_DELETE = 126, /* Last port in team being ++ * deleted */ ++ BFA_STATUS_IM_NO_DRIVER = 127, /* IM driver is not installed */ ++ BFA_STATUS_IM_MAX_VLANS_REACHED = 128, /* Exceeding maximum VLANs ++ * per port */ ++ BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129, /* Bios speed config not ++ * allowed for CNA */ ++ BFA_STATUS_NO_MINPORT_DRIVER = 130, /* Miniport driver is not ++ * loaded */ ++ BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */ ++ BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */ ++ BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */ ++ BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */ ++ BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */ ++ BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */ ++ BFA_STATUS_IM_PVID_REMOVE = 137, /* Cannot remove port vlan (PVID) */ ++ BFA_STATUS_IM_PVID_EDIT = 138, /* Cannot edit port vlan (PVID) */ ++ BFA_STATUS_CNA_NO_BOOT = 139, /* Boot upload not allowed for CNA */ ++ BFA_STATUS_IM_PVID_NON_ZERO = 140, /* Port VLAN ID (PVID) is Set to ++ * Non-Zero Value */ ++ BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141, /* Acquiring Network ++ * Subsytem Lock Failed.Please ++ * try after some time */ ++ BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem ++ * handle Failed. Please try ++ * after some time */ ++ BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not ++ * Enabled on this port */ ++ BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient ++ * permissions to execute the BCU ++ * application */ ++ BFA_STATUS_IM_INV_VLAN_NAME = 145, /* Invalid/Reserved Vlan name ++ * string. The name is not allowed ++ * for the normal Vlans */ ++ BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */ ++ BFA_STATUS_IM_PASSTHRU_EDIT = 147, /* Can not edit passthru vlan id */ ++ BFA_STATUS_IM_BIND_FAILED = 148, /*! < IM Driver bind operation ++ * failed */ ++ BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation ++ * failed */ ++ BFA_STATUS_MAX_VAL /* Unknown error code */ ++}; ++#define bfa_status_t enum bfa_status ++ ++enum bfa_eproto_status { ++ BFA_EPROTO_BAD_ACCEPT = 0, ++ BFA_EPROTO_UNKNOWN_RSP = 1 ++}; ++#define bfa_eproto_status_t enum bfa_eproto_status ++ ++#endif /* __BFA_DEFS_STATUS_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tin.h b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h +new file mode 100644 +index 0000000..e05a2db +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h +@@ -0,0 +1,118 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_TIN_H__ ++#define __BFA_DEFS_TIN_H__ ++ ++#include ++#include ++ ++/** ++ * FCS tin states ++ */ ++enum bfa_tin_state_e { ++ BFA_TIN_SM_OFFLINE = 0, /* tin is offline */ ++ BFA_TIN_SM_WOS_LOGIN = 1, /* Waiting PRLI ACC/RJT from ULP */ ++ BFA_TIN_SM_WFW_ONLINE = 2, /* Waiting ACK to PRLI ACC from FW */ ++ BFA_TIN_SM_ONLINE = 3, /* tin login is complete */ ++ BFA_TIN_SM_WIO_RELOGIN = 4, /* tin relogin is in progress */ ++ BFA_TIN_SM_WIO_LOGOUT = 5, /* Processing of PRLO req from ++ * Initiator is in progress ++ */ ++ BFA_TIN_SM_WOS_LOGOUT = 6, /* Processing of PRLO req from ++ * Initiator is in progress ++ */ ++ BFA_TIN_SM_WIO_CLEAN = 7, /* Waiting for IO cleanup before tin ++ * is offline. This can be triggered ++ * by RPORT LOGO (rcvd/sent) or by ++ * PRLO (rcvd/sent) ++ */ ++}; ++ ++struct bfa_prli_req_s { ++ struct fchs_s fchs; ++ struct fc_prli_s prli_payload; ++}; ++ ++struct bfa_prlo_req_s { ++ struct fchs_s fchs; ++ struct fc_prlo_s prlo_payload; ++}; ++ ++void bfa_tin_send_login_rsp(void *bfa_tin, u32 login_rsp, ++ struct fc_ls_rjt_s rjt_payload); ++void bfa_tin_send_logout_rsp(void *bfa_tin, u32 logout_rsp, ++ struct fc_ls_rjt_s rjt_payload); ++/** ++ * FCS target port statistics ++ */ ++struct bfa_tin_stats_s { ++ u32 onlines; /* ITN nexus onlines (PRLI done) */ ++ u32 offlines; /* ITN Nexus offlines */ ++ u32 prli_req_parse_err; /* prli req parsing errors */ ++ u32 prli_rsp_rjt; /* num prli rsp rejects sent */ ++ u32 prli_rsp_acc; /* num prli rsp accepts sent */ ++ u32 cleanup_comps; /* ITN cleanup completions */ ++}; ++ ++/** ++ * FCS tin attributes returned in queries ++ */ ++struct bfa_tin_attr_s { ++ enum bfa_tin_state_e state; ++ u8 seq_retry; /* Sequence retry supported */ ++ u8 rsvd[3]; ++}; ++ ++/** ++ * BFA TIN async event data structure for BFAL ++ */ ++enum bfa_tin_aen_event { ++ BFA_TIN_AEN_ONLINE = 1, /* Target online */ ++ BFA_TIN_AEN_OFFLINE = 2, /* Target offline */ ++ BFA_TIN_AEN_DISCONNECT = 3, /* Target disconnected */ ++}; ++ ++/** ++ * BFA TIN event data structure. ++ */ ++struct bfa_tin_aen_data_s { ++ u16 vf_id; /* vf_id of the IT nexus */ ++ u16 rsvd[3]; ++ wwn_t lpwwn; /* WWN of logical port */ ++ wwn_t rpwwn; /* WWN of remote(target) port */ ++}; ++ ++/** ++ * Below APIs are needed from BFA driver ++ * Move these to BFA driver public header file? ++ */ ++/* TIN rcvd new PRLI & gets bfad_tin_t ptr from driver this callback */ ++void *bfad_tin_rcvd_login_req(void *bfad_tm_port, void *bfa_tin, ++ wwn_t rp_wwn, u32 rp_fcid, ++ struct bfa_prli_req_s prli_req); ++/* TIN rcvd new PRLO */ ++void bfad_tin_rcvd_logout_req(void *bfad_tin, wwn_t rp_wwn, u32 rp_fcid, ++ struct bfa_prlo_req_s prlo_req); ++/* TIN is online and ready for IO */ ++void bfad_tin_online(void *bfad_tin); ++/* TIN is offline and BFA driver can shutdown its upper stack */ ++void bfad_tin_offline(void *bfad_tin); ++/* TIN does not need this BFA driver tin tag anymore, so can be freed */ ++void bfad_tin_res_free(void *bfad_tin); ++ ++#endif /* __BFA_DEFS_TIN_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h +new file mode 100644 +index 0000000..31881d2 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_TSENSOR_H__ ++#define __BFA_DEFS_TSENSOR_H__ ++ ++#include ++#include ++ ++/** ++ * Temperature sensor status values ++ */ ++enum bfa_tsensor_status { ++ BFA_TSENSOR_STATUS_UNKNOWN = 1, /* unkown status */ ++ BFA_TSENSOR_STATUS_FAULTY = 2, /* sensor is faulty */ ++ BFA_TSENSOR_STATUS_BELOW_MIN = 3, /* temperature below mininum */ ++ BFA_TSENSOR_STATUS_NOMINAL = 4, /* normal temperature */ ++ BFA_TSENSOR_STATUS_ABOVE_MAX = 5, /* temperature above maximum */ ++}; ++ ++/** ++ * Temperature sensor attribute ++ */ ++struct bfa_tsensor_attr_s { ++ enum bfa_tsensor_status status; /* temperature sensor status */ ++ u32 value; /* current temperature in celsius */ ++}; ++ ++#endif /* __BFA_DEFS_TSENSOR_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_types.h b/drivers/scsi/bfa/include/defs/bfa_defs_types.h +new file mode 100644 +index 0000000..4348332 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_types.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_TYPES_H__ ++#define __BFA_DEFS_TYPES_H__ ++ ++#include ++ ++enum bfa_boolean { ++ BFA_FALSE = 0, ++ BFA_TRUE = 1 ++}; ++#define bfa_boolean_t enum bfa_boolean ++ ++#define BFA_STRING_32 32 ++ ++#endif /* __BFA_DEFS_TYPES_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_version.h b/drivers/scsi/bfa/include/defs/bfa_defs_version.h +new file mode 100644 +index 0000000..f8902a2 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_version.h +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#ifndef __BFA_DEFS_VERSION_H__ ++#define __BFA_DEFS_VERSION_H__ ++ ++#define BFA_VERSION_LEN 64 ++ ++#endif +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vf.h b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h +new file mode 100644 +index 0000000..3235be5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h +@@ -0,0 +1,74 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_VF_H__ ++#define __BFA_DEFS_VF_H__ ++ ++#include ++#include ++#include ++ ++/** ++ * VF states ++ */ ++enum bfa_vf_state { ++ BFA_VF_UNINIT = 0, /* fabric is not yet initialized */ ++ BFA_VF_LINK_DOWN = 1, /* link is down */ ++ BFA_VF_FLOGI = 2, /* flogi is in progress */ ++ BFA_VF_AUTH = 3, /* authentication in progress */ ++ BFA_VF_NOFABRIC = 4, /* fabric is not present */ ++ BFA_VF_ONLINE = 5, /* login to fabric is complete */ ++ BFA_VF_EVFP = 6, /* EVFP is in progress */ ++ BFA_VF_ISOLATED = 7, /* port isolated due to vf_id mismatch */ ++}; ++ ++/** ++ * VF statistics ++ */ ++struct bfa_vf_stats_s { ++ u32 flogi_sent; /* Num FLOGIs sent */ ++ u32 flogi_rsp_err; /* FLOGI response errors */ ++ u32 flogi_acc_err; /* FLOGI accept errors */ ++ u32 flogi_accepts; /* FLOGI accepts received */ ++ u32 flogi_rejects; /* FLOGI rejects received */ ++ u32 flogi_unknown_rsp; /* Unknown responses for FLOGI */ ++ u32 flogi_alloc_wait; /* Allocation waits prior to ++ * sending FLOGI ++ */ ++ u32 flogi_rcvd; /* FLOGIs received */ ++ u32 flogi_rejected; /* Incoming FLOGIs rejected */ ++ u32 fabric_onlines; /* Internal fabric online ++ * notification sent to other ++ * modules ++ */ ++ u32 fabric_offlines; /* Internal fabric offline ++ * notification sent to other ++ * modules ++ */ ++ u32 resvd; ++}; ++ ++/** ++ * VF attributes returned in queries ++ */ ++struct bfa_vf_attr_s { ++ enum bfa_vf_state state; /* VF state */ ++ u32 rsvd; ++ wwn_t fabric_name; /* fabric name */ ++}; ++ ++#endif /* __BFA_DEFS_VF_H__ */ +diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vport.h b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h +new file mode 100644 +index 0000000..9f021f4 +--- /dev/null ++++ b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_DEFS_VPORT_H__ ++#define __BFA_DEFS_VPORT_H__ ++ ++#include ++#include ++#include ++ ++/** ++ * VPORT states ++ */ ++enum bfa_vport_state { ++ BFA_FCS_VPORT_UNINIT = 0, ++ BFA_FCS_VPORT_CREATED = 1, ++ BFA_FCS_VPORT_OFFLINE = 1, ++ BFA_FCS_VPORT_FDISC_SEND = 2, ++ BFA_FCS_VPORT_FDISC = 3, ++ BFA_FCS_VPORT_FDISC_RETRY = 4, ++ BFA_FCS_VPORT_ONLINE = 5, ++ BFA_FCS_VPORT_DELETING = 6, ++ BFA_FCS_VPORT_CLEANUP = 6, ++ BFA_FCS_VPORT_LOGO_SEND = 7, ++ BFA_FCS_VPORT_LOGO = 8, ++ BFA_FCS_VPORT_ERROR = 9, ++ BFA_FCS_VPORT_MAX_STATE, ++}; ++ ++/** ++ * vport statistics ++ */ ++struct bfa_vport_stats_s { ++ struct bfa_port_stats_s port_stats; /* base class (port) stats */ ++ /* ++ * TODO - remove ++ */ ++ ++ u32 fdisc_sent; /* num fdisc sent */ ++ u32 fdisc_accepts; /* fdisc accepts */ ++ u32 fdisc_retries; /* fdisc retries */ ++ u32 fdisc_timeouts; /* fdisc timeouts */ ++ u32 fdisc_rsp_err; /* fdisc response error */ ++ u32 fdisc_acc_bad; /* bad fdisc accepts */ ++ u32 fdisc_rejects; /* fdisc rejects */ ++ u32 fdisc_unknown_rsp; ++ /* ++ *!< fdisc rsp unknown error ++ */ ++ u32 fdisc_alloc_wait;/* fdisc req (fcxp)alloc wait */ ++ ++ u32 logo_alloc_wait;/* logo req (fcxp) alloc wait */ ++ u32 logo_sent; /* logo sent */ ++ u32 logo_accepts; /* logo accepts */ ++ u32 logo_rejects; /* logo rejects */ ++ u32 logo_rsp_err; /* logo rsp errors */ ++ u32 logo_unknown_rsp; ++ /* logo rsp unknown errors */ ++ ++ u32 fab_no_npiv; /* fabric does not support npiv */ ++ ++ u32 fab_offline; /* offline events from fab SM */ ++ u32 fab_online; /* online events from fab SM */ ++ u32 fab_cleanup; /* cleanup request from fab SM */ ++ u32 rsvd; ++}; ++ ++/** ++ * BFA vport attribute returned in queries ++ */ ++struct bfa_vport_attr_s { ++ struct bfa_port_attr_s port_attr; /* base class (port) attributes */ ++ enum bfa_vport_state vport_state; /* vport state */ ++ u32 rsvd; ++}; ++ ++#endif /* __BFA_DEFS_VPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb.h b/drivers/scsi/bfa/include/fcb/bfa_fcb.h +new file mode 100644 +index 0000000..2963b0b +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb.h +@@ -0,0 +1,33 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcb.h BFA FCS callback interfaces ++ */ ++ ++#ifndef __BFA_FCB_H__ ++#define __BFA_FCB_H__ ++ ++/** ++ * fcb Main fcs callbacks ++ */ ++ ++void bfa_fcb_exit(struct bfad_s *bfad); ++ ++ ++ ++#endif /* __BFA_FCB_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h +new file mode 100644 +index 0000000..a6c70ae +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h +@@ -0,0 +1,76 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++* : bfad_fcpim.h - BFA FCS initiator mode remote port callbacks ++ */ ++ ++#ifndef __BFAD_FCB_FCPIM_H__ ++#define __BFAD_FCB_FCPIM_H__ ++ ++struct bfad_itnim_s; ++ ++/* ++ * RPIM callbacks ++ */ ++ ++/** ++ * Memory allocation for remote port instance. Called before PRLI is ++ * initiated to the remote target port. ++ * ++ * @param[in] bfad - driver instance ++ * @param[out] itnim - FCS remote port (IM) instance ++ * @param[out] itnim_drv - driver remote port (IM) instance ++ * ++ * @return None ++ */ ++void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim, ++ struct bfad_itnim_s **itnim_drv); ++ ++/** ++ * Free remote port (IM) instance. ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] itnim_drv - driver remote port instance ++ * ++ * @return None ++ */ ++void bfa_fcb_itnim_free(struct bfad_s *bfad, ++ struct bfad_itnim_s *itnim_drv); ++ ++/** ++ * Notification of when login with a remote target device is complete. ++ * ++ * @param[in] itnim_drv - driver remote port instance ++ * ++ * @return None ++ */ ++void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv); ++ ++/** ++ * Notification when login with the remote device is severed. ++ * ++ * @param[in] itnim_drv - driver remote port instance ++ * ++ * @return None ++ */ ++void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv); ++ ++void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv); ++void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv); ++ ++#endif /* __BFAD_FCB_FCPIM_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h +new file mode 100644 +index 0000000..5fd7f98 +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h +@@ -0,0 +1,113 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcb_port.h BFA FCS virtual port driver interfaces ++ */ ++ ++#ifndef __BFA_FCB_PORT_H__ ++#define __BFA_FCB_PORT_H__ ++ ++#include ++/** ++ * fcs_port_fcb FCS port driver interfaces ++ */ ++ ++/* ++ * Forward declarations ++ */ ++struct bfad_port_s; ++ ++/* ++ * Callback functions from BFA FCS to driver ++ */ ++ ++/** ++ * Call from FCS to driver module when a port is instantiated. The port ++ * can be a base port or a virtual port with in the base fabric or ++ * a virtual fabric. ++ * ++ * On this callback, driver is supposed to create scsi_host, scsi_tgt or ++ * network interfaces bases on ports personality/roles. ++ * ++ * base port of base fabric: vf_drv == NULL && vp_drv == NULL ++ * vport of base fabric: vf_drv == NULL && vp_drv != NULL ++ * base port of VF: vf_drv != NULL && vp_drv == NULL ++ * vport of VF: vf_drv != NULL && vp_drv != NULL ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] port - FCS port instance ++ * @param[in] roles - port roles: IM, TM, IP ++ * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF) ++ * @param[in] vp_drv - vport driver instance, NULL if base port ++ * ++ * @return None ++ */ ++struct bfad_port_s *bfa_fcb_port_new(struct bfad_s *bfad, ++ struct bfa_fcs_port_s *port, ++ enum bfa_port_role roles, struct bfad_vf_s *vf_drv, ++ struct bfad_vport_s *vp_drv); ++ ++/** ++ * Call from FCS to driver module when a port is deleted. The port ++ * can be a base port or a virtual port with in the base fabric or ++ * a virtual fabric. ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] roles - port roles: IM, TM, IP ++ * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF) ++ * @param[in] vp_drv - vport driver instance, NULL if base port ++ * ++ * @return None ++ */ ++void bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv); ++ ++/** ++ * Notification when port transitions to ONLINE state. ++ * ++ * Online notification is a logical link up for the local port. This ++ * notification is sent after a successfull FLOGI, or a successful ++ * link initialization in proviate-loop or N2N topologies. ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] roles - port roles: IM, TM, IP ++ * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF) ++ * @param[in] vp_drv - vport driver instance, NULL if base port ++ * ++ * @return None ++ */ ++void bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv); ++ ++/** ++ * Notification when port transitions to OFFLINE state. ++ * ++ * Offline notification is a logical link down for the local port. ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] roles - port roles: IM, TM, IP ++ * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF) ++ * @param[in] vp_drv - vport driver instance, NULL if base port ++ * ++ * @return None ++ */ ++void bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles, ++ struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv); ++ ++ ++#endif /* __BFA_FCB_PORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h +new file mode 100644 +index 0000000..e0261bb +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h +@@ -0,0 +1,80 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcb_rport.h BFA FCS rport driver interfaces ++ */ ++ ++#ifndef __BFA_FCB_RPORT_H__ ++#define __BFA_FCB_RPORT_H__ ++ ++/** ++ * fcs_rport_fcb Remote port driver interfaces ++ */ ++ ++ ++struct bfad_rport_s; ++ ++/* ++ * Callback functions from BFA FCS to driver ++ */ ++ ++/** ++ * Completion callback for bfa_fcs_rport_add(). ++ * ++ * @param[in] rport_drv - driver instance of rport ++ * ++ * @return None ++ */ ++void bfa_fcb_rport_add(struct bfad_rport_s *rport_drv); ++ ++/** ++ * Completion callback for bfa_fcs_rport_remove(). ++ * ++ * @param[in] rport_drv - driver instance of rport ++ * ++ * @return None ++ */ ++void bfa_fcb_rport_remove(struct bfad_rport_s *rport_drv); ++ ++/** ++ * Call to allocate a rport instance. ++ * ++ * @param[in] bfad - driver instance ++ * @param[out] rport - BFA FCS instance of rport ++ * @param[out] rport_drv - driver instance of rport ++ * ++ * @retval BFA_STATUS_OK - successfully allocated ++ * @retval BFA_STATUS_ENOMEM - cannot allocate ++ */ ++bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad, ++ struct bfa_fcs_rport_s **rport, ++ struct bfad_rport_s **rport_drv); ++ ++/** ++ * Call to free rport memory resources. ++ * ++ * @param[in] bfad - driver instance ++ * @param[in] rport_drv - driver instance of rport ++ * ++ * @return None ++ */ ++void bfa_fcb_rport_free(struct bfad_s *bfad, struct bfad_rport_s **rport_drv); ++ ++ ++ ++#endif /* __BFA_FCB_RPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h +new file mode 100644 +index 0000000..cfd3fac +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcb_vf.h BFA FCS virtual fabric driver interfaces ++ */ ++ ++#ifndef __BFA_FCB_VF_H__ ++#define __BFA_FCB_VF_H__ ++ ++/** ++ * fcs_vf_fcb Virtual fabric driver intrefaces ++ */ ++ ++ ++struct bfad_vf_s; ++ ++/* ++ * Callback functions from BFA FCS to driver ++ */ ++ ++/** ++ * Completion callback for bfa_fcs_vf_stop(). ++ * ++ * @param[in] vf_drv - driver instance of vf ++ * ++ * @return None ++ */ ++void bfa_fcb_vf_stop(struct bfad_vf_s *vf_drv); ++ ++ ++ ++#endif /* __BFA_FCB_VF_H__ */ +diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h +new file mode 100644 +index 0000000..a39f474 +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcb_vport.h BFA FCS virtual port driver interfaces ++ */ ++ ++#ifndef __BFA_FCB_VPORT_H__ ++#define __BFA_FCB_VPORT_H__ ++ ++/** ++ * fcs_vport_fcb Virtual port driver interfaces ++ */ ++ ++ ++struct bfad_vport_s; ++ ++/* ++ * Callback functions from BFA FCS to driver ++ */ ++ ++/** ++ * Completion callback for bfa_fcs_vport_delete(). ++ * ++ * @param[in] vport_drv - driver instance of vport ++ * ++ * @return None ++ */ ++void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv); ++ ++ ++ ++#endif /* __BFA_FCB_VPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h +new file mode 100644 +index 0000000..627669c +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h +@@ -0,0 +1,73 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCS_H__ ++#define __BFA_FCS_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define BFA_FCS_OS_STR_LEN 64 ++ ++struct bfa_fcs_stats_s { ++ struct { ++ u32 untagged; /* untagged receive frames */ ++ u32 tagged; /* tagged receive frames */ ++ u32 vfid_unknown; /* VF id is unknown */ ++ } uf; ++}; ++ ++struct bfa_fcs_driver_info_s { ++ u8 version[BFA_VERSION_LEN]; /* Driver Version */ ++ u8 host_machine_name[BFA_FCS_OS_STR_LEN]; ++ u8 host_os_name[BFA_FCS_OS_STR_LEN]; /* OS name and version */ ++ u8 host_os_patch[BFA_FCS_OS_STR_LEN];/* patch or service pack */ ++ u8 os_device_name[BFA_FCS_OS_STR_LEN]; /* Driver Device Name */ ++}; ++ ++struct bfa_fcs_s { ++ struct bfa_s *bfa; /* corresponding BFA bfa instance */ ++ struct bfad_s *bfad; /* corresponding BDA driver instance */ ++ struct bfa_log_mod_s *logm; /* driver logging module instance */ ++ struct bfa_trc_mod_s *trcmod; /* tracing module */ ++ struct bfa_aen_s *aen; /* aen component */ ++ bfa_boolean_t vf_enabled; /* VF mode is enabled */ ++ bfa_boolean_t min_cfg; /* min cfg enabled/disabled */ ++ u16 port_vfid; /* port default VF ID */ ++ struct bfa_fcs_driver_info_s driver_info; ++ struct bfa_fcs_fabric_s fabric; /* base fabric state machine */ ++ struct bfa_fcs_stats_s stats; /* FCS statistics */ ++ struct bfa_wc_s wc; /* waiting counter */ ++}; ++ ++/* ++ * bfa fcs API functions ++ */ ++void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad, ++ bfa_boolean_t min_cfg); ++void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs, ++ struct bfa_fcs_driver_info_s *driver_info); ++void bfa_fcs_exit(struct bfa_fcs_s *fcs); ++void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod); ++void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod); ++void bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen); ++void bfa_fcs_start(struct bfa_fcs_s *fcs); ++ ++#endif /* __BFA_FCS_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h +new file mode 100644 +index 0000000..28c4c9f +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCS_AUTH_H__ ++#define __BFA_FCS_AUTH_H__ ++ ++struct bfa_fcs_s; ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct bfa_fcs_fabric_s; ++ ++ ++ ++struct bfa_fcs_auth_s { ++ bfa_sm_t sm; /* state machine */ ++ bfa_boolean_t policy; /* authentication enabled/disabled */ ++ enum bfa_auth_status status; /* authentication status */ ++ enum auth_rjt_codes rjt_code; /* auth reject status */ ++ enum auth_rjt_code_exps rjt_code_exp; /* auth reject reason */ ++ enum bfa_auth_algo algo; /* Authentication algorithm */ ++ struct bfa_auth_stats_s stats; /* Statistics */ ++ enum auth_dh_gid group; /* DH(diffie-hellman) Group */ ++ enum bfa_auth_secretsource source; /* Secret source */ ++ char secret[BFA_AUTH_SECRET_STRING_LEN]; ++ /* secret string */ ++ u8 secret_len; ++ /* secret string length */ ++ u8 nretries; ++ /* number of retries */ ++ struct bfa_fcs_fabric_s *fabric;/* pointer to fabric */ ++ u8 sentcode; /* pointer to response data */ ++ u8 *response; /* pointer to response data */ ++ struct bfa_timer_s delay_timer; /* delay timer */ ++ struct bfa_fcxp_s *fcxp; /* pointer to fcxp */ ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++}; ++ ++/** ++ * bfa fcs authentication public functions ++ */ ++bfa_status_t bfa_fcs_auth_get_attr(struct bfa_fcs_s *port, ++ struct bfa_auth_attr_s *attr); ++bfa_status_t bfa_fcs_auth_set_policy(struct bfa_fcs_s *port, ++ bfa_boolean_t policy); ++enum bfa_auth_status bfa_fcs_auth_get_status(struct bfa_fcs_s *port); ++bfa_status_t bfa_fcs_auth_set_algo(struct bfa_fcs_s *port, ++ enum bfa_auth_algo algo); ++bfa_status_t bfa_fcs_auth_get_stats(struct bfa_fcs_s *port, ++ struct bfa_auth_stats_s *stats); ++bfa_status_t bfa_fcs_auth_set_dh_group(struct bfa_fcs_s *port, int group); ++bfa_status_t bfa_fcs_auth_set_secretstring(struct bfa_fcs_s *port, ++ char *secret); ++bfa_status_t bfa_fcs_auth_set_secretstring_encrypt(struct bfa_fcs_s *port, ++ u32 secret[], u32 len); ++bfa_status_t bfa_fcs_auth_set_secretsource(struct bfa_fcs_s *port, ++ enum bfa_auth_secretsource src); ++bfa_status_t bfa_fcs_auth_reset_stats(struct bfa_fcs_s *port); ++bfa_status_t bfa_fcs_auth_reinit(struct bfa_fcs_s *port); ++ ++#endif /* __BFA_FCS_AUTH_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h +new file mode 100644 +index 0000000..4ffd224 +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCS_FABRIC_H__ ++#define __BFA_FCS_FABRIC_H__ ++ ++struct bfa_fcs_s; ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * forward declaration ++ */ ++struct bfad_vf_s; ++ ++enum bfa_fcs_fabric_type { ++ BFA_FCS_FABRIC_UNKNOWN = 0, ++ BFA_FCS_FABRIC_SWITCHED = 1, ++ BFA_FCS_FABRIC_PLOOP = 2, ++ BFA_FCS_FABRIC_N2N = 3, ++}; ++ ++ ++struct bfa_fcs_fabric_s { ++ struct list_head qe; /* queue element */ ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_fcs_s *fcs; /* FCS instance */ ++ struct bfa_fcs_port_s bport; /* base logical port */ ++ enum bfa_fcs_fabric_type fab_type; /* fabric type */ ++ enum bfa_pport_type oper_type; /* current link topology */ ++ u8 is_vf; /* is virtual fabric? */ ++ u8 is_npiv; /* is NPIV supported ? */ ++ u8 is_auth; /* is Security/Auth supported ? */ ++ u16 bb_credit; /* BB credit from fabric */ ++ u16 vf_id; /* virtual fabric ID */ ++ u16 num_vports; /* num vports */ ++ u16 rsvd; ++ struct list_head vport_q; /* queue of virtual ports */ ++ struct list_head vf_q; /* queue of virtual fabrics */ ++ struct bfad_vf_s *vf_drv; /* driver vf structure */ ++ struct bfa_timer_s link_timer; /* Link Failure timer. Vport */ ++ wwn_t fabric_name; /* attached fabric name */ ++ bfa_boolean_t auth_reqd; /* authentication required */ ++ struct bfa_timer_s delay_timer; /* delay timer */ ++ union { ++ u16 swp_vfid;/* switch port VF id */ ++ } event_arg; ++ struct bfa_fcs_auth_s auth; /* authentication config */ ++ struct bfa_wc_s wc; /* wait counter for delete */ ++ struct bfa_vf_stats_s stats; /* fabric/vf stats */ ++ struct bfa_lps_s *lps; /* lport login services */ ++ u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached ++ * fabric's ip addr ++ */ ++}; ++ ++#define bfa_fcs_fabric_npiv_capable(__f) (__f)->is_npiv ++#define bfa_fcs_fabric_is_switched(__f) \ ++ ((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED) ++ ++/** ++ * The design calls for a single implementation of base fabric and vf. ++ */ ++#define bfa_fcs_vf_t struct bfa_fcs_fabric_s ++ ++struct bfa_vf_event_s { ++ u32 undefined; ++}; ++ ++/** ++ * bfa fcs vf public functions ++ */ ++bfa_status_t bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id); ++bfa_status_t bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs); ++bfa_status_t bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, ++ u16 vf_id, struct bfa_port_cfg_s *port_cfg, ++ struct bfad_vf_s *vf_drv); ++bfa_status_t bfa_fcs_vf_delete(bfa_fcs_vf_t *vf); ++void bfa_fcs_vf_start(bfa_fcs_vf_t *vf); ++bfa_status_t bfa_fcs_vf_stop(bfa_fcs_vf_t *vf); ++void bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs); ++void bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs); ++void bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr); ++void bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, ++ struct bfa_vf_stats_s *vf_stats); ++void bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf); ++void bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t vpwwn[], int *nports); ++bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id); ++struct bfad_vf_s *bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf); ++ ++#endif /* __BFA_FCS_FABRIC_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h +new file mode 100644 +index 0000000..e719f2c +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h +@@ -0,0 +1,131 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_fcpim.h BFA FCS FCP Initiator Mode interfaces/defines. ++ */ ++ ++#ifndef __BFA_FCS_FCPIM_H__ ++#define __BFA_FCS_FCPIM_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * forward declarations ++ */ ++struct bfad_itnim_s; ++ ++struct bfa_fcs_itnim_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_fcs_rport_s *rport; /* parent remote rport */ ++ struct bfad_itnim_s *itnim_drv; /* driver peer instance */ ++ struct bfa_fcs_s *fcs; /* fcs instance */ ++ struct bfa_timer_s timer; /* timer functions */ ++ struct bfa_itnim_s *bfa_itnim; /* BFA itnim struct */ ++ bfa_boolean_t seq_rec; /* seq recovery support */ ++ bfa_boolean_t rec_support; /* REC supported */ ++ bfa_boolean_t conf_comp; /* FCP_CONF support */ ++ bfa_boolean_t task_retry_id; /* task retry id supp */ ++ struct bfa_fcxp_wqe_s fcxp_wqe; /* wait qelem for fcxp */ ++ struct bfa_fcxp_s *fcxp; /* FCXP in use */ ++ struct bfa_itnim_stats_s stats; /* itn statistics */ ++}; ++ ++ ++static inline struct bfad_port_s * ++bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->port->bfad_port; ++} ++ ++ ++static inline struct bfa_fcs_port_s * ++bfa_fcs_itnim_get_port(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->port; ++} ++ ++ ++static inline wwn_t ++bfa_fcs_itnim_get_nwwn(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->nwwn; ++} ++ ++ ++static inline wwn_t ++bfa_fcs_itnim_get_pwwn(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->pwwn; ++} ++ ++ ++static inline u32 ++bfa_fcs_itnim_get_fcid(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->pid; ++} ++ ++ ++static inline u32 ++bfa_fcs_itnim_get_maxfrsize(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->maxfrsize; ++} ++ ++ ++static inline enum fc_cos ++bfa_fcs_itnim_get_cos(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->rport->fc_cos; ++} ++ ++ ++static inline struct bfad_itnim_s * ++bfa_fcs_itnim_get_drvitn(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->itnim_drv; ++} ++ ++ ++static inline struct bfa_itnim_s * ++bfa_fcs_itnim_get_halitn(struct bfa_fcs_itnim_s *itnim) ++{ ++ return itnim->bfa_itnim; ++} ++ ++/** ++ * bfa fcs FCP Initiator mode API functions ++ */ ++void bfa_fcs_itnim_get_attr(struct bfa_fcs_itnim_s *itnim, ++ struct bfa_itnim_attr_s *attr); ++void bfa_fcs_itnim_get_stats(struct bfa_fcs_itnim_s *itnim, ++ struct bfa_itnim_stats_s *stats); ++struct bfa_fcs_itnim_s *bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port, ++ wwn_t rpwwn); ++bfa_status_t bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn, ++ struct bfa_itnim_attr_s *attr); ++bfa_status_t bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn, ++ struct bfa_itnim_stats_s *stats); ++bfa_status_t bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port, ++ wwn_t rpwwn); ++#endif /* __BFA_FCS_FCPIM_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h +new file mode 100644 +index 0000000..4441fff +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_fdmi.h BFA fcs fdmi module public interface ++ */ ++ ++#ifndef __BFA_FCS_FDMI_H__ ++#define __BFA_FCS_FDMI_H__ ++#include ++#include ++ ++#define BFA_FCS_FDMI_SUPORTED_SPEEDS (FDMI_TRANS_SPEED_1G | \ ++ FDMI_TRANS_SPEED_2G | \ ++ FDMI_TRANS_SPEED_4G | \ ++ FDMI_TRANS_SPEED_8G) ++ ++/* ++* HBA Attribute Block : BFA internal representation. Note : Some variable ++* sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based ++ * on this the size has been reduced to 16 bytes from the standard's 64 bytes. ++ */ ++struct bfa_fcs_fdmi_hba_attr_s { ++ wwn_t node_name; ++ u8 manufacturer[64]; ++ u8 serial_num[64]; ++ u8 model[16]; ++ u8 model_desc[256]; ++ u8 hw_version[8]; ++ u8 driver_version[8]; ++ u8 option_rom_ver[BFA_VERSION_LEN]; ++ u8 fw_version[8]; ++ u8 os_name[256]; ++ u32 max_ct_pyld; ++}; ++ ++/* ++ * Port Attribute Block ++ */ ++struct bfa_fcs_fdmi_port_attr_s { ++ u8 supp_fc4_types[32]; /* supported FC4 types */ ++ u32 supp_speed; /* supported speed */ ++ u32 curr_speed; /* current Speed */ ++ u32 max_frm_size; /* max frame size */ ++ u8 os_device_name[256]; /* OS device Name */ ++ u8 host_name[256]; /* host name */ ++}; ++ ++#endif /* __BFA_FCS_FDMI_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h +new file mode 100644 +index 0000000..b85cba8 +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h +@@ -0,0 +1,226 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_port.h BFA fcs port module public interface ++ */ ++ ++#ifndef __BFA_FCS_PORT_H__ ++#define __BFA_FCS_PORT_H__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct bfa_fcs_s; ++struct bfa_fcs_fabric_s; ++ ++/* ++* @todo : need to move to a global config file. ++ * Maximum Vports supported per physical port or vf. ++ */ ++#define BFA_FCS_MAX_VPORTS_SUPP_CB 255 ++#define BFA_FCS_MAX_VPORTS_SUPP_CT 191 ++ ++/* ++* @todo : need to move to a global config file. ++ * Maximum Rports supported per port (physical/logical). ++ */ ++#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */ ++ ++ ++struct bfa_fcs_port_ns_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_timer_s timer; ++ struct bfa_fcs_port_s *port; /* parent port */ ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++}; ++ ++ ++struct bfa_fcs_port_scn_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_timer_s timer; ++ struct bfa_fcs_port_s *port; /* parent port */ ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++}; ++ ++ ++struct bfa_fcs_port_fdmi_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_timer_s timer; ++ struct bfa_fcs_port_ms_s *ms; /* parent ms */ ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++ u8 retry_cnt; /* retry count */ ++ u8 rsvd[3]; ++}; ++ ++ ++struct bfa_fcs_port_ms_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_timer_s timer; ++ struct bfa_fcs_port_s *port; /* parent port */ ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++ struct bfa_fcs_port_fdmi_s fdmi; /* FDMI component of MS */ ++ u8 retry_cnt; /* retry count */ ++ u8 rsvd[3]; ++}; ++ ++ ++struct bfa_fcs_port_fab_s { ++ struct bfa_fcs_port_ns_s ns; /* NS component of port */ ++ struct bfa_fcs_port_scn_s scn; /* scn component of port */ ++ struct bfa_fcs_port_ms_s ms; /* MS component of port */ ++}; ++ ++ ++ ++#define MAX_ALPA_COUNT 127 ++ ++struct bfa_fcs_port_loop_s { ++ u8 num_alpa; /* Num of ALPA entries in the map */ ++ u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional ++ *Map */ ++ struct bfa_fcs_port_s *port; /* parent port */ ++}; ++ ++ ++ ++struct bfa_fcs_port_n2n_s { ++ u32 rsvd; ++ u16 reply_oxid; /* ox_id from the req flogi to be ++ *used in flogi acc */ ++ wwn_t rem_port_wwn; /* Attached port's wwn */ ++}; ++ ++ ++union bfa_fcs_port_topo_u { ++ struct bfa_fcs_port_fab_s pfab; ++ struct bfa_fcs_port_loop_s ploop; ++ struct bfa_fcs_port_n2n_s pn2n; ++}; ++ ++ ++struct bfa_fcs_port_s { ++ struct list_head qe; /* used by port/vport */ ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_fcs_fabric_s *fabric; /* parent fabric */ ++ struct bfa_port_cfg_s port_cfg; /* port configuration */ ++ struct bfa_timer_s link_timer; /* timer for link offline */ ++ u32 pid : 24; /* FC address */ ++ u8 lp_tag; /* lport tag */ ++ u16 num_rports; /* Num of r-ports */ ++ struct list_head rport_q; /* queue of discovered r-ports */ ++ struct bfa_fcs_s *fcs; /* FCS instance */ ++ union bfa_fcs_port_topo_u port_topo; /* fabric/loop/n2n details */ ++ struct bfad_port_s *bfad_port; /* driver peer instance */ ++ struct bfa_fcs_vport_s *vport; /* NULL for base ports */ ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_fcxp_wqe_s fcxp_wqe; ++ struct bfa_port_stats_s stats; ++ struct bfa_wc_s wc; /* waiting counter for events */ ++}; ++ ++#define bfa_fcs_lport_t struct bfa_fcs_port_s ++ ++/** ++ * Symbolic Name related defines ++ * Total bytes 255. ++ * Physical Port's symbolic name 128 bytes. ++ * For Vports, Vport's symbolic name is appended to the Physical port's ++ * Symbolic Name. ++ * ++ * Physical Port's symbolic name Format : (Total 128 bytes) ++ * Adapter Model number/name : 12 bytes ++ * Driver Version : 10 bytes ++ * Host Machine Name : 30 bytes ++ * Host OS Info : 48 bytes ++ * Host OS PATCH Info : 16 bytes ++ * ( remaining 12 bytes reserved to be used for separator) ++ */ ++#define BFA_FCS_PORT_SYMBNAME_SEPARATOR " | " ++ ++#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ 12 ++#define BFA_FCS_PORT_SYMBNAME_VERSION_SZ 10 ++#define BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ 30 ++#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 48 ++#define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ 16 ++ ++/** ++ * Get FC port ID for a logical port. ++ */ ++#define bfa_fcs_port_get_fcid(_lport) ((_lport)->pid) ++#define bfa_fcs_port_get_pwwn(_lport) ((_lport)->port_cfg.pwwn) ++#define bfa_fcs_port_get_nwwn(_lport) ((_lport)->port_cfg.nwwn) ++#define bfa_fcs_port_get_psym_name(_lport) ((_lport)->port_cfg.sym_name) ++#define bfa_fcs_port_is_initiator(_lport) \ ++ ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_IM) ++#define bfa_fcs_port_is_target(_lport) \ ++ ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_TM) ++#define bfa_fcs_port_get_nrports(_lport) \ ++ ((_lport) ? (_lport)->num_rports : 0) ++ ++static inline struct bfad_port_s * ++bfa_fcs_port_get_drvport(struct bfa_fcs_port_s *port) ++{ ++ return port->bfad_port; ++} ++ ++ ++#define bfa_fcs_port_get_opertype(_lport) (_lport)->fabric->oper_type ++ ++ ++#define bfa_fcs_port_get_fabric_name(_lport) (_lport)->fabric->fabric_name ++ ++ ++#define bfa_fcs_port_get_fabric_ipaddr(_lport) (_lport)->fabric->fabric_ip_addr ++ ++/** ++ * bfa fcs port public functions ++ */ ++void bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs, ++ struct bfa_port_cfg_s *port_cfg); ++struct bfa_fcs_port_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs); ++void bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, ++ wwn_t rport_wwns[], int *nrports); ++ ++wwn_t bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn, ++ int index, int nrports, bfa_boolean_t bwwn); ++ ++struct bfa_fcs_port_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, ++ u16 vf_id, wwn_t lpwwn); ++ ++void bfa_fcs_port_get_info(struct bfa_fcs_port_s *port, ++ struct bfa_port_info_s *port_info); ++void bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port, ++ struct bfa_port_attr_s *port_attr); ++void bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port, ++ struct bfa_port_stats_s *port_stats); ++void bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port); ++enum bfa_pport_speed bfa_fcs_port_get_rport_max_speed( ++ struct bfa_fcs_port_s *port); ++void bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port); ++void bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port); ++ ++#endif /* __BFA_FCS_PORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h +new file mode 100644 +index 0000000..702b95b +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __BFA_FCS_RPORT_H__ ++#define __BFA_FCS_RPORT_H__ ++ ++#include ++#include ++#include ++#include ++ ++#define BFA_FCS_RPORT_DEF_DEL_TIMEOUT 90 /* in secs */ ++/* ++ * forward declarations ++ */ ++struct bfad_rport_s; ++ ++struct bfa_fcs_itnim_s; ++struct bfa_fcs_tin_s; ++struct bfa_fcs_iprp_s; ++ ++/* Rport Features (RPF) */ ++struct bfa_fcs_rpf_s { ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_fcs_rport_s *rport; /* parent rport */ ++ struct bfa_timer_s timer; /* general purpose timer */ ++ struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */ ++ struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */ ++ int rpsc_retries; /* max RPSC retry attempts */ ++ enum bfa_pport_speed rpsc_speed; /* Current Speed from RPSC. ++ * O if RPSC fails */ ++ enum bfa_pport_speed assigned_speed; /* Speed assigned by the user. ++ * will be used if RPSC is not ++ * supported by the rport */ ++}; ++ ++struct bfa_fcs_rport_s { ++ struct list_head qe; /* used by port/vport */ ++ struct bfa_fcs_port_s *port; /* parent FCS port */ ++ struct bfa_fcs_s *fcs; /* fcs instance */ ++ struct bfad_rport_s *rp_drv; /* driver peer instance */ ++ u32 pid; /* port ID of rport */ ++ u16 maxfrsize; /* maximum frame size */ ++ u16 reply_oxid; /* OX_ID of inbound requests */ ++ enum fc_cos fc_cos; /* FC classes of service supp */ ++ bfa_boolean_t cisc; /* CISC capable device */ ++ wwn_t pwwn; /* port wwn of rport */ ++ wwn_t nwwn; /* node wwn of rport */ ++ struct bfa_rport_symname_s psym_name; /* port symbolic name */ ++ bfa_sm_t sm; /* state machine */ ++ struct bfa_timer_s timer; /* general purpose timer */ ++ struct bfa_fcs_itnim_s *itnim; /* ITN initiator mode role */ ++ struct bfa_fcs_tin_s *tin; /* ITN initiator mode role */ ++ struct bfa_fcs_iprp_s *iprp; /* IP/FC role */ ++ struct bfa_rport_s *bfa_rport; /* BFA Rport */ ++ struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */ ++ int plogi_retries; /* max plogi retry attempts */ ++ int ns_retries; /* max NS query retry attempts */ ++ struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */ ++ struct bfa_rport_stats_s stats; /* rport stats */ ++ enum bfa_rport_function scsi_function; /* Initiator/Target */ ++ struct bfa_fcs_rpf_s rpf; /* Rport features module */ ++}; ++ ++static inline struct bfa_rport_s * ++bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport) ++{ ++ return rport->bfa_rport; ++} ++ ++/** ++ * bfa fcs rport API functions ++ */ ++bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn, ++ struct bfa_fcs_rport_s *rport, ++ struct bfad_rport_s *rport_drv); ++bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport); ++void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, ++ struct bfa_rport_attr_s *attr); ++void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport, ++ struct bfa_rport_stats_s *stats); ++void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport); ++struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port, ++ wwn_t rpwwn); ++struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn( ++ struct bfa_fcs_port_s *port, wwn_t rnwwn); ++void bfa_fcs_rport_set_del_timeout(u8 rport_tmo); ++void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, ++ enum bfa_pport_speed speed); ++#endif /* __BFA_FCS_RPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h +new file mode 100644 +index 0000000..cd33f2c +--- /dev/null ++++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_vport.h BFA fcs vport module public interface ++ */ ++ ++#ifndef __BFA_FCS_VPORT_H__ ++#define __BFA_FCS_VPORT_H__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct bfa_fcs_vport_s { ++ struct list_head qe; /* queue elem */ ++ bfa_sm_t sm; /* state machine */ ++ bfa_fcs_lport_t lport; /* logical port */ ++ struct bfa_timer_s timer; /* general purpose timer */ ++ struct bfad_vport_s *vport_drv; /* Driver private */ ++ struct bfa_vport_stats_s vport_stats; /* vport statistics */ ++ struct bfa_lps_s *lps; /* Lport login service */ ++ int fdisc_retries; ++}; ++ ++#define bfa_fcs_vport_get_port(vport) \ ++ ((struct bfa_fcs_port_s *)(&vport->port)) ++ ++/** ++ * bfa fcs vport public functions ++ */ ++bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, ++ struct bfa_fcs_s *fcs, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg, ++ struct bfad_vport_s *vport_drv); ++bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport); ++bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport); ++bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport); ++void bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, ++ struct bfa_vport_attr_s *vport_attr); ++void bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport, ++ struct bfa_vport_stats_s *vport_stats); ++void bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport); ++struct bfa_fcs_vport_s *bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, ++ u16 vf_id, wwn_t vpwwn); ++ ++#endif /* __BFA_FCS_VPORT_H__ */ +diff --git a/drivers/scsi/bfa/include/log/bfa_log_fcs.h b/drivers/scsi/bfa/include/log/bfa_log_fcs.h +new file mode 100644 +index 0000000..b6f5df8 +--- /dev/null ++++ b/drivers/scsi/bfa/include/log/bfa_log_fcs.h +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* ++ * messages define for FCS Module ++ */ ++#ifndef __BFA_LOG_FCS_H__ ++#define __BFA_LOG_FCS_H__ ++#include ++#define BFA_LOG_FCS_FABRIC_NOSWITCH \ ++ (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 1) ++#define BFA_LOG_FCS_FABRIC_ISOLATED \ ++ (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 2) ++#endif +diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h +new file mode 100644 +index 0000000..0412aea +--- /dev/null ++++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for HAL Module */ ++#ifndef __BFA_LOG_HAL_H__ ++#define __BFA_LOG_HAL_H__ ++#include ++#define BFA_LOG_HAL_ASSERT \ ++ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 1) ++#define BFA_LOG_HAL_HEARTBEAT_FAILURE \ ++ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 2) ++#define BFA_LOG_HAL_FCPIM_PARM_INVALID \ ++ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3) ++#define BFA_LOG_HAL_SM_ASSERT \ ++ (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4) ++#endif +diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h +new file mode 100644 +index 0000000..317c054 +--- /dev/null ++++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* messages define for LINUX Module */ ++#ifndef __BFA_LOG_LINUX_H__ ++#define __BFA_LOG_LINUX_H__ ++#include ++#define BFA_LOG_LINUX_DEVICE_CLAIMED \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 1) ++#define BFA_LOG_LINUX_HASH_INIT_FAILED \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 2) ++#define BFA_LOG_LINUX_SYSFS_FAILED \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 3) ++#define BFA_LOG_LINUX_MEM_ALLOC_FAILED \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 4) ++#define BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 5) ++#define BFA_LOG_LINUX_ITNIM_FREE \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 6) ++#define BFA_LOG_LINUX_ITNIM_ONLINE \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 7) ++#define BFA_LOG_LINUX_ITNIM_OFFLINE \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 8) ++#define BFA_LOG_LINUX_SCSI_HOST_FREE \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 9) ++#define BFA_LOG_LINUX_SCSI_ABORT \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10) ++#define BFA_LOG_LINUX_SCSI_ABORT_COMP \ ++ (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11) ++#endif +diff --git a/drivers/scsi/bfa/include/log/bfa_log_wdrv.h b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h +new file mode 100644 +index 0000000..809a95f +--- /dev/null ++++ b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/* ++ * messages define for WDRV Module ++ */ ++#ifndef __BFA_LOG_WDRV_H__ ++#define __BFA_LOG_WDRV_H__ ++#include ++#define BFA_LOG_WDRV_IOC_INIT_ERROR \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 1) ++#define BFA_LOG_WDRV_IOC_INTERNAL_ERROR \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 2) ++#define BFA_LOG_WDRV_IOC_START_ERROR \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 3) ++#define BFA_LOG_WDRV_IOC_STOP_ERROR \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 4) ++#define BFA_LOG_WDRV_INSUFFICIENT_RESOURCES \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 5) ++#define BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR \ ++ (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 6) ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h +new file mode 100644 +index 0000000..c59d663 +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/ct.h +@@ -0,0 +1,492 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __CT_H__ ++#define __CT_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++struct ct_hdr_s{ ++ u32 rev_id:8; /* Revision of the CT */ ++ u32 in_id:24; /* Initiator Id */ ++ u32 gs_type:8; /* Generic service Type */ ++ u32 gs_sub_type:8; /* Generic service sub type */ ++ u32 options:8; /* options */ ++ u32 rsvrd:8; /* reserved */ ++ u32 cmd_rsp_code:16;/* ct command/response code */ ++ u32 max_res_size:16;/* maximum/residual size */ ++ u32 frag_id:8; /* fragment ID */ ++ u32 reason_code:8; /* reason code */ ++ u32 exp_code:8; /* explanation code */ ++ u32 vendor_unq:8; /* vendor unique */ ++}; ++ ++/* ++ * defines for the Revision ++ */ ++enum { ++ CT_GS3_REVISION = 0x01, ++}; ++ ++/* ++ * defines for gs_type ++ */ ++enum { ++ CT_GSTYPE_KEYSERVICE = 0xF7, ++ CT_GSTYPE_ALIASSERVICE = 0xF8, ++ CT_GSTYPE_MGMTSERVICE = 0xFA, ++ CT_GSTYPE_TIMESERVICE = 0xFB, ++ CT_GSTYPE_DIRSERVICE = 0xFC, ++}; ++ ++/* ++ * defines for gs_sub_type for gs type directory service ++ */ ++enum { ++ CT_GSSUBTYPE_NAMESERVER = 0x02, ++}; ++ ++/* ++ * defines for gs_sub_type for gs type management service ++ */ ++enum { ++ CT_GSSUBTYPE_CFGSERVER = 0x01, ++ CT_GSSUBTYPE_UNZONED_NS = 0x02, ++ CT_GSSUBTYPE_ZONESERVER = 0x03, ++ CT_GSSUBTYPE_LOCKSERVER = 0x04, ++ CT_GSSUBTYPE_HBA_MGMTSERVER = 0x10, /* for FDMI */ ++}; ++ ++/* ++ * defines for CT response code field ++ */ ++enum { ++ CT_RSP_REJECT = 0x8001, ++ CT_RSP_ACCEPT = 0x8002, ++}; ++ ++/* ++ * defintions for CT reason code ++ */ ++enum { ++ CT_RSN_INV_CMD = 0x01, ++ CT_RSN_INV_VER = 0x02, ++ CT_RSN_LOGIC_ERR = 0x03, ++ CT_RSN_INV_SIZE = 0x04, ++ CT_RSN_LOGICAL_BUSY = 0x05, ++ CT_RSN_PROTO_ERR = 0x07, ++ CT_RSN_UNABLE_TO_PERF = 0x09, ++ CT_RSN_NOT_SUPP = 0x0B, ++ CT_RSN_SERVER_NOT_AVBL = 0x0D, ++ CT_RSN_SESSION_COULD_NOT_BE_ESTBD = 0x0E, ++ CT_RSN_VENDOR_SPECIFIC = 0xFF, ++ ++}; ++ ++/* ++ * definitions for explanations code for Name server ++ */ ++enum { ++ CT_NS_EXP_NOADDITIONAL = 0x00, ++ CT_NS_EXP_ID_NOT_REG = 0x01, ++ CT_NS_EXP_PN_NOT_REG = 0x02, ++ CT_NS_EXP_NN_NOT_REG = 0x03, ++ CT_NS_EXP_CS_NOT_REG = 0x04, ++ CT_NS_EXP_IPN_NOT_REG = 0x05, ++ CT_NS_EXP_IPA_NOT_REG = 0x06, ++ CT_NS_EXP_FT_NOT_REG = 0x07, ++ CT_NS_EXP_SPN_NOT_REG = 0x08, ++ CT_NS_EXP_SNN_NOT_REG = 0x09, ++ CT_NS_EXP_PT_NOT_REG = 0x0A, ++ CT_NS_EXP_IPP_NOT_REG = 0x0B, ++ CT_NS_EXP_FPN_NOT_REG = 0x0C, ++ CT_NS_EXP_HA_NOT_REG = 0x0D, ++ CT_NS_EXP_FD_NOT_REG = 0x0E, ++ CT_NS_EXP_FF_NOT_REG = 0x0F, ++ CT_NS_EXP_ACCESSDENIED = 0x10, ++ CT_NS_EXP_UNACCEPTABLE_ID = 0x11, ++ CT_NS_EXP_DATABASEEMPTY = 0x12, ++ CT_NS_EXP_NOT_REG_IN_SCOPE = 0x13, ++ CT_NS_EXP_DOM_ID_NOT_PRESENT = 0x14, ++ CT_NS_EXP_PORT_NUM_NOT_PRESENT = 0x15, ++ CT_NS_EXP_NO_DEVICE_ATTACHED = 0x16 ++}; ++ ++/* ++ * defintions for the explanation code for all servers ++ */ ++enum { ++ CT_EXP_AUTH_EXCEPTION = 0xF1, ++ CT_EXP_DB_FULL = 0xF2, ++ CT_EXP_DB_EMPTY = 0xF3, ++ CT_EXP_PROCESSING_REQ = 0xF4, ++ CT_EXP_UNABLE_TO_VERIFY_CONN = 0xF5, ++ CT_EXP_DEVICES_NOT_IN_CMN_ZONE = 0xF6 ++}; ++ ++/* ++ * Command codes for Name server ++ */ ++enum { ++ GS_GID_PN = 0x0121, /* Get Id on port name */ ++ GS_GPN_ID = 0x0112, /* Get port name on ID */ ++ GS_GNN_ID = 0x0113, /* Get node name on ID */ ++ GS_GID_FT = 0x0171, /* Get Id on FC4 type */ ++ GS_GSPN_ID = 0x0118, /* Get symbolic PN on ID */ ++ GS_RFT_ID = 0x0217, /* Register fc4type on ID */ ++ GS_RSPN_ID = 0x0218, /* Register symbolic PN on ID */ ++ GS_RPN_ID = 0x0212, /* Register port name */ ++ GS_RNN_ID = 0x0213, /* Register node name */ ++ GS_RCS_ID = 0x0214, /* Register class of service */ ++ GS_RPT_ID = 0x021A, /* Register port type */ ++ GS_GA_NXT = 0x0100, /* Get all next */ ++ GS_RFF_ID = 0x021F, /* Register FC4 Feature */ ++}; ++ ++struct fcgs_id_req_s{ ++ u32 rsvd:8; ++ u32 dap:24; /* port identifier */ ++}; ++#define fcgs_gpnid_req_t struct fcgs_id_req_s ++#define fcgs_gnnid_req_t struct fcgs_id_req_s ++#define fcgs_gspnid_req_t struct fcgs_id_req_s ++ ++struct fcgs_gidpn_req_s{ ++ wwn_t port_name; /* port wwn */ ++}; ++ ++struct fcgs_gidpn_resp_s{ ++ u32 rsvd:8; ++ u32 dap:24; /* port identifier */ ++}; ++ ++/** ++ * RFT_ID ++ */ ++struct fcgs_rftid_req_s { ++ u32 rsvd:8; ++ u32 dap:24; /* port identifier */ ++ u32 fc4_type[8]; /* fc4 types */ ++}; ++ ++/** ++ * RFF_ID : Register FC4 features. ++ */ ++ ++#define FC_GS_FCP_FC4_FEATURE_INITIATOR 0x02 ++#define FC_GS_FCP_FC4_FEATURE_TARGET 0x01 ++ ++struct fcgs_rffid_req_s{ ++ u32 rsvd :8; ++ u32 dap :24; /* port identifier */ ++ u32 rsvd1 :16; ++ u32 fc4ftr_bits :8; /* fc4 feature bits */ ++ u32 fc4_type :8; /* corresponding FC4 Type */ ++}; ++ ++/** ++ * GID_FT Request ++ */ ++struct fcgs_gidft_req_s{ ++ u8 reserved; ++ u8 domain_id; /* domain, 0 - all fabric */ ++ u8 area_id; /* area, 0 - whole domain */ ++ u8 fc4_type; /* FC_TYPE_FCP for SCSI devices */ ++}; /* GID_FT Request */ ++ ++/** ++ * GID_FT Response ++ */ ++struct fcgs_gidft_resp_s { ++ u8 last:1; /* last port identifier flag */ ++ u8 reserved:7; ++ u32 pid:24; /* port identifier */ ++}; /* GID_FT Response */ ++ ++/** ++ * RSPN_ID ++ */ ++struct fcgs_rspnid_req_s{ ++ u32 rsvd:8; ++ u32 dap:24; /* port identifier */ ++ u8 spn_len; /* symbolic port name length */ ++ u8 spn[256]; /* symbolic port name */ ++}; ++ ++/** ++ * RPN_ID ++ */ ++struct fcgs_rpnid_req_s{ ++ u32 rsvd:8; ++ u32 port_id:24; ++ wwn_t port_name; ++}; ++ ++/** ++ * RNN_ID ++ */ ++struct fcgs_rnnid_req_s{ ++ u32 rsvd:8; ++ u32 port_id:24; ++ wwn_t node_name; ++}; ++ ++/** ++ * RCS_ID ++ */ ++struct fcgs_rcsid_req_s{ ++ u32 rsvd:8; ++ u32 port_id:24; ++ u32 cos; ++}; ++ ++/** ++ * RPT_ID ++ */ ++struct fcgs_rptid_req_s{ ++ u32 rsvd:8; ++ u32 port_id:24; ++ u32 port_type:8; ++ u32 rsvd1:24; ++}; ++ ++/** ++ * GA_NXT Request ++ */ ++struct fcgs_ganxt_req_s{ ++ u32 rsvd:8; ++ u32 port_id:24; ++}; ++ ++/** ++ * GA_NXT Response ++ */ ++struct fcgs_ganxt_rsp_s{ ++ u32 port_type:8; /* Port Type */ ++ u32 port_id:24; /* Port Identifier */ ++ wwn_t port_name; /* Port Name */ ++ u8 spn_len; /* Length of Symbolic Port Name */ ++ char spn[255]; /* Symbolic Port Name */ ++ wwn_t node_name; /* Node Name */ ++ u8 snn_len; /* Length of Symbolic Node Name */ ++ char snn[255]; /* Symbolic Node Name */ ++ u8 ipa[8]; /* Initial Process Associator */ ++ u8 ip[16]; /* IP Address */ ++ u32 cos; /* Class of Service */ ++ u32 fc4types[8]; /* FC-4 TYPEs */ ++ wwn_t fabric_port_name; ++ /* Fabric Port Name */ ++ u32 rsvd:8; /* Reserved */ ++ u32 hard_addr:24; /* Hard Address */ ++}; ++ ++/* ++ * Fabric Config Server ++ */ ++ ++/* ++ * Command codes for Fabric Configuration Server ++ */ ++enum { ++ GS_FC_GFN_CMD = 0x0114, /* GS FC Get Fabric Name */ ++ GS_FC_GMAL_CMD = 0x0116, /* GS FC GMAL */ ++ GS_FC_TRACE_CMD = 0x0400, /* GS FC Trace Route */ ++ GS_FC_PING_CMD = 0x0401, /* GS FC Ping */ ++}; ++ ++/* ++ * Source or Destination Port Tags. ++ */ ++enum { ++ GS_FTRACE_TAG_NPORT_ID = 1, ++ GS_FTRACE_TAG_NPORT_NAME = 2, ++}; ++ ++/* ++* Port Value : Could be a Port id or wwn ++ */ ++union fcgs_port_val_u{ ++ u32 nport_id; ++ wwn_t nport_wwn; ++}; ++ ++#define GS_FTRACE_MAX_HOP_COUNT 20 ++#define GS_FTRACE_REVISION 1 ++ ++/* ++ * Ftrace Related Structures. ++ */ ++ ++/* ++ * STR (Switch Trace) Reject Reason Codes. From FC-SW. ++ */ ++enum { ++ GS_FTRACE_STR_CMD_COMPLETED_SUCC = 0, ++ GS_FTRACE_STR_CMD_NOT_SUPP_IN_NEXT_SWITCH, ++ GS_FTRACE_STR_NO_RESP_FROM_NEXT_SWITCH, ++ GS_FTRACE_STR_MAX_HOP_CNT_REACHED, ++ GS_FTRACE_STR_SRC_PORT_NOT_FOUND, ++ GS_FTRACE_STR_DST_PORT_NOT_FOUND, ++ GS_FTRACE_STR_DEVICES_NOT_IN_COMMON_ZONE, ++ GS_FTRACE_STR_NO_ROUTE_BW_PORTS, ++ GS_FTRACE_STR_NO_ADDL_EXPLN, ++ GS_FTRACE_STR_FABRIC_BUSY, ++ GS_FTRACE_STR_FABRIC_BUILD_IN_PROGRESS, ++ GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_START = 0xf0, ++ GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_END = 0xff, ++}; ++ ++/* ++ * Ftrace Request ++ */ ++struct fcgs_ftrace_req_s{ ++ u32 revision; ++ u16 src_port_tag; /* Source Port tag */ ++ u16 src_port_len; /* Source Port len */ ++ union fcgs_port_val_u src_port_val; /* Source Port value */ ++ u16 dst_port_tag; /* Destination Port tag */ ++ u16 dst_port_len; /* Destination Port len */ ++ union fcgs_port_val_u dst_port_val; /* Destination Port value */ ++ u32 token; ++ u8 vendor_id[8]; /* T10 Vendor Identifier */ ++ u8 vendor_info[8]; /* Vendor specific Info */ ++ u32 max_hop_cnt; /* Max Hop Count */ ++}; ++ ++/* ++ * Path info structure ++ */ ++struct fcgs_ftrace_path_info_s{ ++ wwn_t switch_name; /* Switch WWN */ ++ u32 domain_id; ++ wwn_t ingress_port_name; /* Ingress ports wwn */ ++ u32 ingress_phys_port_num; /* Ingress ports physical port ++ * number ++ */ ++ wwn_t egress_port_name; /* Ingress ports wwn */ ++ u32 egress_phys_port_num; /* Ingress ports physical port ++ * number ++ */ ++}; ++ ++/* ++ * Ftrace Acc Response ++ */ ++struct fcgs_ftrace_resp_s{ ++ u32 revision; ++ u32 token; ++ u8 vendor_id[8]; /* T10 Vendor Identifier */ ++ u8 vendor_info[8]; /* Vendor specific Info */ ++ u32 str_rej_reason_code; /* STR Reject Reason Code */ ++ u32 num_path_info_entries; /* No. of path info entries */ ++ /* ++ * path info entry/entries. ++ */ ++ struct fcgs_ftrace_path_info_s path_info[1]; ++ ++}; ++ ++/* ++* Fabric Config Server : FCPing ++ */ ++ ++/* ++ * FC Ping Request ++ */ ++struct fcgs_fcping_req_s{ ++ u32 revision; ++ u16 port_tag; ++ u16 port_len; /* Port len */ ++ union fcgs_port_val_u port_val; /* Port value */ ++ u32 token; ++}; ++ ++/* ++ * FC Ping Response ++ */ ++struct fcgs_fcping_resp_s{ ++ u32 token; ++}; ++ ++/* ++ * Command codes for zone server query. ++ */ ++enum { ++ ZS_GZME = 0x0124, /* Get zone member extended */ ++}; ++ ++/* ++ * ZS GZME request ++ */ ++#define ZS_GZME_ZNAMELEN 32 ++struct zs_gzme_req_s{ ++ u8 znamelen; ++ u8 rsvd[3]; ++ u8 zname[ZS_GZME_ZNAMELEN]; ++}; ++ ++enum zs_mbr_type{ ++ ZS_MBR_TYPE_PWWN = 1, ++ ZS_MBR_TYPE_DOMPORT = 2, ++ ZS_MBR_TYPE_PORTID = 3, ++ ZS_MBR_TYPE_NWWN = 4, ++}; ++ ++struct zs_mbr_wwn_s{ ++ u8 mbr_type; ++ u8 rsvd[3]; ++ wwn_t wwn; ++}; ++ ++struct zs_query_resp_s{ ++ u32 nmbrs; /* number of zone members */ ++ struct zs_mbr_wwn_s mbr[1]; ++}; ++ ++/* ++ * GMAL Command ( Get ( interconnect Element) Management Address List) ++ * To retrieve the IP Address of a Switch. ++ */ ++ ++#define CT_GMAL_RESP_PREFIX_TELNET "telnet://" ++#define CT_GMAL_RESP_PREFIX_HTTP "http://" ++ ++/* GMAL/GFN request */ ++struct fcgs_req_s { ++ wwn_t wwn; /* PWWN/NWWN */ ++}; ++ ++#define fcgs_gmal_req_t struct fcgs_req_s ++#define fcgs_gfn_req_t struct fcgs_req_s ++ ++/* Accept Response to GMAL */ ++struct fcgs_gmal_resp_s { ++ u32 ms_len; /* Num of entries */ ++ u8 ms_ma[256]; ++}; ++ ++struct fc_gmal_entry_s { ++ u8 len; ++ u8 prefix[7]; /* like "http://" */ ++ u8 ip_addr[248]; ++}; ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h +new file mode 100644 +index 0000000..3e39ba5 +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/fc.h +@@ -0,0 +1,1105 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FC_H__ ++#define __FC_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++/* ++ * Fibre Channel Header Structure (FCHS) definition ++ */ ++struct fchs_s { ++#ifdef __BIGENDIAN ++ u32 routing:4; /* routing bits */ ++ u32 cat_info:4; /* category info */ ++#else ++ u32 cat_info:4; /* category info */ ++ u32 routing:4; /* routing bits */ ++#endif ++ u32 d_id:24; /* destination identifier */ ++ ++ u32 cs_ctl:8; /* class specific control */ ++ u32 s_id:24; /* source identifier */ ++ ++ u32 type:8; /* data structure type */ ++ u32 f_ctl:24; /* initial frame control */ ++ ++ u8 seq_id; /* sequence identifier */ ++ u8 df_ctl; /* data field control */ ++ u16 seq_cnt; /* sequence count */ ++ ++ u16 ox_id; /* originator exchange ID */ ++ u16 rx_id; /* responder exchange ID */ ++ ++ u32 ro; /* relative offset */ ++}; ++/* ++ * Fibre Channel BB_E Header Structure ++ */ ++struct fcbbehs_s { ++ u16 ver_rsvd; ++ u32 rsvd[2]; ++ u32 rsvd__sof; ++}; ++ ++#define FC_SEQ_ID_MAX 256 ++ ++/* ++ * routing bit definitions ++ */ ++enum { ++ FC_RTG_FC4_DEV_DATA = 0x0, /* FC-4 Device Data */ ++ FC_RTG_EXT_LINK = 0x2, /* Extended Link Data */ ++ FC_RTG_FC4_LINK_DATA = 0x3, /* FC-4 Link Data */ ++ FC_RTG_VIDEO_DATA = 0x4, /* Video Data */ ++ FC_RTG_EXT_HDR = 0x5, /* VFT, IFR or Encapsuled */ ++ FC_RTG_BASIC_LINK = 0x8, /* Basic Link data */ ++ FC_RTG_LINK_CTRL = 0xC, /* Link Control */ ++}; ++ ++/* ++ * information category for extended link data and FC-4 Link Data ++ */ ++enum { ++ FC_CAT_LD_REQUEST = 0x2, /* Request */ ++ FC_CAT_LD_REPLY = 0x3, /* Reply */ ++ FC_CAT_LD_DIAG = 0xF, /* for DIAG use only */ ++}; ++ ++/* ++ * information category for extended headers (VFT, IFR or encapsulation) ++ */ ++enum { ++ FC_CAT_VFT_HDR = 0x0, /* Virtual fabric tagging header */ ++ FC_CAT_IFR_HDR = 0x1, /* Inter-Fabric routing header */ ++ FC_CAT_ENC_HDR = 0x2, /* Encapsulation header */ ++}; ++ ++/* ++ * information category for FC-4 device data ++ */ ++enum { ++ FC_CAT_UNCATEG_INFO = 0x0, /* Uncategorized information */ ++ FC_CAT_SOLICIT_DATA = 0x1, /* Solicited Data */ ++ FC_CAT_UNSOLICIT_CTRL = 0x2, /* Unsolicited Control */ ++ FC_CAT_SOLICIT_CTRL = 0x3, /* Solicited Control */ ++ FC_CAT_UNSOLICIT_DATA = 0x4, /* Unsolicited Data */ ++ FC_CAT_DATA_DESC = 0x5, /* Data Descriptor */ ++ FC_CAT_UNSOLICIT_CMD = 0x6, /* Unsolicited Command */ ++ FC_CAT_CMD_STATUS = 0x7, /* Command Status */ ++}; ++ ++/* ++ * information category for Link Control ++ */ ++enum { ++ FC_CAT_ACK_1 = 0x00, ++ FC_CAT_ACK_0_N = 0x01, ++ FC_CAT_P_RJT = 0x02, ++ FC_CAT_F_RJT = 0x03, ++ FC_CAT_P_BSY = 0x04, ++ FC_CAT_F_BSY_DATA = 0x05, ++ FC_CAT_F_BSY_LINK_CTL = 0x06, ++ FC_CAT_F_LCR = 0x07, ++ FC_CAT_NTY = 0x08, ++ FC_CAT_END = 0x09, ++}; ++ ++/* ++ * Type Field Definitions. FC-PH Section 18.5 pg. 165 ++ */ ++enum { ++ FC_TYPE_BLS = 0x0, /* Basic Link Service */ ++ FC_TYPE_ELS = 0x1, /* Extended Link Service */ ++ FC_TYPE_IP = 0x5, /* IP */ ++ FC_TYPE_FCP = 0x8, /* SCSI-FCP */ ++ FC_TYPE_GPP = 0x9, /* SCSI_GPP */ ++ FC_TYPE_SERVICES = 0x20, /* Fibre Channel Services */ ++ FC_TYPE_FC_FSS = 0x22, /* Fabric Switch Services */ ++ FC_TYPE_FC_AL = 0x23, /* FC-AL */ ++ FC_TYPE_FC_SNMP = 0x24, /* FC-SNMP */ ++ FC_TYPE_MAX = 256, /* 256 FC-4 types */ ++}; ++ ++struct fc_fc4types_s{ ++ u8 bits[FC_TYPE_MAX / 8]; ++}; ++ ++/* ++ * Frame Control Definitions. FC-PH Table-45. pg. 168 ++ */ ++enum { ++ FCTL_EC_ORIG = 0x000000, /* exchange originator */ ++ FCTL_EC_RESP = 0x800000, /* exchange responder */ ++ FCTL_SEQ_INI = 0x000000, /* sequence initiator */ ++ FCTL_SEQ_REC = 0x400000, /* sequence recipient */ ++ FCTL_FS_EXCH = 0x200000, /* first sequence of xchg */ ++ FCTL_LS_EXCH = 0x100000, /* last sequence of xchg */ ++ FCTL_END_SEQ = 0x080000, /* last frame of sequence */ ++ FCTL_SI_XFER = 0x010000, /* seq initiative transfer */ ++ FCTL_RO_PRESENT = 0x000008, /* relative offset present */ ++ FCTL_FILLBYTE_MASK = 0x000003 /* , fill byte mask */ ++}; ++ ++/* ++ * Fabric Well Known Addresses ++ */ ++enum { ++ FC_MIN_WELL_KNOWN_ADDR = 0xFFFFF0, ++ FC_DOMAIN_CONTROLLER_MASK = 0xFFFC00, ++ FC_ALIAS_SERVER = 0xFFFFF8, ++ FC_MGMT_SERVER = 0xFFFFFA, ++ FC_TIME_SERVER = 0xFFFFFB, ++ FC_NAME_SERVER = 0xFFFFFC, ++ FC_FABRIC_CONTROLLER = 0xFFFFFD, ++ FC_FABRIC_PORT = 0xFFFFFE, ++ FC_BROADCAST_SERVER = 0xFFFFFF ++}; ++ ++/* ++ * domain/area/port defines ++ */ ++#define FC_DOMAIN_MASK 0xFF0000 ++#define FC_DOMAIN_SHIFT 16 ++#define FC_AREA_MASK 0x00FF00 ++#define FC_AREA_SHIFT 8 ++#define FC_PORT_MASK 0x0000FF ++#define FC_PORT_SHIFT 0 ++ ++#define FC_GET_DOMAIN(p) (((p) & FC_DOMAIN_MASK) >> FC_DOMAIN_SHIFT) ++#define FC_GET_AREA(p) (((p) & FC_AREA_MASK) >> FC_AREA_SHIFT) ++#define FC_GET_PORT(p) (((p) & FC_PORT_MASK) >> FC_PORT_SHIFT) ++ ++#define FC_DOMAIN_CTRLR(p) (FC_DOMAIN_CONTROLLER_MASK | (FC_GET_DOMAIN(p))) ++ ++enum { ++ FC_RXID_ANY = 0xFFFFU, ++}; ++ ++/* ++ * generic ELS command ++ */ ++struct fc_els_cmd_s{ ++ u32 els_code:8; /* ELS Command Code */ ++ u32 reserved:24; ++}; ++ ++/* ++ * ELS Command Codes. FC-PH Table-75. pg. 223 ++ */ ++enum { ++ FC_ELS_LS_RJT = 0x1, /* Link Service Reject. */ ++ FC_ELS_ACC = 0x02, /* Accept */ ++ FC_ELS_PLOGI = 0x03, /* N_Port Login. */ ++ FC_ELS_FLOGI = 0x04, /* F_Port Login. */ ++ FC_ELS_LOGO = 0x05, /* Logout. */ ++ FC_ELS_ABTX = 0x06, /* Abort Exchange */ ++ FC_ELS_RES = 0x08, /* Read Exchange status */ ++ FC_ELS_RSS = 0x09, /* Read sequence status block */ ++ FC_ELS_RSI = 0x0A, /* Request Sequence Initiative */ ++ FC_ELS_ESTC = 0x0C, /* Estimate Credit. */ ++ FC_ELS_RTV = 0x0E, /* Read Timeout Value. */ ++ FC_ELS_RLS = 0x0F, /* Read Link Status. */ ++ FC_ELS_ECHO = 0x10, /* Echo */ ++ FC_ELS_TEST = 0x11, /* Test */ ++ FC_ELS_RRQ = 0x12, /* Reinstate Recovery Qualifier. */ ++ FC_ELS_REC = 0x13, /* Add this for TAPE support in FCR */ ++ FC_ELS_PRLI = 0x20, /* Process Login */ ++ FC_ELS_PRLO = 0x21, /* Process Logout. */ ++ FC_ELS_SCN = 0x22, /* State Change Notification. */ ++ FC_ELS_TPRLO = 0x24, /* Third Party Process Logout. */ ++ FC_ELS_PDISC = 0x50, /* Discover N_Port Parameters. */ ++ FC_ELS_FDISC = 0x51, /* Discover F_Port Parameters. */ ++ FC_ELS_ADISC = 0x52, /* Discover Address. */ ++ FC_ELS_FAN = 0x60, /* Fabric Address Notification */ ++ FC_ELS_RSCN = 0x61, /* Reg State Change Notification */ ++ FC_ELS_SCR = 0x62, /* State Change Registration. */ ++ FC_ELS_RTIN = 0x77, /* Mangement server request */ ++ FC_ELS_RNID = 0x78, /* Mangement server request */ ++ FC_ELS_RLIR = 0x79, /* Registered Link Incident Record */ ++ ++ FC_ELS_RPSC = 0x7D, /* Report Port Speed Capabilities */ ++ FC_ELS_QSA = 0x7E, /* Query Security Attributes. Ref FC-SP */ ++ FC_ELS_E2E_LBEACON = 0x81, ++ /* End-to-End Link Beacon */ ++ FC_ELS_AUTH = 0x90, /* Authentication. Ref FC-SP */ ++ FC_ELS_RFCN = 0x97, /* Request Fabric Change Notification. Ref ++ *FC-SP */ ++ ++}; ++ ++/* ++ * Version numbers for FC-PH standards, ++ * used in login to indicate what port ++ * supports. See FC-PH-X table 158. ++ */ ++enum { ++ FC_PH_VER_4_3 = 0x09, ++ FC_PH_VER_PH_3 = 0x20, ++}; ++ ++/* ++ * PDU size defines ++ */ ++enum { ++ FC_MIN_PDUSZ = 512, ++ FC_MAX_PDUSZ = 2112, ++}; ++ ++/* ++ * N_Port PLOGI Common Service Parameters. ++ * FC-PH-x. Figure-76. pg. 308. ++ */ ++struct fc_plogi_csp_s{ ++ u8 verhi; /* FC-PH high version */ ++ u8 verlo; /* FC-PH low version */ ++ u16 bbcred; /* BB_Credit */ ++ ++#ifdef __BIGENDIAN ++ u8 ciro:1, /* continuously increasing RO */ ++ rro:1, /* random relative offset */ ++ npiv_supp:1, /* NPIV supported */ ++ port_type:1, /* N_Port/F_port */ ++ altbbcred:1, /* alternate BB_Credit */ ++ resolution:1, /* ms/ns ED_TOV resolution */ ++ vvl_info:1, /* VVL Info included */ ++ reserved1:1; ++ ++ u8 hg_supp:1, ++ query_dbc:1, ++ security:1, ++ sync_cap:1, ++ r_t_tov:1, ++ dh_dup_supp:1, ++ cisc:1, /* continuously increasing seq count */ ++ payload:1; ++#else ++ u8 reserved2:2, ++ resolution:1, /* ms/ns ED_TOV resolution */ ++ altbbcred:1, /* alternate BB_Credit */ ++ port_type:1, /* N_Port/F_port */ ++ npiv_supp:1, /* NPIV supported */ ++ rro:1, /* random relative offset */ ++ ciro:1; /* continuously increasing RO */ ++ ++ u8 payload:1, ++ cisc:1, /* continuously increasing seq count */ ++ dh_dup_supp:1, ++ r_t_tov:1, ++ sync_cap:1, ++ security:1, ++ query_dbc:1, ++ hg_supp:1; ++#endif ++ ++ u16 rxsz; /* recieve data_field size */ ++ ++ u16 conseq; ++ u16 ro_bitmap; ++ ++ u32 e_d_tov; ++}; ++ ++/* ++ * N_Port PLOGI Class Specific Parameters. ++ * FC-PH-x. Figure 78. pg. 318. ++ */ ++struct fc_plogi_clp_s{ ++#ifdef __BIGENDIAN ++ u32 class_valid:1; ++ u32 intermix:1; /* class intermix supported if set =1. ++ * valid only for class1. Reserved for ++ * class2 & class3 ++ */ ++ u32 reserved1:2; ++ u32 sequential:1; ++ u32 reserved2:3; ++#else ++ u32 reserved2:3; ++ u32 sequential:1; ++ u32 reserved1:2; ++ u32 intermix:1; /* class intermix supported if set =1. ++ * valid only for class1. Reserved for ++ * class2 & class3 ++ */ ++ u32 class_valid:1; ++#endif ++ ++ u32 reserved3:24; ++ ++ u32 reserved4:16; ++ u32 rxsz:16; /* Receive data_field size */ ++ ++ u32 reserved5:8; ++ u32 conseq:8; ++ u32 e2e_credit:16; /* end to end credit */ ++ ++ u32 reserved7:8; ++ u32 ospx:8; ++ u32 reserved8:16; ++}; ++ ++#define FLOGI_VVL_BRCD 0x42524344 /* ASCII value for each character in ++ * string "BRCD" */ ++ ++/* ++ * PLOGI els command and reply payload ++ */ ++struct fc_logi_s{ ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ struct fc_plogi_csp_s csp; /* common service params */ ++ wwn_t port_name; ++ wwn_t node_name; ++ struct fc_plogi_clp_s class1; /* class 1 service parameters */ ++ struct fc_plogi_clp_s class2; /* class 2 service parameters */ ++ struct fc_plogi_clp_s class3; /* class 3 service parameters */ ++ struct fc_plogi_clp_s class4; /* class 4 service parameters */ ++ u8 vvl[16]; /* vendor version level */ ++}; ++ ++/* ++ * LOGO els command payload ++ */ ++struct fc_logo_s{ ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 nport_id:24; /* N_Port identifier of source */ ++ wwn_t orig_port_name; /* Port name of the LOGO originator */ ++}; ++ ++/* ++ * ADISC els command payload ++ */ ++struct fc_adisc_s { ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 orig_HA:24; /* originator hard address */ ++ wwn_t orig_port_name; /* originator port name */ ++ wwn_t orig_node_name; /* originator node name */ ++ u32 res2:8; ++ u32 nport_id:24; /* originator NPortID */ ++}; ++ ++/* ++ * Exchange status block ++ */ ++struct fc_exch_status_blk_s{ ++ u32 oxid:16; ++ u32 rxid:16; ++ u32 res1:8; ++ u32 orig_np:24; /* originator NPortID */ ++ u32 res2:8; ++ u32 resp_np:24; /* responder NPortID */ ++ u32 es_bits; ++ u32 res3; ++ /* ++ * un modified section of the fields ++ */ ++}; ++ ++/* ++ * RES els command payload ++ */ ++struct fc_res_s { ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 nport_id:24; /* N_Port identifier of source */ ++ u32 oxid:16; ++ u32 rxid:16; ++ u8 assoc_hdr[32]; ++}; ++ ++/* ++ * RES els accept payload ++ */ ++struct fc_res_acc_s{ ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ struct fc_exch_status_blk_s fc_exch_blk; /* Exchange status block */ ++}; ++ ++/* ++ * REC els command payload ++ */ ++struct fc_rec_s { ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 nport_id:24; /* N_Port identifier of source */ ++ u32 oxid:16; ++ u32 rxid:16; ++}; ++ ++#define FC_REC_ESB_OWN_RSP 0x80000000 /* responder owns */ ++#define FC_REC_ESB_SI 0x40000000 /* SI is owned */ ++#define FC_REC_ESB_COMP 0x20000000 /* exchange is complete */ ++#define FC_REC_ESB_ENDCOND_ABN 0x10000000 /* abnormal ending */ ++#define FC_REC_ESB_RQACT 0x04000000 /* recovery qual active */ ++#define FC_REC_ESB_ERRP_MSK 0x03000000 ++#define FC_REC_ESB_OXID_INV 0x00800000 /* invalid OXID */ ++#define FC_REC_ESB_RXID_INV 0x00400000 /* invalid RXID */ ++#define FC_REC_ESB_PRIO_INUSE 0x00200000 ++ ++/* ++ * REC els accept payload ++ */ ++struct fc_rec_acc_s { ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 oxid:16; ++ u32 rxid:16; ++ u32 res1:8; ++ u32 orig_id:24; /* N_Port id of exchange originator */ ++ u32 res2:8; ++ u32 resp_id:24; /* N_Port id of exchange responder */ ++ u32 count; /* data transfer count */ ++ u32 e_stat; /* exchange status */ ++}; ++ ++/* ++ * RSI els payload ++ */ ++struct fc_rsi_s { ++ struct fc_els_cmd_s els_cmd; ++ u32 res1:8; ++ u32 orig_sid:24; ++ u32 oxid:16; ++ u32 rxid:16; ++}; ++ ++/* ++ * structure for PRLI paramater pages, both request & response ++ * see FC-PH-X table 113 & 115 for explanation also FCP table 8 ++ */ ++struct fc_prli_params_s{ ++ u32 reserved: 16; ++#ifdef __BIGENDIAN ++ u32 reserved1: 5; ++ u32 rec_support : 1; ++ u32 task_retry_id : 1; ++ u32 retry : 1; ++ ++ u32 confirm : 1; ++ u32 doverlay:1; ++ u32 initiator:1; ++ u32 target:1; ++ u32 cdmix:1; ++ u32 drmix:1; ++ u32 rxrdisab:1; ++ u32 wxrdisab:1; ++#else ++ u32 retry : 1; ++ u32 task_retry_id : 1; ++ u32 rec_support : 1; ++ u32 reserved1: 5; ++ ++ u32 wxrdisab:1; ++ u32 rxrdisab:1; ++ u32 drmix:1; ++ u32 cdmix:1; ++ u32 target:1; ++ u32 initiator:1; ++ u32 doverlay:1; ++ u32 confirm : 1; ++#endif ++}; ++ ++/* ++ * valid values for rspcode in PRLI ACC payload ++ */ ++enum { ++ FC_PRLI_ACC_XQTD = 0x1, /* request executed */ ++ FC_PRLI_ACC_PREDEF_IMG = 0x5, /* predefined image - no prli needed */ ++}; ++ ++struct fc_prli_params_page_s{ ++ u32 type:8; ++ u32 codext:8; ++#ifdef __BIGENDIAN ++ u32 origprocasv:1; ++ u32 rsppav:1; ++ u32 imagepair:1; ++ u32 reserved1:1; ++ u32 rspcode:4; ++#else ++ u32 rspcode:4; ++ u32 reserved1:1; ++ u32 imagepair:1; ++ u32 rsppav:1; ++ u32 origprocasv:1; ++#endif ++ u32 reserved2:8; ++ ++ u32 origprocas; ++ u32 rspprocas; ++ struct fc_prli_params_s servparams; ++}; ++ ++/* ++ * PRLI request and accept payload, FC-PH-X tables 112 & 114 ++ */ ++struct fc_prli_s{ ++ u32 command:8; ++ u32 pglen:8; ++ u32 pagebytes:16; ++ struct fc_prli_params_page_s parampage; ++}; ++ ++/* ++ * PRLO logout params page ++ */ ++struct fc_prlo_params_page_s{ ++ u32 type:8; ++ u32 type_ext:8; ++#ifdef __BIGENDIAN ++ u32 opa_valid:1; /* originator process associator ++ * valid ++ */ ++ u32 rpa_valid:1; /* responder process associator valid */ ++ u32 res1:14; ++#else ++ u32 res1:14; ++ u32 rpa_valid:1; /* responder process associator valid */ ++ u32 opa_valid:1; /* originator process associator ++ * valid ++ */ ++#endif ++ u32 orig_process_assc; ++ u32 resp_process_assc; ++ ++ u32 res2; ++}; ++ ++/* ++ * PRLO els command payload ++ */ ++struct fc_prlo_s{ ++ u32 command:8; ++ u32 page_len:8; ++ u32 payload_len:16; ++ struct fc_prlo_params_page_s prlo_params[1]; ++}; ++ ++/* ++ * PRLO Logout response parameter page ++ */ ++struct fc_prlo_acc_params_page_s{ ++ u32 type:8; ++ u32 type_ext:8; ++ ++#ifdef __BIGENDIAN ++ u32 opa_valid:1; /* originator process associator ++ * valid ++ */ ++ u32 rpa_valid:1; /* responder process associator valid */ ++ u32 res1:14; ++#else ++ u32 res1:14; ++ u32 rpa_valid:1; /* responder process associator valid */ ++ u32 opa_valid:1; /* originator process associator ++ * valid ++ */ ++#endif ++ u32 orig_process_assc; ++ u32 resp_process_assc; ++ ++ u32 fc4type_csp; ++}; ++ ++/* ++ * PRLO els command ACC payload ++ */ ++struct fc_prlo_acc_s{ ++ u32 command:8; ++ u32 page_len:8; ++ u32 payload_len:16; ++ struct fc_prlo_acc_params_page_s prlo_acc_params[1]; ++}; ++ ++/* ++ * SCR els command payload ++ */ ++enum { ++ FC_SCR_REG_FUNC_FABRIC_DETECTED = 0x01, ++ FC_SCR_REG_FUNC_N_PORT_DETECTED = 0x02, ++ FC_SCR_REG_FUNC_FULL = 0x03, ++ FC_SCR_REG_FUNC_CLEAR_REG = 0xFF, ++}; ++ ++/* SCR VU registrations */ ++enum { ++ FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE = 0x01 ++}; ++ ++struct fc_scr_s{ ++ u32 command:8; ++ u32 res:24; ++ u32 vu_reg_func:8; /* Vendor Unique Registrations */ ++ u32 res1:16; ++ u32 reg_func:8; ++}; ++ ++/* ++ * Information category for Basic link data ++ */ ++enum { ++ FC_CAT_NOP = 0x0, ++ FC_CAT_ABTS = 0x1, ++ FC_CAT_RMC = 0x2, ++ FC_CAT_BA_ACC = 0x4, ++ FC_CAT_BA_RJT = 0x5, ++ FC_CAT_PRMT = 0x6, ++}; ++ ++/* ++ * LS_RJT els reply payload ++ */ ++struct fc_ls_rjt_s { ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 reason_code:8; /* Reason code for reject */ ++ u32 reason_code_expl:8; /* Reason code explanation */ ++ u32 vendor_unique:8; /* Vendor specific */ ++}; ++ ++/* ++ * LS_RJT reason codes ++ */ ++enum { ++ FC_LS_RJT_RSN_INV_CMD_CODE = 0x01, ++ FC_LS_RJT_RSN_LOGICAL_ERROR = 0x03, ++ FC_LS_RJT_RSN_LOGICAL_BUSY = 0x05, ++ FC_LS_RJT_RSN_PROTOCOL_ERROR = 0x07, ++ FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD = 0x09, ++ FC_LS_RJT_RSN_CMD_NOT_SUPP = 0x0B, ++}; ++ ++/* ++ * LS_RJT reason code explanation ++ */ ++enum { ++ FC_LS_RJT_EXP_NO_ADDL_INFO = 0x00, ++ FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS = 0x01, ++ FC_LS_RJT_EXP_SPARMS_ERR_INI_CTL = 0x03, ++ FC_LS_RJT_EXP_SPARMS_ERR_REC_CTL = 0x05, ++ FC_LS_RJT_EXP_SPARMS_ERR_RXSZ = 0x07, ++ FC_LS_RJT_EXP_SPARMS_ERR_CONSEQ = 0x09, ++ FC_LS_RJT_EXP_SPARMS_ERR_CREDIT = 0x0B, ++ FC_LS_RJT_EXP_INV_PORT_NAME = 0x0D, ++ FC_LS_RJT_EXP_INV_NODE_FABRIC_NAME = 0x0E, ++ FC_LS_RJT_EXP_INV_CSP = 0x0F, ++ FC_LS_RJT_EXP_INV_ASSOC_HDR = 0x11, ++ FC_LS_RJT_EXP_ASSOC_HDR_REQD = 0x13, ++ FC_LS_RJT_EXP_INV_ORIG_S_ID = 0x15, ++ FC_LS_RJT_EXP_INV_OXID_RXID_COMB = 0x17, ++ FC_LS_RJT_EXP_CMD_ALREADY_IN_PROG = 0x19, ++ FC_LS_RJT_EXP_LOGIN_REQUIRED = 0x1E, ++ FC_LS_RJT_EXP_INVALID_NPORT_ID = 0x1F, ++ FC_LS_RJT_EXP_INSUFF_RES = 0x29, ++ FC_LS_RJT_EXP_CMD_NOT_SUPP = 0x2C, ++ FC_LS_RJT_EXP_INV_PAYLOAD_LEN = 0x2D, ++}; ++ ++/* ++ * RRQ els command payload ++ */ ++struct fc_rrq_s{ ++ struct fc_els_cmd_s els_cmd; /* ELS command code */ ++ u32 res1:8; ++ u32 s_id:24; /* exchange originator S_ID */ ++ ++ u32 ox_id:16; /* originator exchange ID */ ++ u32 rx_id:16; /* responder exchange ID */ ++ ++ u32 res2[8]; /* optional association header */ ++}; ++ ++/* ++ * ABTS BA_ACC reply payload ++ */ ++struct fc_ba_acc_s{ ++ u32 seq_id_valid:8; /* set to 0x00 for Abort Exchange */ ++ u32 seq_id:8; /* invalid for Abort Exchange */ ++ u32 res2:16; ++ u32 ox_id:16; /* OX_ID from ABTS frame */ ++ u32 rx_id:16; /* RX_ID from ABTS frame */ ++ u32 low_seq_cnt:16; /* set to 0x0000 for Abort Exchange */ ++ u32 high_seq_cnt:16;/* set to 0xFFFF for Abort Exchange */ ++}; ++ ++/* ++ * ABTS BA_RJT reject payload ++ */ ++struct fc_ba_rjt_s{ ++ u32 res1:8; /* Reserved */ ++ u32 reason_code:8; /* reason code for reject */ ++ u32 reason_expl:8; /* reason code explanation */ ++ u32 vendor_unique:8;/* vendor unique reason code,set to 0 */ ++}; ++ ++/* ++ * TPRLO logout parameter page ++ */ ++struct fc_tprlo_params_page_s{ ++ u32 type:8; ++ u32 type_ext:8; ++ ++#ifdef __BIGENDIAN ++ u32 opa_valid:1; ++ u32 rpa_valid:1; ++ u32 tpo_nport_valid:1; ++ u32 global_process_logout:1; ++ u32 res1:12; ++#else ++ u32 res1:12; ++ u32 global_process_logout:1; ++ u32 tpo_nport_valid:1; ++ u32 rpa_valid:1; ++ u32 opa_valid:1; ++#endif ++ ++ u32 orig_process_assc; ++ u32 resp_process_assc; ++ ++ u32 res2:8; ++ u32 tpo_nport_id; ++}; ++ ++/* ++ * TPRLO ELS command payload ++ */ ++struct fc_tprlo_s{ ++ u32 command:8; ++ u32 page_len:8; ++ u32 payload_len:16; ++ ++ struct fc_tprlo_params_page_s tprlo_params[1]; ++}; ++ ++enum fc_tprlo_type{ ++ FC_GLOBAL_LOGO = 1, ++ FC_TPR_LOGO ++}; ++ ++/* ++ * TPRLO els command ACC payload ++ */ ++struct fc_tprlo_acc_s{ ++ u32 command:8; ++ u32 page_len:8; ++ u32 payload_len:16; ++ struct fc_prlo_acc_params_page_s tprlo_acc_params[1]; ++}; ++ ++/* ++ * RSCN els command req payload ++ */ ++#define FC_RSCN_PGLEN 0x4 ++ ++enum fc_rscn_format{ ++ FC_RSCN_FORMAT_PORTID = 0x0, ++ FC_RSCN_FORMAT_AREA = 0x1, ++ FC_RSCN_FORMAT_DOMAIN = 0x2, ++ FC_RSCN_FORMAT_FABRIC = 0x3, ++}; ++ ++struct fc_rscn_event_s{ ++ u32 format:2; ++ u32 qualifier:4; ++ u32 resvd:2; ++ u32 portid:24; ++}; ++ ++struct fc_rscn_pl_s{ ++ u8 command; ++ u8 pagelen; ++ u16 payldlen; ++ struct fc_rscn_event_s event[1]; ++}; ++ ++/* ++ * ECHO els command req payload ++ */ ++struct fc_echo_s { ++ struct fc_els_cmd_s els_cmd; ++}; ++ ++/* ++ * RNID els command ++ */ ++ ++#define RNID_NODEID_DATA_FORMAT_COMMON 0x00 ++#define RNID_NODEID_DATA_FORMAT_FCP3 0x08 ++#define RNID_NODEID_DATA_FORMAT_DISCOVERY 0xDF ++ ++#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001 ++#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002 ++#define RNID_ASSOCIATED_TYPE_HUB 0x00000003 ++#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004 ++#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005 ++#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009 ++#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A ++#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B ++#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E ++#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011 ++#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002 ++#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003 ++#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF ++ ++/* ++ * RNID els command payload ++ */ ++struct fc_rnid_cmd_s{ ++ struct fc_els_cmd_s els_cmd; ++ u32 node_id_data_format:8; ++ u32 reserved:24; ++}; ++ ++/* ++ * RNID els response payload ++ */ ++ ++struct fc_rnid_common_id_data_s{ ++ wwn_t port_name; ++ wwn_t node_name; ++}; ++ ++struct fc_rnid_general_topology_data_s{ ++ u32 vendor_unique[4]; ++ u32 asso_type; ++ u32 phy_port_num; ++ u32 num_attached_nodes; ++ u32 node_mgmt:8; ++ u32 ip_version:8; ++ u32 udp_tcp_port_num:16; ++ u32 ip_address[4]; ++ u32 reserved:16; ++ u32 vendor_specific:16; ++}; ++ ++struct fc_rnid_acc_s{ ++ struct fc_els_cmd_s els_cmd; ++ u32 node_id_data_format:8; ++ u32 common_id_data_length:8; ++ u32 reserved:8; ++ u32 specific_id_data_length:8; ++ struct fc_rnid_common_id_data_s common_id_data; ++ struct fc_rnid_general_topology_data_s gen_topology_data; ++}; ++ ++#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001 ++#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002 ++#define RNID_ASSOCIATED_TYPE_HUB 0x00000003 ++#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004 ++#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005 ++#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009 ++#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A ++#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B ++#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E ++#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011 ++#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002 ++#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003 ++#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF ++ ++enum fc_rpsc_speed_cap{ ++ RPSC_SPEED_CAP_1G = 0x8000, ++ RPSC_SPEED_CAP_2G = 0x4000, ++ RPSC_SPEED_CAP_4G = 0x2000, ++ RPSC_SPEED_CAP_10G = 0x1000, ++ RPSC_SPEED_CAP_8G = 0x0800, ++ RPSC_SPEED_CAP_16G = 0x0400, ++ ++ RPSC_SPEED_CAP_UNKNOWN = 0x0001, ++}; ++ ++enum fc_rpsc_op_speed_s{ ++ RPSC_OP_SPEED_1G = 0x8000, ++ RPSC_OP_SPEED_2G = 0x4000, ++ RPSC_OP_SPEED_4G = 0x2000, ++ RPSC_OP_SPEED_10G = 0x1000, ++ RPSC_OP_SPEED_8G = 0x0800, ++ RPSC_OP_SPEED_16G = 0x0400, ++ ++ RPSC_OP_SPEED_NOT_EST = 0x0001, /*! speed not established */ ++}; ++ ++struct fc_rpsc_speed_info_s{ ++ u16 port_speed_cap; /*! see fc_rpsc_speed_cap_t */ ++ u16 port_op_speed; /*! see fc_rpsc_op_speed_t */ ++}; ++ ++enum link_e2e_beacon_subcmd{ ++ LINK_E2E_BEACON_ON = 1, ++ LINK_E2E_BEACON_OFF = 2 ++}; ++ ++enum beacon_type{ ++ BEACON_TYPE_NORMAL = 1, /*! Normal Beaconing. Green */ ++ BEACON_TYPE_WARN = 2, /*! Warning Beaconing. Yellow/Amber */ ++ BEACON_TYPE_CRITICAL = 3 /*! Critical Beaconing. Red */ ++}; ++ ++struct link_e2e_beacon_param_s { ++ u8 beacon_type; /* Beacon Type. See beacon_type_t */ ++ u8 beacon_frequency; ++ /* Beacon frequency. Number of blinks ++ * per 10 seconds ++ */ ++ u16 beacon_duration;/* Beacon duration (in Seconds). The ++ * command operation should be ++ * terminated at the end of this ++ * timeout value. ++ * ++ * Ignored if diag_sub_cmd is ++ * LINK_E2E_BEACON_OFF. ++ * ++ * If 0, beaconing will continue till a ++ * BEACON OFF request is received ++ */ ++}; ++ ++/* ++ * Link E2E beacon request/good response format. For LS_RJTs use fc_ls_rjt_t ++ */ ++struct link_e2e_beacon_req_s{ ++ u32 ls_code; /*! FC_ELS_E2E_LBEACON in requests * ++ *or FC_ELS_ACC in good replies */ ++ u32 ls_sub_cmd; /*! See link_e2e_beacon_subcmd_t */ ++ struct link_e2e_beacon_param_s beacon_parm; ++}; ++ ++/** ++ * If RPSC request is sent to the Domain Controller, the request is for ++ * all the ports within that domain (TODO - I don't think FOS implements ++ * this...). ++ */ ++struct fc_rpsc_cmd_s{ ++ struct fc_els_cmd_s els_cmd; ++}; ++ ++/* ++ * RPSC Acc ++ */ ++struct fc_rpsc_acc_s{ ++ u32 command:8; ++ u32 rsvd:8; ++ u32 num_entries:16; ++ ++ struct fc_rpsc_speed_info_s speed_info[1]; ++}; ++ ++/** ++ * If RPSC2 request is sent to the Domain Controller, ++ */ ++#define FC_BRCD_TOKEN 0x42524344 ++ ++struct fc_rpsc2_cmd_s{ ++ struct fc_els_cmd_s els_cmd; ++ u32 token; ++ u16 resvd; ++ u16 num_pids; /* Number of pids in the request */ ++ struct { ++ u32 rsvd1:8; ++ u32 pid:24; /* port identifier */ ++ } pid_list[1]; ++}; ++ ++enum fc_rpsc2_port_type{ ++ RPSC2_PORT_TYPE_UNKNOWN = 0, ++ RPSC2_PORT_TYPE_NPORT = 1, ++ RPSC2_PORT_TYPE_NLPORT = 2, ++ RPSC2_PORT_TYPE_NPIV_PORT = 0x5f, ++ RPSC2_PORT_TYPE_NPORT_TRUNK = 0x6f, ++}; ++ ++/* ++ * RPSC2 portInfo entry structure ++ */ ++struct fc_rpsc2_port_info_s{ ++ u32 pid; /* PID */ ++ u16 resvd1; ++ u16 index; /* port number / index */ ++ u8 resvd2; ++ u8 type; /* port type N/NL/... */ ++ u16 speed; /* port Operating Speed */ ++}; ++ ++/* ++ * RPSC2 Accept payload ++ */ ++struct fc_rpsc2_acc_s{ ++ u8 els_cmd; ++ u8 resvd; ++ u16 num_pids; /* Number of pids in the request */ ++ struct fc_rpsc2_port_info_s port_info[1]; /* port information */ ++}; ++ ++/** ++ * bit fields so that multiple classes can be specified ++ */ ++enum fc_cos{ ++ FC_CLASS_2 = 0x04, ++ FC_CLASS_3 = 0x08, ++ FC_CLASS_2_3 = 0x0C, ++}; ++ ++/* ++ * symbolic name ++ */ ++struct fc_symname_s{ ++ u8 symname[FC_SYMNAME_MAX]; ++}; ++ ++struct fc_alpabm_s{ ++ u8 alpa_bm[FC_ALPA_MAX / 8]; ++}; ++ ++/* ++ * protocol default timeout values ++ */ ++#define FC_ED_TOV 2 ++#define FC_REC_TOV (FC_ED_TOV + 1) ++#define FC_RA_TOV 10 ++#define FC_ELS_TOV (2 * FC_RA_TOV) ++ ++/* ++ * virtual fabric related defines ++ */ ++#define FC_VF_ID_NULL 0 /* must not be used as VF_ID */ ++#define FC_VF_ID_MIN 1 ++#define FC_VF_ID_MAX 0xEFF ++#define FC_VF_ID_CTL 0xFEF /* control VF_ID */ ++ ++/** ++ * Virtual Fabric Tagging header format ++ * @caution This is defined only in BIG ENDIAN format. ++ */ ++struct fc_vft_s{ ++ u32 r_ctl:8; ++ u32 ver:2; ++ u32 type:4; ++ u32 res_a:2; ++ u32 priority:3; ++ u32 vf_id:12; ++ u32 res_b:1; ++ u32 hopct:8; ++ u32 res_c:24; ++}; ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/fc_sp.h b/drivers/scsi/bfa/include/protocol/fc_sp.h +new file mode 100644 +index 0000000..55bb0b3 +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/fc_sp.h +@@ -0,0 +1,224 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FC_SP_H__ ++#define __FC_SP_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum auth_els_flags{ ++ FC_AUTH_ELS_MORE_FRAGS_FLAG = 0x80, /*! bit-7. More Fragments ++ * Follow ++ */ ++ FC_AUTH_ELS_CONCAT_FLAG = 0x40, /*! bit-6. Concatenation Flag */ ++ FC_AUTH_ELS_SEQ_NUM_FLAG = 0x01 /*! bit-0. Sequence Number */ ++}; ++ ++enum auth_msg_codes{ ++ FC_AUTH_MC_AUTH_RJT = 0x0A, /*! Auth Reject */ ++ FC_AUTH_MC_AUTH_NEG = 0x0B, /*! Auth Negotiate */ ++ FC_AUTH_MC_AUTH_DONE = 0x0C, /*! Auth Done */ ++ ++ FC_AUTH_MC_DHCHAP_CHAL = 0x10, /*! DHCHAP Challenge */ ++ FC_AUTH_MC_DHCHAP_REPLY = 0x11, /*! DHCHAP Reply */ ++ FC_AUTH_MC_DHCHAP_SUCC = 0x12, /*! DHCHAP Success */ ++ ++ FC_AUTH_MC_FCAP_REQ = 0x13, /*! FCAP Request */ ++ FC_AUTH_MC_FCAP_ACK = 0x14, /*! FCAP Acknowledge */ ++ FC_AUTH_MC_FCAP_CONF = 0x15, /*! FCAP Confirm */ ++ ++ FC_AUTH_MC_FCPAP_INIT = 0x16, /*! FCPAP Init */ ++ FC_AUTH_MC_FCPAP_ACC = 0x17, /*! FCPAP Accept */ ++ FC_AUTH_MC_FCPAP_COMP = 0x18, /*! FCPAP Complete */ ++ ++ FC_AUTH_MC_IKE_SA_INIT = 0x22, /*! IKE SA INIT */ ++ FC_AUTH_MC_IKE_SA_AUTH = 0x23, /*! IKE SA Auth */ ++ FC_AUTH_MC_IKE_CREATE_CHILD_SA = 0x24, /*! IKE Create Child SA */ ++ FC_AUTH_MC_IKE_INFO = 0x25, /*! IKE informational */ ++}; ++ ++enum auth_proto_version{ ++ FC_AUTH_PROTO_VER_1 = 1, /*! Protocol Version 1 */ ++}; ++ ++enum { ++ FC_AUTH_ELS_COMMAND_CODE = 0x90,/*! Authentication ELS Command code */ ++ FC_AUTH_PROTO_PARAM_LEN_SZ = 4, /*! Size of Proto Parameter Len Field */ ++ FC_AUTH_PROTO_PARAM_VAL_SZ = 4, /*! Size of Proto Parameter Val Field */ ++ FC_MAX_AUTH_SECRET_LEN = 256, ++ /*! Maximum secret string length */ ++ FC_AUTH_NUM_USABLE_PROTO_LEN_SZ = 4, ++ /*! Size of usable protocols field */ ++ FC_AUTH_RESP_VALUE_LEN_SZ = 4, ++ /*! Size of response value length */ ++ FC_MAX_CHAP_KEY_LEN = 256, /*! Maximum md5 digest length */ ++ FC_MAX_AUTH_RETRIES = 3, /*! Maximum number of retries */ ++ FC_MD5_DIGEST_LEN = 16, /*! MD5 digest length */ ++ FC_SHA1_DIGEST_LEN = 20, /*! SHA1 digest length */ ++ FC_MAX_DHG_SUPPORTED = 1, /*! Maximum DH Groups supported */ ++ FC_MAX_ALG_SUPPORTED = 1, /*! Maximum algorithms supported */ ++ FC_MAX_PROTO_SUPPORTED = 1, /*! Maximum protocols supported */ ++ FC_START_TXN_ID = 2, /*! Starting transaction ID */ ++}; ++ ++enum auth_proto_id{ ++ FC_AUTH_PROTO_DHCHAP = 0x00000001, ++ FC_AUTH_PROTO_FCAP = 0x00000002, ++ FC_AUTH_PROTO_FCPAP = 0x00000003, ++ FC_AUTH_PROTO_IKEv2 = 0x00000004, ++ FC_AUTH_PROTO_IKEv2_AUTH = 0x00000005, ++}; ++ ++struct auth_name_s{ ++ u16 name_tag; /*! Name Tag = 1 for Authentication */ ++ u16 name_len; /*! Name Length = 8 for Authentication ++ */ ++ wwn_t name; /*! Name. TODO - is this PWWN */ ++}; ++ ++ ++enum auth_hash_func{ ++ FC_AUTH_HASH_FUNC_MD5 = 0x00000005, ++ FC_AUTH_HASH_FUNC_SHA_1 = 0x00000006, ++}; ++ ++enum auth_dh_gid{ ++ FC_AUTH_DH_GID_0_DHG_NULL = 0x00000000, ++ FC_AUTH_DH_GID_1_DHG_1024 = 0x00000001, ++ FC_AUTH_DH_GID_2_DHG_1280 = 0x00000002, ++ FC_AUTH_DH_GID_3_DHG_1536 = 0x00000003, ++ FC_AUTH_DH_GID_4_DHG_2048 = 0x00000004, ++ FC_AUTH_DH_GID_6_DHG_3072 = 0x00000006, ++ FC_AUTH_DH_GID_7_DHG_4096 = 0x00000007, ++ FC_AUTH_DH_GID_8_DHG_6144 = 0x00000008, ++ FC_AUTH_DH_GID_9_DHG_8192 = 0x00000009, ++}; ++ ++struct auth_els_msg_s { ++ u8 auth_els_code; /* Authentication ELS Code (0x90) */ ++ u8 auth_els_flag; /* Authentication ELS Flags */ ++ u8 auth_msg_code; /* Authentication Message Code */ ++ u8 proto_version; /* Protocol Version */ ++ u32 msg_len; /* Message Length */ ++ u32 trans_id; /* Transaction Identifier (T_ID) */ ++ ++ /* Msg payload follows... */ ++}; ++ ++ ++enum auth_neg_param_tags { ++ FC_AUTH_NEG_DHCHAP_HASHLIST = 0x0001, ++ FC_AUTH_NEG_DHCHAP_DHG_ID_LIST = 0x0002, ++}; ++ ++ ++struct dhchap_param_format_s { ++ u16 tag; /*! Parameter Tag. See ++ * auth_neg_param_tags_t ++ */ ++ u16 word_cnt; ++ ++ /* followed by variable length parameter value... */ ++}; ++ ++struct auth_proto_params_s { ++ u32 proto_param_len; ++ u32 proto_id; ++ ++ /* ++ * Followed by variable length Protocol specific parameters. DH-CHAP ++ * uses dhchap_param_format_t ++ */ ++}; ++ ++struct auth_neg_msg_s { ++ struct auth_name_s auth_ini_name; ++ u32 usable_auth_protos; ++ struct auth_proto_params_s proto_params[1]; /*! (1..usable_auth_proto) ++ * protocol params ++ */ ++}; ++ ++struct auth_dh_val_s { ++ u32 dh_val_len; ++ u32 dh_val[1]; ++}; ++ ++struct auth_dhchap_chal_msg_s { ++ struct auth_els_msg_s hdr; ++ struct auth_name_s auth_responder_name; /* TODO VRK - is auth_name_t ++ * type OK? ++ */ ++ u32 hash_id; ++ u32 dh_grp_id; ++ u32 chal_val_len; ++ char chal_val[1]; ++ ++ /* ...followed by variable Challenge length/value and DH length/value */ ++}; ++ ++ ++enum auth_rjt_codes { ++ FC_AUTH_RJT_CODE_AUTH_FAILURE = 0x01, ++ FC_AUTH_RJT_CODE_LOGICAL_ERR = 0x02, ++}; ++ ++enum auth_rjt_code_exps { ++ FC_AUTH_CEXP_AUTH_MECH_NOT_USABLE = 0x01, ++ FC_AUTH_CEXP_DH_GROUP_NOT_USABLE = 0x02, ++ FC_AUTH_CEXP_HASH_FUNC_NOT_USABLE = 0x03, ++ FC_AUTH_CEXP_AUTH_XACT_STARTED = 0x04, ++ FC_AUTH_CEXP_AUTH_FAILED = 0x05, ++ FC_AUTH_CEXP_INCORRECT_PLD = 0x06, ++ FC_AUTH_CEXP_INCORRECT_PROTO_MSG = 0x07, ++ FC_AUTH_CEXP_RESTART_AUTH_PROTO = 0x08, ++ FC_AUTH_CEXP_AUTH_CONCAT_NOT_SUPP = 0x09, ++ FC_AUTH_CEXP_PROTO_VER_NOT_SUPP = 0x0A, ++}; ++ ++enum auth_status { ++ FC_AUTH_STATE_INPROGRESS = 0, /*! authentication in progress */ ++ FC_AUTH_STATE_FAILED = 1, /*! authentication failed */ ++ FC_AUTH_STATE_SUCCESS = 2 /*! authentication successful */ ++}; ++ ++struct auth_rjt_msg_s { ++ struct auth_els_msg_s hdr; ++ u8 reason_code; ++ u8 reason_code_exp; ++ u8 rsvd[2]; ++}; ++ ++ ++struct auth_dhchap_neg_msg_s { ++ struct auth_els_msg_s hdr; ++ struct auth_neg_msg_s nego; ++}; ++ ++struct auth_dhchap_reply_msg_s { ++ struct auth_els_msg_s hdr; ++ ++ /* ++ * followed by response value length & Value + DH Value Length & Value ++ */ ++}; ++ ++#pragma pack() ++ ++#endif /* __FC_SP_H__ */ +diff --git a/drivers/scsi/bfa/include/protocol/fcp.h b/drivers/scsi/bfa/include/protocol/fcp.h +new file mode 100644 +index 0000000..9ade68a +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/fcp.h +@@ -0,0 +1,186 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FCPPROTO_H__ ++#define __FCPPROTO_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++enum { ++ FCP_RJT = 0x01000000, /* SRR reject */ ++ FCP_SRR_ACCEPT = 0x02000000, /* SRR accept */ ++ FCP_SRR = 0x14000000, /* Sequence Retransmission Request */ ++}; ++ ++/* ++ * SRR FC-4 LS payload ++ */ ++struct fc_srr_s{ ++ u32 ls_cmd; ++ u32 ox_id:16; /* ox-id */ ++ u32 rx_id:16; /* rx-id */ ++ u32 ro; /* relative offset */ ++ u32 r_ctl:8; /* R_CTL for I.U. */ ++ u32 res:24; ++}; ++ ++ ++/* ++ * FCP_CMND definitions ++ */ ++#define FCP_CMND_CDB_LEN 16 ++#define FCP_CMND_LUN_LEN 8 ++ ++struct fcp_cmnd_s{ ++ lun_t lun; /* 64-bit LU number */ ++ u8 crn; /* command reference number */ ++#ifdef __BIGENDIAN ++ u8 resvd:1, ++ priority:4, /* FCP-3: SAM-3 priority */ ++ taskattr:3; /* scsi task attribute */ ++#else ++ u8 taskattr:3, /* scsi task attribute */ ++ priority:4, /* FCP-3: SAM-3 priority */ ++ resvd:1; ++#endif ++ u8 tm_flags; /* task management flags */ ++#ifdef __BIGENDIAN ++ u8 addl_cdb_len:6, /* additional CDB length words */ ++ iodir:2; /* read/write FCP_DATA IUs */ ++#else ++ u8 iodir:2, /* read/write FCP_DATA IUs */ ++ addl_cdb_len:6; /* additional CDB length */ ++#endif ++ struct scsi_cdb_s cdb; ++ ++ /* ++ * !!! additional cdb bytes follows here!!! ++ */ ++ u32 fcp_dl; /* bytes to be transferred */ ++}; ++ ++#define fcp_cmnd_cdb_len(_cmnd) ((_cmnd)->addl_cdb_len * 4 + FCP_CMND_CDB_LEN) ++#define fcp_cmnd_fcpdl(_cmnd) ((&(_cmnd)->fcp_dl)[(_cmnd)->addl_cdb_len]) ++ ++/* ++ * fcp_cmnd_t.iodir field values ++ */ ++enum fcp_iodir{ ++ FCP_IODIR_NONE = 0, ++ FCP_IODIR_WRITE = 1, ++ FCP_IODIR_READ = 2, ++ FCP_IODIR_RW = 3, ++}; ++ ++/* ++ * Task attribute field ++ */ ++enum { ++ FCP_TASK_ATTR_SIMPLE = 0, ++ FCP_TASK_ATTR_HOQ = 1, ++ FCP_TASK_ATTR_ORDERED = 2, ++ FCP_TASK_ATTR_ACA = 4, ++ FCP_TASK_ATTR_UNTAGGED = 5, /* obsolete in FCP-3 */ ++}; ++ ++/* ++ * Task management flags field - only one bit shall be set ++ */ ++#ifndef BIT ++#define BIT(_x) (1 << (_x)) ++#endif ++enum fcp_tm_cmnd{ ++ FCP_TM_ABORT_TASK_SET = BIT(1), ++ FCP_TM_CLEAR_TASK_SET = BIT(2), ++ FCP_TM_LUN_RESET = BIT(4), ++ FCP_TM_TARGET_RESET = BIT(5), /* obsolete in FCP-3 */ ++ FCP_TM_CLEAR_ACA = BIT(6), ++}; ++ ++/* ++ * FCP_XFER_RDY IU defines ++ */ ++struct fcp_xfer_rdy_s{ ++ u32 data_ro; ++ u32 burst_len; ++ u32 reserved; ++}; ++ ++/* ++ * FCP_RSP residue flags ++ */ ++enum fcp_residue{ ++ FCP_NO_RESIDUE = 0, /* no residue */ ++ FCP_RESID_OVER = 1, /* more data left that was not sent */ ++ FCP_RESID_UNDER = 2, /* less data than requested */ ++}; ++ ++enum { ++ FCP_RSPINFO_GOOD = 0, ++ FCP_RSPINFO_DATALEN_MISMATCH = 1, ++ FCP_RSPINFO_CMND_INVALID = 2, ++ FCP_RSPINFO_ROLEN_MISMATCH = 3, ++ FCP_RSPINFO_TM_NOT_SUPP = 4, ++ FCP_RSPINFO_TM_FAILED = 5, ++}; ++ ++struct fcp_rspinfo_s{ ++ u32 res0:24; ++ u32 rsp_code:8; /* response code (as above) */ ++ u32 res1; ++}; ++ ++struct fcp_resp_s{ ++ u32 reserved[2]; /* 2 words reserved */ ++ u16 reserved2; ++#ifdef __BIGENDIAN ++ u8 reserved3:3; ++ u8 fcp_conf_req:1; /* FCP_CONF is requested */ ++ u8 resid_flags:2; /* underflow/overflow */ ++ u8 sns_len_valid:1;/* sense len is valid */ ++ u8 rsp_len_valid:1;/* response len is valid */ ++#else ++ u8 rsp_len_valid:1;/* response len is valid */ ++ u8 sns_len_valid:1;/* sense len is valid */ ++ u8 resid_flags:2; /* underflow/overflow */ ++ u8 fcp_conf_req:1; /* FCP_CONF is requested */ ++ u8 reserved3:3; ++#endif ++ u8 scsi_status; /* one byte SCSI status */ ++ u32 residue; /* residual data bytes */ ++ u32 sns_len; /* length od sense info */ ++ u32 rsp_len; /* length of response info */ ++}; ++ ++#define fcp_snslen(__fcprsp) ((__fcprsp)->sns_len_valid ? \ ++ (__fcprsp)->sns_len : 0) ++#define fcp_rsplen(__fcprsp) ((__fcprsp)->rsp_len_valid ? \ ++ (__fcprsp)->rsp_len : 0) ++#define fcp_rspinfo(__fcprsp) ((struct fcp_rspinfo_s *)((__fcprsp) + 1)) ++#define fcp_snsinfo(__fcprsp) (((u8 *)fcp_rspinfo(__fcprsp)) + \ ++ fcp_rsplen(__fcprsp)) ++ ++struct fcp_cmnd_fr_s{ ++ struct fchs_s fchs; ++ struct fcp_cmnd_s fcp; ++}; ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/fdmi.h b/drivers/scsi/bfa/include/protocol/fdmi.h +new file mode 100644 +index 0000000..6c05c26 +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/fdmi.h +@@ -0,0 +1,163 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __FDMI_H__ ++#define __FDMI_H__ ++ ++#include ++#include ++#include ++ ++#pragma pack(1) ++ ++/* ++ * FDMI Command Codes ++ */ ++#define FDMI_GRHL 0x0100 ++#define FDMI_GHAT 0x0101 ++#define FDMI_GRPL 0x0102 ++#define FDMI_GPAT 0x0110 ++#define FDMI_RHBA 0x0200 ++#define FDMI_RHAT 0x0201 ++#define FDMI_RPRT 0x0210 ++#define FDMI_RPA 0x0211 ++#define FDMI_DHBA 0x0300 ++#define FDMI_DPRT 0x0310 ++ ++/* ++ * FDMI reason codes ++ */ ++#define FDMI_NO_ADDITIONAL_EXP 0x00 ++#define FDMI_HBA_ALREADY_REG 0x10 ++#define FDMI_HBA_ATTRIB_NOT_REG 0x11 ++#define FDMI_HBA_ATTRIB_MULTIPLE 0x12 ++#define FDMI_HBA_ATTRIB_LENGTH_INVALID 0x13 ++#define FDMI_HBA_ATTRIB_NOT_PRESENT 0x14 ++#define FDMI_PORT_ORIG_NOT_IN_LIST 0x15 ++#define FDMI_PORT_HBA_NOT_IN_LIST 0x16 ++#define FDMI_PORT_ATTRIB_NOT_REG 0x20 ++#define FDMI_PORT_NOT_REG 0x21 ++#define FDMI_PORT_ATTRIB_MULTIPLE 0x22 ++#define FDMI_PORT_ATTRIB_LENGTH_INVALID 0x23 ++#define FDMI_PORT_ALREADY_REGISTEREED 0x24 ++ ++/* ++ * FDMI Transmission Speed Mask values ++ */ ++#define FDMI_TRANS_SPEED_1G 0x00000001 ++#define FDMI_TRANS_SPEED_2G 0x00000002 ++#define FDMI_TRANS_SPEED_10G 0x00000004 ++#define FDMI_TRANS_SPEED_4G 0x00000008 ++#define FDMI_TRANS_SPEED_8G 0x00000010 ++#define FDMI_TRANS_SPEED_16G 0x00000020 ++#define FDMI_TRANS_SPEED_UNKNOWN 0x00008000 ++ ++/* ++ * FDMI HBA attribute types ++ */ ++enum fdmi_hba_attribute_type { ++ FDMI_HBA_ATTRIB_NODENAME = 1, /* 0x0001 */ ++ FDMI_HBA_ATTRIB_MANUFACTURER, /* 0x0002 */ ++ FDMI_HBA_ATTRIB_SERIALNUM, /* 0x0003 */ ++ FDMI_HBA_ATTRIB_MODEL, /* 0x0004 */ ++ FDMI_HBA_ATTRIB_MODEL_DESC, /* 0x0005 */ ++ FDMI_HBA_ATTRIB_HW_VERSION, /* 0x0006 */ ++ FDMI_HBA_ATTRIB_DRIVER_VERSION, /* 0x0007 */ ++ FDMI_HBA_ATTRIB_ROM_VERSION, /* 0x0008 */ ++ FDMI_HBA_ATTRIB_FW_VERSION, /* 0x0009 */ ++ FDMI_HBA_ATTRIB_OS_NAME, /* 0x000A */ ++ FDMI_HBA_ATTRIB_MAX_CT, /* 0x000B */ ++ ++ FDMI_HBA_ATTRIB_MAX_TYPE ++}; ++ ++/* ++ * FDMI Port attribute types ++ */ ++enum fdmi_port_attribute_type { ++ FDMI_PORT_ATTRIB_FC4_TYPES = 1, /* 0x0001 */ ++ FDMI_PORT_ATTRIB_SUPP_SPEED, /* 0x0002 */ ++ FDMI_PORT_ATTRIB_PORT_SPEED, /* 0x0003 */ ++ FDMI_PORT_ATTRIB_FRAME_SIZE, /* 0x0004 */ ++ FDMI_PORT_ATTRIB_DEV_NAME, /* 0x0005 */ ++ FDMI_PORT_ATTRIB_HOST_NAME, /* 0x0006 */ ++ ++ FDMI_PORT_ATTR_MAX_TYPE ++}; ++ ++/* ++ * FDMI attribute ++ */ ++struct fdmi_attr_s { ++ u16 type; ++ u16 len; ++ u8 value[1]; ++}; ++ ++/* ++ * HBA Attribute Block ++ */ ++struct fdmi_hba_attr_s { ++ u32 attr_count; /* # of attributes */ ++ struct fdmi_attr_s hba_attr; /* n attributes */ ++}; ++ ++/* ++ * Registered Port List ++ */ ++struct fdmi_port_list_s { ++ u32 num_ports; /* number Of Port Entries */ ++ wwn_t port_entry; /* one or more */ ++}; ++ ++/* ++ * Port Attribute Block ++ */ ++struct fdmi_port_attr_s { ++ u32 attr_count; /* # of attributes */ ++ struct fdmi_attr_s port_attr; /* n attributes */ ++}; ++ ++/* ++ * FDMI Register HBA Attributes ++ */ ++struct fdmi_rhba_s { ++ wwn_t hba_id; /* HBA Identifier */ ++ struct fdmi_port_list_s port_list; /* Registered Port List */ ++ struct fdmi_hba_attr_s hba_attr_blk; /* HBA attribute block */ ++}; ++ ++/* ++ * FDMI Register Port ++ */ ++struct fdmi_rprt_s { ++ wwn_t hba_id; /* HBA Identifier */ ++ wwn_t port_name; /* Port wwn */ ++ struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */ ++}; ++ ++/* ++ * FDMI Register Port Attributes ++ */ ++struct fdmi_rpa_s { ++ wwn_t port_name; /* port wwn */ ++ struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */ ++}; ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h +new file mode 100644 +index 0000000..6830dc3 +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/pcifw.h +@@ -0,0 +1,75 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * pcifw.h PCI FW related headers ++ */ ++ ++#ifndef __PCIFW_H__ ++#define __PCIFW_H__ ++ ++#pragma pack(1) ++ ++struct pnp_hdr_s{ ++ u32 signature; /* "$PnP" */ ++ u8 rev; /* Struct revision */ ++ u8 len; /* Header structure len in multiples ++ * of 16 bytes */ ++ u16 off; /* Offset to next header 00 if none */ ++ u8 rsvd; /* Reserved byte */ ++ u8 cksum; /* 8-bit checksum for this header */ ++ u32 pnp_dev_id; /* PnP Device Id */ ++ u16 mfstr; /* Pointer to manufacturer string */ ++ u16 prstr; /* Pointer to product string */ ++ u8 devtype[3]; /* Device Type Code */ ++ u8 devind; /* Device Indicator */ ++ u16 bcventr; /* Bootstrap entry vector */ ++ u16 rsvd2; /* Reserved */ ++ u16 sriv; /* Static resource information vector */ ++}; ++ ++struct pci_3_0_ds_s{ ++ u32 sig; /* Signature "PCIR" */ ++ u16 vendid; /* Vendor ID */ ++ u16 devid; /* Device ID */ ++ u16 devlistoff; /* Device List Offset */ ++ u16 len; /* PCI Data Structure Length */ ++ u8 rev; /* PCI Data Structure Revision */ ++ u8 clcode[3]; /* Class Code */ ++ u16 imglen; /* Code image length in multiples of ++ * 512 bytes */ ++ u16 coderev; /* Revision level of code/data */ ++ u8 codetype; /* Code type 0x00 - BIOS */ ++ u8 indr; /* Last image indicator */ ++ u16 mrtimglen; /* Max Run Time Image Length */ ++ u16 cuoff; /* Config Utility Code Header Offset */ ++ u16 dmtfclp; /* DMTF CLP entry point offset */ ++}; ++ ++struct pci_optrom_hdr_s{ ++ u16 sig; /* Signature 0x55AA */ ++ u8 len; /* Option ROM length in units of 512 bytes */ ++ u8 inivec[3]; /* Initialization vector */ ++ u8 rsvd[16]; /* Reserved field */ ++ u16 verptr; /* Pointer to version string - private */ ++ u16 pcids; /* Pointer to PCI data structure */ ++ u16 pnphdr; /* Pointer to PnP expansion header */ ++}; ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/include/protocol/scsi.h b/drivers/scsi/bfa/include/protocol/scsi.h +new file mode 100644 +index 0000000..b220e6b +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/scsi.h +@@ -0,0 +1,1648 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __SCSI_H__ ++#define __SCSI_H__ ++ ++#include ++ ++#pragma pack(1) ++ ++/* ++ * generic SCSI cdb definition ++ */ ++#define SCSI_MAX_CDBLEN 16 ++struct scsi_cdb_s{ ++ u8 scsi_cdb[SCSI_MAX_CDBLEN]; ++}; ++ ++/* ++ * scsi lun serial number definition ++ */ ++#define SCSI_LUN_SN_LEN 32 ++struct scsi_lun_sn_s{ ++ u8 lun_sn[SCSI_LUN_SN_LEN]; ++}; ++ ++/* ++ * SCSI Direct Access Commands ++ */ ++enum { ++ SCSI_OP_TEST_UNIT_READY = 0x00, ++ SCSI_OP_REQUEST_SENSE = 0x03, ++ SCSI_OP_FORMAT_UNIT = 0x04, ++ SCSI_OP_READ6 = 0x08, ++ SCSI_OP_WRITE6 = 0x0A, ++ SCSI_OP_WRITE_FILEMARKS = 0x10, ++ SCSI_OP_INQUIRY = 0x12, ++ SCSI_OP_MODE_SELECT6 = 0x15, ++ SCSI_OP_RESERVE6 = 0x16, ++ SCSI_OP_RELEASE6 = 0x17, ++ SCSI_OP_MODE_SENSE6 = 0x1A, ++ SCSI_OP_START_STOP_UNIT = 0x1B, ++ SCSI_OP_SEND_DIAGNOSTIC = 0x1D, ++ SCSI_OP_READ_CAPACITY = 0x25, ++ SCSI_OP_READ10 = 0x28, ++ SCSI_OP_WRITE10 = 0x2A, ++ SCSI_OP_VERIFY10 = 0x2F, ++ SCSI_OP_READ_DEFECT_DATA = 0x37, ++ SCSI_OP_LOG_SELECT = 0x4C, ++ SCSI_OP_LOG_SENSE = 0x4D, ++ SCSI_OP_MODE_SELECT10 = 0x55, ++ SCSI_OP_RESERVE10 = 0x56, ++ SCSI_OP_RELEASE10 = 0x57, ++ SCSI_OP_MODE_SENSE10 = 0x5A, ++ SCSI_OP_PER_RESERVE_IN = 0x5E, ++ SCSI_OP_PER_RESERVE_OUR = 0x5E, ++ SCSI_OP_READ16 = 0x88, ++ SCSI_OP_WRITE16 = 0x8A, ++ SCSI_OP_VERIFY16 = 0x8F, ++ SCSI_OP_READ_CAPACITY16 = 0x9E, ++ SCSI_OP_REPORT_LUNS = 0xA0, ++ SCSI_OP_READ12 = 0xA8, ++ SCSI_OP_WRITE12 = 0xAA, ++ SCSI_OP_UNDEF = 0xFF, ++}; ++ ++/* ++ * SCSI START_STOP_UNIT command ++ */ ++struct scsi_start_stop_unit_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 reserved1:4; ++ u8 immed:1; ++#else ++ u8 immed:1; ++ u8 reserved1:4; ++ u8 lun:3; ++#endif ++ u8 reserved2; ++ u8 reserved3; ++#ifdef __BIGENDIAN ++ u8 power_conditions:4; ++ u8 reserved4:2; ++ u8 loEj:1; ++ u8 start:1; ++#else ++ u8 start:1; ++ u8 loEj:1; ++ u8 reserved4:2; ++ u8 power_conditions:4; ++#endif ++ u8 control; ++}; ++ ++/* ++ * SCSI SEND_DIAGNOSTIC command ++ */ ++struct scsi_send_diagnostic_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 self_test_code:3; ++ u8 pf:1; ++ u8 reserved1:1; ++ u8 self_test:1; ++ u8 dev_offl:1; ++ u8 unit_offl:1; ++#else ++ u8 unit_offl:1; ++ u8 dev_offl:1; ++ u8 self_test:1; ++ u8 reserved1:1; ++ u8 pf:1; ++ u8 self_test_code:3; ++#endif ++ u8 reserved2; ++ ++ u8 param_list_length[2]; /* MSB first */ ++ u8 control; ++ ++}; ++ ++/* ++ * SCSI READ10/WRITE10 commands ++ */ ++struct scsi_rw10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 dpo:1; /* Disable Page Out */ ++ u8 fua:1; /* Force Unit Access */ ++ u8 reserved1:2; ++ u8 rel_adr:1; /* relative address */ ++#else ++ u8 rel_adr:1; ++ u8 reserved1:2; ++ u8 fua:1; ++ u8 dpo:1; ++ u8 lun:3; ++#endif ++ u8 lba0; /* logical block address - MSB */ ++ u8 lba1; ++ u8 lba2; ++ u8 lba3; /* LSB */ ++ u8 reserved3; ++ u8 xfer_length0; /* transfer length in blocks - MSB */ ++ u8 xfer_length1; /* LSB */ ++ u8 control; ++}; ++ ++#define SCSI_CDB10_GET_LBA(cdb) \ ++ (((cdb)->lba0 << 24) | ((cdb)->lba1 << 16) | \ ++ ((cdb)->lba2 << 8) | (cdb)->lba3) ++ ++#define SCSI_CDB10_SET_LBA(cdb, lba) { \ ++ (cdb)->lba0 = lba >> 24; \ ++ (cdb)->lba1 = (lba >> 16) & 0xFF; \ ++ (cdb)->lba2 = (lba >> 8) & 0xFF; \ ++ (cdb)->lba3 = lba & 0xFF; \ ++} ++ ++#define SCSI_CDB10_GET_TL(cdb) \ ++ ((cdb)->xfer_length0 << 8 | (cdb)->xfer_length1) ++#define SCSI_CDB10_SET_TL(cdb, tl) { \ ++ (cdb)->xfer_length0 = tl >> 8; \ ++ (cdb)->xfer_length1 = tl & 0xFF; \ ++} ++ ++/* ++ * SCSI READ6/WRITE6 commands ++ */ ++struct scsi_rw6_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 lba0:5; /* MSb */ ++#else ++ u8 lba0:5; /* MSb */ ++ u8 lun:3; ++#endif ++ u8 lba1; ++ u8 lba2; /* LSB */ ++ u8 xfer_length; ++ u8 control; ++}; ++ ++#define SCSI_TAPE_CDB6_GET_TL(cdb) \ ++ (((cdb)->tl0 << 16) | ((cdb)->tl1 << 8) | (cdb)->tl2) ++ ++#define SCSI_TAPE_CDB6_SET_TL(cdb, tl) { \ ++ (cdb)->tl0 = tl >> 16; \ ++ (cdb)->tl1 = (tl >> 8) & 0xFF; \ ++ (cdb)->tl2 = tl & 0xFF; \ ++} ++ ++/* ++ * SCSI sequential (TAPE) wrtie command ++ */ ++struct scsi_tape_wr_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 rsvd:7; ++ u8 fixed:1; /* MSb */ ++#else ++ u8 fixed:1; /* MSb */ ++ u8 rsvd:7; ++#endif ++ u8 tl0; /* Msb */ ++ u8 tl1; ++ u8 tl2; /* Lsb */ ++ ++ u8 control; ++}; ++ ++#define SCSI_CDB6_GET_LBA(cdb) \ ++ (((cdb)->lba0 << 16) | ((cdb)->lba1 << 8) | (cdb)->lba2) ++ ++#define SCSI_CDB6_SET_LBA(cdb, lba) { \ ++ (cdb)->lba0 = lba >> 16; \ ++ (cdb)->lba1 = (lba >> 8) & 0xFF; \ ++ (cdb)->lba2 = lba & 0xFF; \ ++} ++ ++#define SCSI_CDB6_GET_TL(cdb) ((cdb)->xfer_length) ++#define SCSI_CDB6_SET_TL(cdb, tl) { \ ++ (cdb)->xfer_length = tl; \ ++} ++ ++/* ++ * SCSI sense data format ++ */ ++struct scsi_sense_s{ ++#ifdef __BIGENDIAN ++ u8 valid:1; ++ u8 rsp_code:7; ++#else ++ u8 rsp_code:7; ++ u8 valid:1; ++#endif ++ u8 seg_num; ++#ifdef __BIGENDIAN ++ u8 file_mark:1; ++ u8 eom:1; /* end of media */ ++ u8 ili:1; /* incorrect length indicator */ ++ u8 reserved:1; ++ u8 sense_key:4; ++#else ++ u8 sense_key:4; ++ u8 reserved:1; ++ u8 ili:1; /* incorrect length indicator */ ++ u8 eom:1; /* end of media */ ++ u8 file_mark:1; ++#endif ++ u8 information[4]; /* device-type or command specific info ++ */ ++ u8 add_sense_length; ++ /* additional sense length */ ++ u8 command_info[4];/* command specific information ++ */ ++ u8 asc; /* additional sense code */ ++ u8 ascq; /* additional sense code qualifier */ ++ u8 fru_code; /* field replaceable unit code */ ++#ifdef __BIGENDIAN ++ u8 sksv:1; /* sense key specific valid */ ++ u8 c_d:1; /* command/data bit */ ++ u8 res1:2; ++ u8 bpv:1; /* bit pointer valid */ ++ u8 bpointer:3; /* bit pointer */ ++#else ++ u8 bpointer:3; /* bit pointer */ ++ u8 bpv:1; /* bit pointer valid */ ++ u8 res1:2; ++ u8 c_d:1; /* command/data bit */ ++ u8 sksv:1; /* sense key specific valid */ ++#endif ++ u8 fpointer[2]; /* field pointer */ ++}; ++ ++#define SCSI_SENSE_CUR_ERR 0x70 ++#define SCSI_SENSE_DEF_ERR 0x71 ++ ++/* ++ * SCSI sense key values ++ */ ++#define SCSI_SK_NO_SENSE 0x0 ++#define SCSI_SK_REC_ERR 0x1 /* recovered error */ ++#define SCSI_SK_NOT_READY 0x2 ++#define SCSI_SK_MED_ERR 0x3 /* medium error */ ++#define SCSI_SK_HW_ERR 0x4 /* hardware error */ ++#define SCSI_SK_ILLEGAL_REQ 0x5 ++#define SCSI_SK_UNIT_ATT 0x6 /* unit attention */ ++#define SCSI_SK_DATA_PROTECT 0x7 ++#define SCSI_SK_BLANK_CHECK 0x8 ++#define SCSI_SK_VENDOR_SPEC 0x9 ++#define SCSI_SK_COPY_ABORTED 0xA ++#define SCSI_SK_ABORTED_CMND 0xB ++#define SCSI_SK_VOL_OVERFLOW 0xD ++#define SCSI_SK_MISCOMPARE 0xE ++ ++/* ++ * SCSI additional sense codes ++ */ ++#define SCSI_ASC_NO_ADD_SENSE 0x00 ++#define SCSI_ASC_LUN_NOT_READY 0x04 ++#define SCSI_ASC_LUN_COMMUNICATION 0x08 ++#define SCSI_ASC_WRITE_ERROR 0x0C ++#define SCSI_ASC_INVALID_CMND_CODE 0x20 ++#define SCSI_ASC_BAD_LBA 0x21 ++#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24 ++#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25 ++#define SCSI_ASC_LUN_WRITE_PROTECT 0x27 ++#define SCSI_ASC_POWERON_BDR 0x29 /* power on reset, bus reset, ++ * bus device reset ++ */ ++#define SCSI_ASC_PARAMS_CHANGED 0x2A ++#define SCSI_ASC_CMND_CLEARED_BY_A_I 0x2F ++#define SCSI_ASC_SAVING_PARAM_NOTSUPP 0x39 ++#define SCSI_ASC_TOCC 0x3F /* target operating condtions ++ * changed ++ */ ++#define SCSI_ASC_PARITY_ERROR 0x47 ++#define SCSI_ASC_CMND_PHASE_ERROR 0x4A ++#define SCSI_ASC_DATA_PHASE_ERROR 0x4B ++#define SCSI_ASC_VENDOR_SPEC 0x7F ++ ++/* ++ * SCSI additional sense code qualifiers ++ */ ++#define SCSI_ASCQ_CAUSE_NOT_REPORT 0x00 ++#define SCSI_ASCQ_BECOMING_READY 0x01 ++#define SCSI_ASCQ_INIT_CMD_REQ 0x02 ++#define SCSI_ASCQ_FORMAT_IN_PROGRESS 0x04 ++#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07 ++#define SCSI_ASCQ_SELF_TEST_IN_PROGRESS 0x09 ++#define SCSI_ASCQ_WR_UNEXP_UNSOL_DATA 0x0C ++#define SCSI_ASCQ_WR_NOTENG_UNSOL_DATA 0x0D ++ ++#define SCSI_ASCQ_LBA_OUT_OF_RANGE 0x00 ++#define SCSI_ASCQ_INVALID_ELEMENT_ADDR 0x01 ++ ++#define SCSI_ASCQ_LUN_WRITE_PROTECTED 0x00 ++#define SCSI_ASCQ_LUN_HW_WRITE_PROTECTED 0x01 ++#define SCSI_ASCQ_LUN_SW_WRITE_PROTECTED 0x02 ++ ++#define SCSI_ASCQ_POR 0x01 /* power on reset */ ++#define SCSI_ASCQ_SBR 0x02 /* scsi bus reset */ ++#define SCSI_ASCQ_BDR 0x03 /* bus device reset */ ++#define SCSI_ASCQ_DIR 0x04 /* device internal reset */ ++ ++#define SCSI_ASCQ_MODE_PARAMS_CHANGED 0x01 ++#define SCSI_ASCQ_LOG_PARAMS_CHANGED 0x02 ++#define SCSI_ASCQ_RESERVATIONS_PREEMPTED 0x03 ++#define SCSI_ASCQ_RESERVATIONS_RELEASED 0x04 ++#define SCSI_ASCQ_REGISTRATIONS_PREEMPTED 0x05 ++ ++#define SCSI_ASCQ_MICROCODE_CHANGED 0x01 ++#define SCSI_ASCQ_CHANGED_OPER_COND 0x02 ++#define SCSI_ASCQ_INQ_CHANGED 0x03 /* inquiry data changed */ ++#define SCSI_ASCQ_DI_CHANGED 0x05 /* device id changed */ ++#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */ ++ ++#define SCSI_ASCQ_DP_CRC_ERR 0x01 /* data phase crc error */ ++#define SCSI_ASCQ_DP_SCSI_PARITY_ERR 0x02 /* data phase scsi parity error ++ */ ++#define SCSI_ASCQ_IU_CRC_ERR 0x03 /* information unit crc error */ ++#define SCSI_ASCQ_PROTO_SERV_CRC_ERR 0x05 ++ ++#define SCSI_ASCQ_LUN_TIME_OUT 0x01 ++ ++/* ------------------------------------------------------------ ++ * SCSI INQUIRY ++ * ------------------------------------------------------------*/ ++ ++struct scsi_inquiry_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 reserved1:3; ++ u8 cmd_dt:1; ++ u8 evpd:1; ++#else ++ u8 evpd:1; ++ u8 cmd_dt:1; ++ u8 reserved1:3; ++ u8 lun:3; ++#endif ++ u8 page_code; ++ u8 reserved2; ++ u8 alloc_length; ++ u8 control; ++}; ++ ++struct scsi_inquiry_vendor_s{ ++ u8 vendor_id[8]; ++}; ++ ++struct scsi_inquiry_prodid_s{ ++ u8 product_id[16]; ++}; ++ ++struct scsi_inquiry_prodrev_s{ ++ u8 product_rev[4]; ++}; ++ ++struct scsi_inquiry_data_s{ ++#ifdef __BIGENDIAN ++ u8 peripheral_qual:3; /* peripheral qualifier */ ++ u8 device_type:5; /* peripheral device type */ ++ ++ u8 rmb:1; /* removable medium bit */ ++ u8 device_type_mod:7; /* device type modifier */ ++ ++ u8 version; ++ ++ u8 aenc:1; /* async event notification capability ++ */ ++ u8 trm_iop:1; /* terminate I/O process */ ++ u8 norm_aca:1; /* normal ACA supported */ ++ u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */ ++ u8 rsp_data_format:4; ++ ++ u8 additional_len; ++ u8 sccs:1; ++ u8 reserved1:7; ++ ++ u8 reserved2:1; ++ u8 enc_serv:1; /* enclosure service component */ ++ u8 reserved3:1; ++ u8 multi_port:1; /* multi-port device */ ++ u8 m_chngr:1; /* device in medium transport element */ ++ u8 ack_req_q:1; /* SIP specific bit */ ++ u8 addr32:1; /* SIP specific bit */ ++ u8 addr16:1; /* SIP specific bit */ ++ ++ u8 rel_adr:1; /* relative address */ ++ u8 w_bus32:1; ++ u8 w_bus16:1; ++ u8 synchronous:1; ++ u8 linked_commands:1; ++ u8 trans_dis:1; ++ u8 cmd_queue:1; /* command queueing supported */ ++ u8 soft_reset:1; /* soft reset alternative (VS) */ ++#else ++ u8 device_type:5; /* peripheral device type */ ++ u8 peripheral_qual:3; ++ /* peripheral qualifier */ ++ ++ u8 device_type_mod:7; ++ /* device type modifier */ ++ u8 rmb:1; /* removable medium bit */ ++ ++ u8 version; ++ ++ u8 rsp_data_format:4; ++ u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */ ++ u8 norm_aca:1; /* normal ACA supported */ ++ u8 terminate_iop:1;/* terminate I/O process */ ++ u8 aenc:1; /* async event notification capability ++ */ ++ ++ u8 additional_len; ++ u8 reserved1:7; ++ u8 sccs:1; ++ ++ u8 addr16:1; /* SIP specific bit */ ++ u8 addr32:1; /* SIP specific bit */ ++ u8 ack_req_q:1; /* SIP specific bit */ ++ u8 m_chngr:1; /* device in medium transport element */ ++ u8 multi_port:1; /* multi-port device */ ++ u8 reserved3:1; /* TBD - Vendor Specific */ ++ u8 enc_serv:1; /* enclosure service component */ ++ u8 reserved2:1; ++ ++ u8 soft_seset:1; /* soft reset alternative (VS) */ ++ u8 cmd_queue:1; /* command queueing supported */ ++ u8 trans_dis:1; ++ u8 linked_commands:1; ++ u8 synchronous:1; ++ u8 w_bus16:1; ++ u8 w_bus32:1; ++ u8 rel_adr:1; /* relative address */ ++#endif ++ struct scsi_inquiry_vendor_s vendor_id; ++ struct scsi_inquiry_prodid_s product_id; ++ struct scsi_inquiry_prodrev_s product_rev; ++ u8 vendor_specific[20]; ++ u8 reserved4[40]; ++}; ++ ++/* ++ * inquiry.peripheral_qual field values ++ */ ++#define SCSI_DEVQUAL_DEFAULT 0 ++#define SCSI_DEVQUAL_NOT_CONNECTED 1 ++#define SCSI_DEVQUAL_NOT_SUPPORTED 3 ++ ++/* ++ * inquiry.device_type field values ++ */ ++#define SCSI_DEVICE_DIRECT_ACCESS 0x00 ++#define SCSI_DEVICE_SEQ_ACCESS 0x01 ++#define SCSI_DEVICE_ARRAY_CONTROLLER 0x0C ++#define SCSI_DEVICE_UNKNOWN 0x1F ++ ++/* ++ * inquiry.version ++ */ ++#define SCSI_VERSION_ANSI_X3131 2 /* ANSI X3.131 SCSI-2 */ ++#define SCSI_VERSION_SPC 3 /* SPC (SCSI-3), ANSI X3.301:1997 */ ++#define SCSI_VERSION_SPC_2 4 /* SPC-2 */ ++ ++/* ++ * response data format ++ */ ++#define SCSI_RSP_DATA_FORMAT 2 /* SCSI-2 & SPC */ ++ ++/* ++ * SCSI inquiry page codes ++ */ ++#define SCSI_INQ_PAGE_VPD_PAGES 0x00 /* supported vpd pages */ ++#define SCSI_INQ_PAGE_USN_PAGE 0x80 /* unit serial number page */ ++#define SCSI_INQ_PAGE_DEV_IDENT 0x83 /* device indentification page ++ */ ++#define SCSI_INQ_PAGES_MAX 3 ++ ++/* ++ * supported vital product data pages ++ */ ++struct scsi_inq_page_vpd_pages_s{ ++#ifdef __BIGENDIAN ++ u8 peripheral_qual:3; ++ u8 device_type:5; ++#else ++ u8 device_type:5; ++ u8 peripheral_qual:3; ++#endif ++ u8 page_code; ++ u8 reserved; ++ u8 page_length; ++ u8 pages[SCSI_INQ_PAGES_MAX]; ++}; ++ ++/* ++ * Unit serial number page ++ */ ++#define SCSI_INQ_USN_LEN 32 ++ ++struct scsi_inq_usn_s{ ++ char usn[SCSI_INQ_USN_LEN]; ++}; ++ ++struct scsi_inq_page_usn_s{ ++#ifdef __BIGENDIAN ++ u8 peripheral_qual:3; ++ u8 device_type:5; ++#else ++ u8 device_type:5; ++ u8 peripheral_qual:3; ++#endif ++ u8 page_code; ++ u8 reserved1; ++ u8 page_length; ++ struct scsi_inq_usn_s usn; ++}; ++ ++enum { ++ SCSI_INQ_DIP_CODE_BINARY = 1, /* identifier has binary value */ ++ SCSI_INQ_DIP_CODE_ASCII = 2, /* identifier has ascii value */ ++}; ++ ++enum { ++ SCSI_INQ_DIP_ASSOC_LUN = 0, /* id is associated with device */ ++ SCSI_INQ_DIP_ASSOC_PORT = 1, /* id is associated with port that ++ * received the request ++ */ ++}; ++ ++enum { ++ SCSI_INQ_ID_TYPE_VENDOR = 1, ++ SCSI_INQ_ID_TYPE_IEEE = 2, ++ SCSI_INQ_ID_TYPE_FC_FS = 3, ++ SCSI_INQ_ID_TYPE_OTHER = 4, ++}; ++ ++struct scsi_inq_dip_desc_s{ ++#ifdef __BIGENDIAN ++ u8 res0:4; ++ u8 code_set:4; ++ u8 res1:2; ++ u8 association:2; ++ u8 id_type:4; ++#else ++ u8 code_set:4; ++ u8 res0:4; ++ u8 id_type:4; ++ u8 association:2; ++ u8 res1:2; ++#endif ++ u8 res2; ++ u8 id_len; ++ struct scsi_lun_sn_s id; ++}; ++ ++/* ++ * Device indentification page ++ */ ++struct scsi_inq_page_dev_ident_s{ ++#ifdef __BIGENDIAN ++ u8 peripheral_qual:3; ++ u8 device_type:5; ++#else ++ u8 device_type:5; ++ u8 peripheral_qual:3; ++#endif ++ u8 page_code; ++ u8 reserved1; ++ u8 page_length; ++ struct scsi_inq_dip_desc_s desc; ++}; ++ ++/* ------------------------------------------------------------ ++ * READ CAPACITY ++ * ------------------------------------------------------------ ++ */ ++ ++struct scsi_read_capacity_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 reserved1:4; ++ u8 rel_adr:1; ++#else ++ u8 rel_adr:1; ++ u8 reserved1:4; ++ u8 lun:3; ++#endif ++ u8 lba0; /* MSB */ ++ u8 lba1; ++ u8 lba2; ++ u8 lba3; /* LSB */ ++ u8 reserved2; ++ u8 reserved3; ++#ifdef __BIGENDIAN ++ u8 reserved4:7; ++ u8 pmi:1; /* partial medium indicator */ ++#else ++ u8 pmi:1; /* partial medium indicator */ ++ u8 reserved4:7; ++#endif ++ u8 control; ++}; ++ ++struct scsi_read_capacity_data_s{ ++ u32 max_lba; /* maximum LBA available */ ++ u32 block_length; /* in bytes */ ++}; ++ ++struct scsi_read_capacity16_data_s{ ++ u64 lba; /* maximum LBA available */ ++ u32 block_length; /* in bytes */ ++#ifdef __BIGENDIAN ++ u8 reserved1:4, ++ p_type:3, ++ prot_en:1; ++ u8 reserved2:4, ++ lb_pbe:4; /* logical blocks per physical block ++ * exponent */ ++ u16 reserved3:2, ++ lba_align:14; /* lowest aligned logical block ++ * address */ ++#else ++ u16 lba_align:14, /* lowest aligned logical block ++ * address */ ++ reserved3:2; ++ u8 lb_pbe:4, /* logical blocks per physical block ++ * exponent */ ++ reserved2:4; ++ u8 prot_en:1, ++ p_type:3, ++ reserved1:4; ++#endif ++ u64 reserved4; ++ u64 reserved5; ++}; ++ ++/* ------------------------------------------------------------ ++ * REPORT LUNS command ++ * ------------------------------------------------------------ ++ */ ++ ++struct scsi_report_luns_s{ ++ u8 opcode; /* A0h - REPORT LUNS opCode */ ++ u8 reserved1[5]; ++ u8 alloc_length[4];/* allocation length MSB first */ ++ u8 reserved2; ++ u8 control; ++}; ++ ++#define SCSI_REPORT_LUN_ALLOC_LENGTH(rl) \ ++ ((rl->alloc_length[0] << 24) | (rl->alloc_length[1] << 16) | \ ++ (rl->alloc_length[2] << 8) | (rl->alloc_length[3])) ++ ++#define SCSI_REPORT_LUNS_SET_ALLOCLEN(rl, alloc_len) { \ ++ (rl)->alloc_length[0] = (alloc_len) >> 24; \ ++ (rl)->alloc_length[1] = ((alloc_len) >> 16) & 0xFF; \ ++ (rl)->alloc_length[2] = ((alloc_len) >> 8) & 0xFF; \ ++ (rl)->alloc_length[3] = (alloc_len) & 0xFF; \ ++} ++ ++struct scsi_report_luns_data_s{ ++ u32 lun_list_length; /* length of LUN list length */ ++ u32 reserved; ++ lun_t lun[1]; /* first LUN in lun list */ ++}; ++ ++/* ------------------------------------------------------------- ++ * SCSI mode parameters ++ * ----------------------------------------------------------- ++ */ ++enum { ++ SCSI_DA_MEDIUM_DEF = 0, /* direct access default medium type */ ++ SCSI_DA_MEDIUM_SS = 1, /* direct access single sided */ ++ SCSI_DA_MEDIUM_DS = 2, /* direct access double sided */ ++}; ++ ++/* ++ * SCSI Mode Select(6) cdb ++ */ ++struct scsi_mode_select6_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 pf:1; /* page format */ ++ u8 reserved2:3; ++ u8 sp:1; /* save pages if set to 1 */ ++#else ++ u8 sp:1; /* save pages if set to 1 */ ++ u8 reserved2:3; ++ u8 pf:1; /* page format */ ++ u8 reserved1:3; ++#endif ++ u8 reserved3[2]; ++ u8 alloc_len; ++ u8 control; ++}; ++ ++/* ++ * SCSI Mode Select(10) cdb ++ */ ++struct scsi_mode_select10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 pf:1; /* page format */ ++ u8 reserved2:3; ++ u8 sp:1; /* save pages if set to 1 */ ++#else ++ u8 sp:1; /* save pages if set to 1 */ ++ u8 reserved2:3; ++ u8 pf:1; /* page format */ ++ u8 reserved1:3; ++#endif ++ u8 reserved3[5]; ++ u8 alloc_len_msb; ++ u8 alloc_len_lsb; ++ u8 control; ++}; ++ ++/* ++ * SCSI Mode Sense(6) cdb ++ */ ++struct scsi_mode_sense6_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:4; ++ u8 dbd:1; /* disable block discriptors if set to 1 */ ++ u8 reserved2:3; ++ ++ u8 pc:2; /* page control */ ++ u8 page_code:6; ++#else ++ u8 reserved2:3; ++ u8 dbd:1; /* disable block descriptors if set to 1 */ ++ u8 reserved1:4; ++ ++ u8 page_code:6; ++ u8 pc:2; /* page control */ ++#endif ++ u8 reserved3; ++ u8 alloc_len; ++ u8 control; ++}; ++ ++/* ++ * SCSI Mode Sense(10) cdb ++ */ ++struct scsi_mode_sense10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 LLBAA:1; /* long LBA accepted if set to 1 */ ++ u8 dbd:1; /* disable block descriptors if set ++ * to 1 ++ */ ++ u8 reserved2:3; ++ ++ u8 pc:2; /* page control */ ++ u8 page_code:6; ++#else ++ u8 reserved2:3; ++ u8 dbd:1; /* disable block descriptors if set to ++ * 1 ++ */ ++ u8 LLBAA:1; /* long LBA accepted if set to 1 */ ++ u8 reserved1:3; ++ ++ u8 page_code:6; ++ u8 pc:2; /* page control */ ++#endif ++ u8 reserved3[4]; ++ u8 alloc_len_msb; ++ u8 alloc_len_lsb; ++ u8 control; ++}; ++ ++#define SCSI_CDB10_GET_AL(cdb) \ ++ ((cdb)->alloc_len_msb << 8 | (cdb)->alloc_len_lsb) ++ ++#define SCSI_CDB10_SET_AL(cdb, al) { \ ++ (cdb)->alloc_len_msb = al >> 8; \ ++ (cdb)->alloc_len_lsb = al & 0xFF; \ ++} ++ ++#define SCSI_CDB6_GET_AL(cdb) ((cdb)->alloc_len) ++ ++#define SCSI_CDB6_SET_AL(cdb, al) { \ ++ (cdb)->alloc_len = al; \ ++} ++ ++/* ++ * page control field values ++ */ ++#define SCSI_PC_CURRENT_VALUES 0x0 ++#define SCSI_PC_CHANGEABLE_VALUES 0x1 ++#define SCSI_PC_DEFAULT_VALUES 0x2 ++#define SCSI_PC_SAVED_VALUES 0x3 ++ ++/* ++ * SCSI mode page codes ++ */ ++#define SCSI_MP_VENDOR_SPEC 0x00 ++#define SCSI_MP_DISC_RECN 0x02 /* disconnect-reconnect page */ ++#define SCSI_MP_FORMAT_DEVICE 0x03 ++#define SCSI_MP_RDG 0x04 /* rigid disk geometry page */ ++#define SCSI_MP_FDP 0x05 /* flexible disk page */ ++#define SCSI_MP_CACHING 0x08 /* caching page */ ++#define SCSI_MP_CONTROL 0x0A /* control mode page */ ++#define SCSI_MP_MED_TYPES_SUP 0x0B /* medium types supported page */ ++#define SCSI_MP_INFO_EXCP_CNTL 0x1C /* informational exception control */ ++#define SCSI_MP_ALL 0x3F /* return all pages - mode sense only */ ++ ++/* ++ * mode parameter header ++ */ ++struct scsi_mode_param_header6_s{ ++ u8 mode_datalen; ++ u8 medium_type; ++ ++ /* ++ * device specific parameters expanded for direct access devices ++ */ ++#ifdef __BIGENDIAN ++ u32 wp:1; /* write protected */ ++ u32 reserved1:2; ++ u32 dpofua:1; /* disable page out + force unit access ++ */ ++ u32 reserved2:4; ++#else ++ u32 reserved2:4; ++ u32 dpofua:1; /* disable page out + force unit access ++ */ ++ u32 reserved1:2; ++ u32 wp:1; /* write protected */ ++#endif ++ ++ u8 block_desclen; ++}; ++ ++struct scsi_mode_param_header10_s{ ++ u32 mode_datalen:16; ++ u32 medium_type:8; ++ ++ /* ++ * device specific parameters expanded for direct access devices ++ */ ++#ifdef __BIGENDIAN ++ u32 wp:1; /* write protected */ ++ u32 reserved1:2; ++ u32 dpofua:1; /* disable page out + force unit access ++ */ ++ u32 reserved2:4; ++#else ++ u32 reserved2:4; ++ u32 dpofua:1; /* disable page out + force unit access ++ */ ++ u32 reserved1:2; ++ u32 wp:1; /* write protected */ ++#endif ++ ++#ifdef __BIGENDIAN ++ u32 reserved3:7; ++ u32 longlba:1; ++#else ++ u32 longlba:1; ++ u32 reserved3:7; ++#endif ++ u32 reserved4:8; ++ u32 block_desclen:16; ++}; ++ ++/* ++ * mode parameter block descriptor ++ */ ++struct scsi_mode_param_desc_s{ ++ u32 nblks; ++ u32 density_code:8; ++ u32 block_length:24; ++}; ++ ++/* ++ * Disconnect-reconnect mode page format ++ */ ++struct scsi_mp_disc_recn_s{ ++#ifdef __BIGENDIAN ++ u8 ps:1; ++ u8 reserved1:1; ++ u8 page_code:6; ++#else ++ u8 page_code:6; ++ u8 reserved1:1; ++ u8 ps:1; ++#endif ++ u8 page_len; ++ u8 buf_full_ratio; ++ u8 buf_empty_ratio; ++ ++ u8 bil_msb; /* bus inactivity limit -MSB */ ++ u8 bil_lsb; /* bus inactivity limit -LSB */ ++ ++ u8 dtl_msb; /* disconnect time limit - MSB */ ++ u8 dtl_lsb; /* disconnect time limit - LSB */ ++ ++ u8 ctl_msb; /* connect time limit - MSB */ ++ u8 ctl_lsb; /* connect time limit - LSB */ ++ ++ u8 max_burst_len_msb; ++ u8 max_burst_len_lsb; ++#ifdef __BIGENDIAN ++ u8 emdp:1; /* enable modify data pointers */ ++ u8 fa:3; /* fair arbitration */ ++ u8 dimm:1; /* disconnect immediate */ ++ u8 dtdc:3; /* data transfer disconnect control */ ++#else ++ u8 dtdc:3; /* data transfer disconnect control */ ++ u8 dimm:1; /* disconnect immediate */ ++ u8 fa:3; /* fair arbitration */ ++ u8 emdp:1; /* enable modify data pointers */ ++#endif ++ ++ u8 reserved3; ++ ++ u8 first_burst_len_msb; ++ u8 first_burst_len_lsb; ++}; ++ ++/* ++ * SCSI format device mode page ++ */ ++struct scsi_mp_format_device_s{ ++#ifdef __BIGENDIAN ++ u32 ps:1; ++ u32 reserved1:1; ++ u32 page_code:6; ++#else ++ u32 page_code:6; ++ u32 reserved1:1; ++ u32 ps:1; ++#endif ++ u32 page_len:8; ++ u32 tracks_per_zone:16; ++ ++ u32 a_sec_per_zone:16; ++ u32 a_tracks_per_zone:16; ++ ++ u32 a_tracks_per_lun:16; /* alternate tracks/lun-MSB */ ++ u32 sec_per_track:16; /* sectors/track-MSB */ ++ ++ u32 bytes_per_sector:16; ++ u32 interleave:16; ++ ++ u32 tsf:16; /* track skew factor-MSB */ ++ u32 csf:16; /* cylinder skew factor-MSB */ ++ ++#ifdef __BIGENDIAN ++ u32 ssec:1; /* soft sector formatting */ ++ u32 hsec:1; /* hard sector formatting */ ++ u32 rmb:1; /* removable media */ ++ u32 surf:1; /* surface */ ++ u32 reserved2:4; ++#else ++ u32 reserved2:4; ++ u32 surf:1; /* surface */ ++ u32 rmb:1; /* removable media */ ++ u32 hsec:1; /* hard sector formatting */ ++ u32 ssec:1; /* soft sector formatting */ ++#endif ++ u32 reserved3:24; ++}; ++ ++/* ++ * SCSI rigid disk device geometry page ++ */ ++struct scsi_mp_rigid_device_geometry_s{ ++#ifdef __BIGENDIAN ++ u32 ps:1; ++ u32 reserved1:1; ++ u32 page_code:6; ++#else ++ u32 page_code:6; ++ u32 reserved1:1; ++ u32 ps:1; ++#endif ++ u32 page_len:8; ++ u32 num_cylinders0:8; ++ u32 num_cylinders1:8; ++ ++ u32 num_cylinders2:8; ++ u32 num_heads:8; ++ u32 scwp0:8; ++ u32 scwp1:8; ++ ++ u32 scwp2:8; ++ u32 scrwc0:8; ++ u32 scrwc1:8; ++ u32 scrwc2:8; ++ ++ u32 dsr:16; ++ u32 lscyl0:8; ++ u32 lscyl1:8; ++ ++ u32 lscyl2:8; ++#ifdef __BIGENDIAN ++ u32 reserved2:6; ++ u32 rpl:2; /* rotational position locking */ ++#else ++ u32 rpl:2; /* rotational position locking */ ++ u32 reserved2:6; ++#endif ++ u32 rot_off:8; ++ u32 reserved3:8; ++ ++ u32 med_rot_rate:16; ++ u32 reserved4:16; ++}; ++ ++/* ++ * SCSI caching mode page ++ */ ++struct scsi_mp_caching_s{ ++#ifdef __BIGENDIAN ++ u8 ps:1; ++ u8 res1:1; ++ u8 page_code:6; ++#else ++ u8 page_code:6; ++ u8 res1:1; ++ u8 ps:1; ++#endif ++ u8 page_len; ++#ifdef __BIGENDIAN ++ u8 ic:1; /* initiator control */ ++ u8 abpf:1; /* abort pre-fetch */ ++ u8 cap:1; /* caching analysis permitted */ ++ u8 disc:1; /* discontinuity */ ++ u8 size:1; /* size enable */ ++ u8 wce:1; /* write cache enable */ ++ u8 mf:1; /* multiplication factor */ ++ u8 rcd:1; /* read cache disable */ ++ ++ u8 drrp:4; /* demand read retention priority */ ++ u8 wrp:4; /* write retention priority */ ++#else ++ u8 rcd:1; /* read cache disable */ ++ u8 mf:1; /* multiplication factor */ ++ u8 wce:1; /* write cache enable */ ++ u8 size:1; /* size enable */ ++ u8 disc:1; /* discontinuity */ ++ u8 cap:1; /* caching analysis permitted */ ++ u8 abpf:1; /* abort pre-fetch */ ++ u8 ic:1; /* initiator control */ ++ ++ u8 wrp:4; /* write retention priority */ ++ u8 drrp:4; /* demand read retention priority */ ++#endif ++ u8 dptl[2];/* disable pre-fetch transfer length */ ++ u8 min_prefetch[2]; ++ u8 max_prefetch[2]; ++ u8 max_prefetch_limit[2]; ++#ifdef __BIGENDIAN ++ u8 fsw:1; /* force sequential write */ ++ u8 lbcss:1;/* logical block cache segment size */ ++ u8 dra:1; /* disable read ahead */ ++ u8 vs:2; /* vendor specific */ ++ u8 res2:3; ++#else ++ u8 res2:3; ++ u8 vs:2; /* vendor specific */ ++ u8 dra:1; /* disable read ahead */ ++ u8 lbcss:1;/* logical block cache segment size */ ++ u8 fsw:1; /* force sequential write */ ++#endif ++ u8 num_cache_segs; ++ ++ u8 cache_seg_size[2]; ++ u8 res3; ++ u8 non_cache_seg_size[3]; ++}; ++ ++/* ++ * SCSI control mode page ++ */ ++struct scsi_mp_control_page_s{ ++#ifdef __BIGENDIAN ++u8 ps:1; ++u8 reserved1:1; ++u8 page_code:6; ++#else ++u8 page_code:6; ++u8 reserved1:1; ++u8 ps:1; ++#endif ++ u8 page_len; ++#ifdef __BIGENDIAN ++ u8 tst:3; /* task set type */ ++ u8 reserved3:3; ++ u8 gltsd:1; /* global logging target save disable */ ++ u8 rlec:1; /* report log exception condition */ ++ ++ u8 qalgo_mod:4; /* queue alogorithm modifier */ ++ u8 reserved4:1; ++ u8 qerr:2; /* queue error management */ ++ u8 dque:1; /* disable queuing */ ++ ++ u8 reserved5:1; ++ u8 rac:1; /* report a check */ ++ u8 reserved6:2; ++ u8 swp:1; /* software write protect */ ++ u8 raerp:1; /* ready AER permission */ ++ u8 uaaerp:1; /* unit attenstion AER permission */ ++ u8 eaerp:1; /* error AER permission */ ++ ++ u8 reserved7:5; ++ u8 autoload_mod:3; ++#else ++ u8 rlec:1; /* report log exception condition */ ++ u8 gltsd:1; /* global logging target save disable */ ++ u8 reserved3:3; ++ u8 tst:3; /* task set type */ ++ ++ u8 dque:1; /* disable queuing */ ++ u8 qerr:2; /* queue error management */ ++ u8 reserved4:1; ++ u8 qalgo_mod:4; /* queue alogorithm modifier */ ++ ++ u8 eaerp:1; /* error AER permission */ ++ u8 uaaerp:1; /* unit attenstion AER permission */ ++ u8 raerp:1; /* ready AER permission */ ++ u8 swp:1; /* software write protect */ ++ u8 reserved6:2; ++ u8 rac:1; /* report a check */ ++ u8 reserved5:1; ++ ++ u8 autoload_mod:3; ++ u8 reserved7:5; ++#endif ++ u8 rahp_msb; /* ready AER holdoff period - MSB */ ++ u8 rahp_lsb; /* ready AER holdoff period - LSB */ ++ ++ u8 busy_timeout_period_msb; ++ u8 busy_timeout_period_lsb; ++ ++ u8 ext_selftest_compl_time_msb; ++ u8 ext_selftest_compl_time_lsb; ++}; ++ ++/* ++ * SCSI medium types supported mode page ++ */ ++struct scsi_mp_medium_types_sup_s{ ++#ifdef __BIGENDIAN ++ u8 ps:1; ++ u8 reserved1:1; ++ u8 page_code:6; ++#else ++ u8 page_code:6; ++ u8 reserved1:1; ++ u8 ps:1; ++#endif ++ u8 page_len; ++ ++ u8 reserved3[2]; ++ u8 med_type1_sup; /* medium type one supported */ ++ u8 med_type2_sup; /* medium type two supported */ ++ u8 med_type3_sup; /* medium type three supported */ ++ u8 med_type4_sup; /* medium type four supported */ ++}; ++ ++/* ++ * SCSI informational exception control mode page ++ */ ++struct scsi_mp_info_excpt_cntl_s{ ++#ifdef __BIGENDIAN ++ u8 ps:1; ++ u8 reserved1:1; ++ u8 page_code:6; ++#else ++ u8 page_code:6; ++ u8 reserved1:1; ++ u8 ps:1; ++#endif ++ u8 page_len; ++#ifdef __BIGENDIAN ++ u8 perf:1; /* performance */ ++ u8 reserved3:1; ++ u8 ebf:1; /* enable background fucntion */ ++ u8 ewasc:1; /* enable warning */ ++ u8 dexcpt:1; /* disable exception control */ ++ u8 test:1; /* enable test device failure ++ * notification ++ */ ++ u8 reserved4:1; ++ u8 log_error:1; ++ ++ u8 reserved5:4; ++ u8 mrie:4; /* method of reporting info ++ * exceptions ++ */ ++#else ++ u8 log_error:1; ++ u8 reserved4:1; ++ u8 test:1; /* enable test device failure ++ * notification ++ */ ++ u8 dexcpt:1; /* disable exception control */ ++ u8 ewasc:1; /* enable warning */ ++ u8 ebf:1; /* enable background fucntion */ ++ u8 reserved3:1; ++ u8 perf:1; /* performance */ ++ ++ u8 mrie:4; /* method of reporting info ++ * exceptions ++ */ ++ u8 reserved5:4; ++#endif ++ u8 interval_timer_msb; ++ u8 interval_timer_lsb; ++ ++ u8 report_count_msb; ++ u8 report_count_lsb; ++}; ++ ++/* ++ * Methods of reporting informational exceptions ++ */ ++#define SCSI_MP_IEC_NO_REPORT 0x0 /* no reporting of exceptions */ ++#define SCSI_MP_IEC_AER 0x1 /* async event reporting */ ++#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attenstion */ ++#define SCSI_MO_IEC_COND_REC_ERR 0x3 /* conditionally generate recovered ++ * error ++ */ ++#define SCSI_MP_IEC_UNCOND_REC_ERR 0x4 /* unconditionally generate recovered ++ * error ++ */ ++#define SCSI_MP_IEC_NO_SENSE 0x5 /* generate no sense */ ++#define SCSI_MP_IEC_ON_REQUEST 0x6 /* only report exceptions on request */ ++ ++/* ++ * SCSI flexible disk page ++ */ ++struct scsi_mp_flexible_disk_s{ ++#ifdef __BIGENDIAN ++ u8 ps:1; ++ u8 reserved1:1; ++ u8 page_code:6; ++#else ++ u8 page_code:6; ++ u8 reserved1:1; ++ u8 ps:1; ++#endif ++ u8 page_len; ++ ++ u8 transfer_rate_msb; ++ u8 transfer_rate_lsb; ++ ++ u8 num_heads; ++ u8 num_sectors; ++ ++ u8 bytes_per_sector_msb; ++ u8 bytes_per_sector_lsb; ++ ++ u8 num_cylinders_msb; ++ u8 num_cylinders_lsb; ++ ++ u8 sc_wpc_msb; /* starting cylinder-write ++ * precompensation msb ++ */ ++ u8 sc_wpc_lsb; /* starting cylinder-write ++ * precompensation lsb ++ */ ++ u8 sc_rwc_msb; /* starting cylinder-reduced write ++ * current msb ++ */ ++ u8 sc_rwc_lsb; /* starting cylinder-reduced write ++ * current lsb ++ */ ++ ++ u8 dev_step_rate_msb; ++ u8 dev_step_rate_lsb; ++ ++ u8 dev_step_pulse_width; ++ ++ u8 head_sd_msb; /* head settle delay msb */ ++ u8 head_sd_lsb; /* head settle delay lsb */ ++ ++ u8 motor_on_delay; ++ u8 motor_off_delay; ++#ifdef __BIGENDIAN ++ u8 trdy:1; /* true ready bit */ ++ u8 ssn:1; /* start sector number bit */ ++ u8 mo:1; /* motor on bit */ ++ u8 reserved3:5; ++ ++ u8 reserved4:4; ++ u8 spc:4; /* step pulse per cylinder */ ++#else ++ u8 reserved3:5; ++ u8 mo:1; /* motor on bit */ ++ u8 ssn:1; /* start sector number bit */ ++ u8 trdy:1; /* true ready bit */ ++ ++ u8 spc:4; /* step pulse per cylinder */ ++ u8 reserved4:4; ++#endif ++ u8 write_comp; ++ u8 head_load_delay; ++ u8 head_unload_delay; ++#ifdef __BIGENDIAN ++ u8 pin34:4; /* pin34 usage */ ++ u8 pin2:4; /* pin2 usage */ ++ ++ u8 pin4:4; /* pin4 usage */ ++ u8 pin1:4; /* pin1 usage */ ++#else ++ u8 pin2:4; /* pin2 usage */ ++ u8 pin34:4; /* pin34 usage */ ++ ++ u8 pin1:4; /* pin1 usage */ ++ u8 pin4:4; /* pin4 usage */ ++#endif ++ u8 med_rot_rate_msb; ++ u8 med_rot_rate_lsb; ++ ++ u8 reserved5[2]; ++}; ++ ++struct scsi_mode_page_format_data6_s{ ++ struct scsi_mode_param_header6_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_format_device_s format; /* format device data */ ++}; ++ ++struct scsi_mode_page_format_data10_s{ ++ struct scsi_mode_param_header10_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_format_device_s format; /* format device data */ ++}; ++ ++struct scsi_mode_page_rdg_data6_s{ ++ struct scsi_mode_param_header6_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_rigid_device_geometry_s rdg; ++ /* rigid geometry data */ ++}; ++ ++struct scsi_mode_page_rdg_data10_s{ ++ struct scsi_mode_param_header10_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_rigid_device_geometry_s rdg; ++ /* rigid geometry data */ ++}; ++ ++struct scsi_mode_page_cache6_s{ ++ struct scsi_mode_param_header6_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_caching_s cache; /* cache page data */ ++}; ++ ++struct scsi_mode_page_cache10_s{ ++ struct scsi_mode_param_header10_s mph; /* mode page header */ ++ struct scsi_mode_param_desc_s desc; /* block descriptor */ ++ struct scsi_mp_caching_s cache; /* cache page data */ ++}; ++ ++/* -------------------------------------------------------------- ++ * Format Unit command ++ * ------------------------------------------------------------ ++ */ ++ ++/* ++ * Format Unit CDB ++ */ ++struct scsi_format_unit_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 res1:3; ++ u8 fmtdata:1; /* if set, data out phase has format ++ * data ++ */ ++ u8 cmplst:1; /* if set, defect list is complete */ ++ u8 def_list:3; /* format of defect descriptor is ++ * fmtdata =1 ++ */ ++#else ++ u8 def_list:3; /* format of defect descriptor is ++ * fmtdata = 1 ++ */ ++ u8 cmplst:1; /* if set, defect list is complete */ ++ u8 fmtdata:1; /* if set, data out phase has format ++ * data ++ */ ++ u8 res1:3; ++#endif ++ u8 interleave_msb; ++ u8 interleave_lsb; ++ u8 vendor_spec; ++ u8 control; ++}; ++ ++/* ++ * h ++ */ ++struct scsi_reserve6_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved:3; ++ u8 obsolete:4; ++ u8 extent:1; ++#else ++ u8 extent:1; ++ u8 obsolete:4; ++ u8 reserved:3; ++#endif ++ u8 reservation_id; ++ u16 param_list_len; ++ u8 control; ++}; ++ ++/* ++ * h ++ */ ++struct scsi_release6_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 obsolete:4; ++ u8 extent:1; ++#else ++ u8 extent:1; ++ u8 obsolete:4; ++ u8 reserved1:3; ++#endif ++ u8 reservation_id; ++ u16 reserved2; ++ u8 control; ++}; ++ ++/* ++ * h ++ */ ++struct scsi_reserve10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 third_party:1; ++ u8 reserved2:2; ++ u8 long_id:1; ++ u8 extent:1; ++#else ++ u8 extent:1; ++ u8 long_id:1; ++ u8 reserved2:2; ++ u8 third_party:1; ++ u8 reserved1:3; ++#endif ++ u8 reservation_id; ++ u8 third_pty_dev_id; ++ u8 reserved3; ++ u8 reserved4; ++ u8 reserved5; ++ u16 param_list_len; ++ u8 control; ++}; ++ ++struct scsi_release10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 third_party:1; ++ u8 reserved2:2; ++ u8 long_id:1; ++ u8 extent:1; ++#else ++ u8 extent:1; ++ u8 long_id:1; ++ u8 reserved2:2; ++ u8 third_party:1; ++ u8 reserved1:3; ++#endif ++ u8 reservation_id; ++ u8 third_pty_dev_id; ++ u8 reserved3; ++ u8 reserved4; ++ u8 reserved5; ++ u16 param_list_len; ++ u8 control; ++}; ++ ++struct scsi_verify10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 dpo:1; ++ u8 reserved:2; ++ u8 bytchk:1; ++ u8 reladdr:1; ++#else ++ u8 reladdr:1; ++ u8 bytchk:1; ++ u8 reserved:2; ++ u8 dpo:1; ++ u8 lun:3; ++#endif ++ u8 lba0; ++ u8 lba1; ++ u8 lba2; ++ u8 lba3; ++ u8 reserved1; ++ u8 verification_len0; ++ u8 verification_len1; ++ u8 control_byte; ++}; ++ ++struct scsi_request_sense_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 lun:3; ++ u8 reserved:5; ++#else ++ u8 reserved:5; ++ u8 lun:3; ++#endif ++ u8 reserved0; ++ u8 reserved1; ++ u8 alloc_len; ++ u8 control_byte; ++}; ++ ++/* ------------------------------------------------------------ ++ * SCSI status byte values ++ * ------------------------------------------------------------ ++ */ ++#define SCSI_STATUS_GOOD 0x00 ++#define SCSI_STATUS_CHECK_CONDITION 0x02 ++#define SCSI_STATUS_CONDITION_MET 0x04 ++#define SCSI_STATUS_BUSY 0x08 ++#define SCSI_STATUS_INTERMEDIATE 0x10 ++#define SCSI_STATUS_ICM 0x14 /* intermediate condition met */ ++#define SCSI_STATUS_RESERVATION_CONFLICT 0x18 ++#define SCSI_STATUS_COMMAND_TERMINATED 0x22 ++#define SCSI_STATUS_QUEUE_FULL 0x28 ++#define SCSI_STATUS_ACA_ACTIVE 0x30 ++ ++#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length ++ * in CDBs ++ */ ++ ++#define SCSI_OP_WRITE_VERIFY10 0x2E ++#define SCSI_OP_WRITE_VERIFY12 0xAE ++#define SCSI_OP_UNDEF 0xFF ++ ++/* ++ * SCSI WRITE-VERIFY(10) command ++ */ ++struct scsi_write_verify10_s{ ++ u8 opcode; ++#ifdef __BIGENDIAN ++ u8 reserved1:3; ++ u8 dpo:1; /* Disable Page Out */ ++ u8 reserved2:1; ++ u8 ebp:1; /* erse by-pass */ ++ u8 bytchk:1; /* byte check */ ++ u8 rel_adr:1; /* relative address */ ++#else ++ u8 rel_adr:1; /* relative address */ ++ u8 bytchk:1; /* byte check */ ++ u8 ebp:1; /* erse by-pass */ ++ u8 reserved2:1; ++ u8 dpo:1; /* Disable Page Out */ ++ u8 reserved1:3; ++#endif ++ u8 lba0; /* logical block address - MSB */ ++ u8 lba1; ++ u8 lba2; ++ u8 lba3; /* LSB */ ++ u8 reserved3; ++ u8 xfer_length0; /* transfer length in blocks - MSB */ ++ u8 xfer_length1; /* LSB */ ++ u8 control; ++}; ++ ++#pragma pack() ++ ++#endif /* __SCSI_H__ */ +diff --git a/drivers/scsi/bfa/include/protocol/types.h b/drivers/scsi/bfa/include/protocol/types.h +new file mode 100644 +index 0000000..2875a6c +--- /dev/null ++++ b/drivers/scsi/bfa/include/protocol/types.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * types.h Protocol defined base types ++ */ ++ ++#ifndef __TYPES_H__ ++#define __TYPES_H__ ++ ++#include ++ ++#define wwn_t u64 ++#define lun_t u64 ++ ++#define WWN_NULL (0) ++#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */ ++#define FC_ALPA_MAX 128 ++ ++#pragma pack(1) ++ ++#define MAC_ADDRLEN (6) ++struct mac_s { u8 mac[MAC_ADDRLEN]; }; ++#define mac_t struct mac_s ++ ++#pragma pack() ++ ++#endif +diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c +new file mode 100644 +index 0000000..a418ded +--- /dev/null ++++ b/drivers/scsi/bfa/loop.c +@@ -0,0 +1,422 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * port_loop.c vport private loop implementation. ++ */ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_trcmod.h" ++#include "lport_priv.h" ++ ++BFA_TRC_FILE(FCS, LOOP); ++ ++/** ++ * ALPA to LIXA bitmap mapping ++ * ++ * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31 ++ * is for L_bit (login required) and is filled as ALPA 0x00 here. ++ */ ++static const u8 port_loop_alpa_map[] = { ++ 0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, /* Word 3 Bits 0..7 */ ++ 0xD9, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, /* Word 3 Bits 8..15 */ ++ 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7, 0xC6, 0xC5, /* Word 3 Bits 16..23 */ ++ 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5, 0xB4, 0xB3, /* Word 3 Bits 24..31 */ ++ ++ 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, /* Word 2 Bits 0..7 */ ++ 0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, /* Word 2 Bits 8..15 */ ++ 0x98, 0x97, 0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, /* Word 2 Bits 16..23 */ ++ 0x80, 0x7C, 0x7A, 0x79, 0x76, 0x75, 0x74, 0x73, /* Word 2 Bits 24..31 */ ++ ++ 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, /* Word 1 Bits 0..7 */ ++ 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56, /* Word 1 Bits 8..15 */ ++ 0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, /* Word 1 Bits 16..23 */ ++ 0x4B, 0x4A, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, /* Word 1 Bits 24..31 */ ++ ++ 0x3A, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, /* Word 0 Bits 0..7 */ ++ 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x27, 0x26, /* Word 0 Bits 8..15 */ ++ 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17, /* Word 0 Bits 16..23 */ ++ 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, /* Word 0 Bits 24..31 */ ++}; ++ ++/* ++ * Local Functions ++ */ ++bfa_status_t bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, ++ u8 alpa); ++ ++void bfa_fcs_port_loop_plogi_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++bfa_status_t bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, ++ u8 alpa); ++ ++void bfa_fcs_port_loop_adisc_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++bfa_status_t bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, ++ u8 alpa); ++ ++void bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++bfa_status_t bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, ++ u8 alpa); ++ ++void bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++/** ++ * Called by port to initializar in provate LOOP topology. ++ */ ++void ++bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port) ++{ ++} ++ ++/** ++ * Called by port to notify transition to online state. ++ */ ++void ++bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port) ++{ ++ ++ u8 num_alpa = port->port_topo.ploop.num_alpa; ++ u8 *alpa_pos_map = port->port_topo.ploop.alpa_pos_map; ++ struct bfa_fcs_rport_s *r_port; ++ int ii = 0; ++ ++ /* ++ * If the port role is Initiator Mode, create Rports. ++ */ ++ if (port->port_cfg.roles == BFA_PORT_ROLE_FCP_IM) { ++ /* ++ * Check if the ALPA positional bitmap is available. ++ * if not, we send PLOGI to all possible ALPAs. ++ */ ++ if (num_alpa > 0) { ++ for (ii = 0; ii < num_alpa; ii++) { ++ /* ++ * ignore ALPA of bfa port ++ */ ++ if (alpa_pos_map[ii] != port->pid) { ++ r_port = bfa_fcs_rport_create(port, ++ alpa_pos_map[ii]); ++ } ++ } ++ } else { ++ for (ii = 0; ii < MAX_ALPA_COUNT; ii++) { ++ /* ++ * ignore ALPA of bfa port ++ */ ++ if ((port_loop_alpa_map[ii] > 0) ++ && (port_loop_alpa_map[ii] != port->pid)) ++ bfa_fcs_port_loop_send_plogi(port, ++ port_loop_alpa_map[ii]); ++ /**TBD */ ++ } ++ } ++ } else { ++ /* ++ * TBD Target Mode ?? ++ */ ++ } ++ ++} ++ ++/** ++ * Called by port to notify transition to offline state. ++ */ ++void ++bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port) ++{ ++ ++} ++ ++/** ++ * Called by port to notify a LIP on the loop. ++ */ ++void ++bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port) ++{ ++} ++ ++/** ++ * Local Functions. ++ */ ++bfa_status_t ++bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp = NULL; ++ int len; ++ ++ bfa_trc(port->fcs, alpa); ++ ++ fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL, ++ NULL); ++ bfa_assert(fcxp); ++ ++ len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, ++ bfa_fcs_port_loop_plogi_response, (void *)port, ++ FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Called by fcxp to notify the Plogi response ++ */ ++void ++bfa_fcs_port_loop_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg; ++ struct fc_logi_s *plogi_resp; ++ struct fc_els_cmd_s *els_cmd; ++ ++ bfa_trc(port->fcs, req_status); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ /* ++ * @todo ++ * This could mean that the device with this APLA does not ++ * exist on the loop. ++ */ ++ ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ plogi_resp = (struct fc_logi_s *) els_cmd; ++ ++ if (els_cmd->els_code == FC_ELS_ACC) { ++ bfa_fcs_rport_start(port, rsp_fchs, plogi_resp); ++ } else { ++ bfa_trc(port->fcs, plogi_resp->els_cmd.els_code); ++ bfa_assert(0); ++ } ++} ++ ++bfa_status_t ++bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, u8 alpa) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(port->fcs, alpa); ++ ++ fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL, ++ NULL); ++ bfa_assert(fcxp); ++ ++ len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, ++ bfa_fcs_port_loop_plogi_acc_response, ++ (void *)port, FC_MAX_PDUSZ, 0); /* No response ++ * expected ++ */ ++ ++ return BFA_STATUS_OK; ++} ++ ++/* ++ * Plogi Acc Response ++ * We donot do any processing here. ++ */ ++void ++bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ ++ struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ return; ++ } ++} ++ ++bfa_status_t ++bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, u8 alpa) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(port->fcs, alpa); ++ ++ fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL, ++ NULL); ++ bfa_assert(fcxp); ++ ++ len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, ++ bfa_fcs_port_loop_adisc_response, (void *)port, ++ FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Called by fcxp to notify the ADISC response ++ */ ++void ++bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg; ++ struct bfa_fcs_rport_s *rport; ++ struct fc_adisc_s *adisc_resp; ++ struct fc_els_cmd_s *els_cmd; ++ u32 pid = rsp_fchs->s_id; ++ ++ bfa_trc(port->fcs, req_status); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ /* ++ * TBD : we may need to retry certain requests ++ */ ++ bfa_fcxp_free(fcxp); ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ adisc_resp = (struct fc_adisc_s *) els_cmd; ++ ++ if (els_cmd->els_code == FC_ELS_ACC) { ++ } else { ++ bfa_trc(port->fcs, adisc_resp->els_cmd.els_code); ++ ++ /* ++ * TBD: we may need to check for reject codes and retry ++ */ ++ rport = bfa_fcs_port_get_rport_by_pid(port, pid); ++ if (rport) { ++ list_del(&rport->qe); ++ bfa_fcs_rport_delete(rport); ++ } ++ ++ } ++ return; ++} ++ ++bfa_status_t ++bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, u8 alpa) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(port->fcs, alpa); ++ ++ fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL, ++ NULL); ++ bfa_assert(fcxp); ++ ++ len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, ++ bfa_fcs_port_loop_adisc_acc_response, ++ (void *)port, FC_MAX_PDUSZ, 0); /* no reponse ++ * expected ++ */ ++ ++ return BFA_STATUS_OK; ++} ++ ++/* ++ * Adisc Acc Response ++ * We donot do any processing here. ++ */ ++void ++bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ ++ struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ return; ++ } ++} +diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c +new file mode 100644 +index 0000000..8f51a83 +--- /dev/null ++++ b/drivers/scsi/bfa/lport_api.c +@@ -0,0 +1,291 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * port_api.c BFA FCS port ++ */ ++ ++#include ++#include ++#include ++#include "fcs_rport.h" ++#include "fcs_fabric.h" ++#include "fcs_trcmod.h" ++#include "fcs_vport.h" ++ ++BFA_TRC_FILE(FCS, PORT_API); ++ ++ ++ ++/** ++ * fcs_port_api BFA FCS port API ++ */ ++ ++void ++bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg) ++{ ++} ++ ++struct bfa_fcs_port_s * ++bfa_fcs_get_base_port(struct bfa_fcs_s *fcs) ++{ ++ return (&fcs->fabric.bport); ++} ++ ++wwn_t ++bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn, int index, ++ int nrports, bfa_boolean_t bwwn) ++{ ++ struct list_head *qh, *qe; ++ struct bfa_fcs_rport_s *rport = NULL; ++ int i; ++ struct bfa_fcs_s *fcs; ++ ++ if (port == NULL || nrports == 0) ++ return (wwn_t) 0; ++ ++ fcs = port->fcs; ++ bfa_trc(fcs, (u32) nrports); ++ ++ i = 0; ++ qh = &port->rport_q; ++ qe = bfa_q_first(qh); ++ ++ while ((qe != qh) && (i < nrports)) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) { ++ qe = bfa_q_next(qe); ++ bfa_trc(fcs, (u32) rport->pwwn); ++ bfa_trc(fcs, rport->pid); ++ bfa_trc(fcs, i); ++ continue; ++ } ++ ++ if (bwwn) { ++ if (!memcmp(&wwn, &rport->pwwn, 8)) ++ break; ++ } else { ++ if (i == index) ++ break; ++ } ++ ++ i++; ++ qe = bfa_q_next(qe); ++ } ++ ++ bfa_trc(fcs, i); ++ if (rport) { ++ return rport->pwwn; ++ } else { ++ return (wwn_t) 0; ++ } ++} ++ ++void ++bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, wwn_t rport_wwns[], ++ int *nrports) ++{ ++ struct list_head *qh, *qe; ++ struct bfa_fcs_rport_s *rport = NULL; ++ int i; ++ struct bfa_fcs_s *fcs; ++ ++ if (port == NULL || rport_wwns == NULL || *nrports == 0) ++ return; ++ ++ fcs = port->fcs; ++ bfa_trc(fcs, (u32) *nrports); ++ ++ i = 0; ++ qh = &port->rport_q; ++ qe = bfa_q_first(qh); ++ ++ while ((qe != qh) && (i < *nrports)) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) { ++ qe = bfa_q_next(qe); ++ bfa_trc(fcs, (u32) rport->pwwn); ++ bfa_trc(fcs, rport->pid); ++ bfa_trc(fcs, i); ++ continue; ++ } ++ ++ rport_wwns[i] = rport->pwwn; ++ ++ i++; ++ qe = bfa_q_next(qe); ++ } ++ ++ bfa_trc(fcs, i); ++ *nrports = i; ++ return; ++} ++ ++/* ++ * Iterate's through all the rport's in the given port to ++ * determine the maximum operating speed. ++ */ ++enum bfa_pport_speed ++bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port) ++{ ++ struct list_head *qh, *qe; ++ struct bfa_fcs_rport_s *rport = NULL; ++ struct bfa_fcs_s *fcs; ++ enum bfa_pport_speed max_speed = 0; ++ struct bfa_pport_attr_s pport_attr; ++ enum bfa_pport_speed pport_speed; ++ ++ if (port == NULL) ++ return 0; ++ ++ fcs = port->fcs; ++ ++ /* ++ * Get Physical port's current speed ++ */ ++ bfa_pport_get_attr(port->fcs->bfa, &pport_attr); ++ pport_speed = pport_attr.speed; ++ bfa_trc(fcs, pport_speed); ++ ++ qh = &port->rport_q; ++ qe = bfa_q_first(qh); ++ ++ while (qe != qh) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000) ++ || (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE)) { ++ qe = bfa_q_next(qe); ++ continue; ++ } ++ ++ if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_8GBPS) ++ || (rport->rpf.rpsc_speed > pport_speed)) { ++ max_speed = rport->rpf.rpsc_speed; ++ break; ++ } else if (rport->rpf.rpsc_speed > max_speed) { ++ max_speed = rport->rpf.rpsc_speed; ++ } ++ ++ qe = bfa_q_next(qe); ++ } ++ ++ bfa_trc(fcs, max_speed); ++ return max_speed; ++} ++ ++struct bfa_fcs_port_s * ++bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn) ++{ ++ struct bfa_fcs_vport_s *vport; ++ bfa_fcs_vf_t *vf; ++ ++ bfa_assert(fcs != NULL); ++ ++ vf = bfa_fcs_vf_lookup(fcs, vf_id); ++ if (vf == NULL) { ++ bfa_trc(fcs, vf_id); ++ return (NULL); ++ } ++ ++ if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn)) ++ return (&vf->bport); ++ ++ vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn); ++ if (vport) ++ return (&vport->lport); ++ ++ return (NULL); ++} ++ ++/* ++ * API corresponding to VmWare's NPIV_VPORT_GETINFO. ++ */ ++void ++bfa_fcs_port_get_info(struct bfa_fcs_port_s *port, ++ struct bfa_port_info_s *port_info) ++{ ++ ++ bfa_trc(port->fcs, port->fabric->fabric_name); ++ ++ if (port->vport == NULL) { ++ /* ++ * This is a Physical port ++ */ ++ port_info->port_type = BFA_PORT_TYPE_PHYSICAL; ++ ++ /* ++ * @todo : need to fix the state & reason ++ */ ++ port_info->port_state = 0; ++ port_info->offline_reason = 0; ++ ++ port_info->port_wwn = bfa_fcs_port_get_pwwn(port); ++ port_info->node_wwn = bfa_fcs_port_get_nwwn(port); ++ ++ port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs); ++ port_info->num_vports_inuse = ++ bfa_fcs_fabric_vport_count(port->fabric); ++ port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP; ++ port_info->num_rports_inuse = port->num_rports; ++ } else { ++ /* ++ * This is a virtual port ++ */ ++ port_info->port_type = BFA_PORT_TYPE_VIRTUAL; ++ ++ /* ++ * @todo : need to fix the state & reason ++ */ ++ port_info->port_state = 0; ++ port_info->offline_reason = 0; ++ ++ port_info->port_wwn = bfa_fcs_port_get_pwwn(port); ++ port_info->node_wwn = bfa_fcs_port_get_nwwn(port); ++ } ++} ++ ++void ++bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port, ++ struct bfa_port_stats_s *port_stats) ++{ ++ bfa_os_memcpy(port_stats, &fcs_port->stats, ++ sizeof(struct bfa_port_stats_s)); ++ return; ++} ++ ++void ++bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port) ++{ ++ bfa_os_memset(&fcs_port->stats, 0, sizeof(struct bfa_port_stats_s)); ++ return; ++} ++ ++void ++bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port) ++{ ++ fcs_port->port_cfg.roles |= BFA_PORT_ROLE_FCP_IPFC; ++ return; ++} ++ ++void ++bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port) ++{ ++ fcs_port->port_cfg.roles &= ~BFA_PORT_ROLE_FCP_IPFC; ++ return; ++} ++ ++ +diff --git a/drivers/scsi/bfa/lport_priv.h b/drivers/scsi/bfa/lport_priv.h +new file mode 100644 +index 0000000..dbae370 +--- /dev/null ++++ b/drivers/scsi/bfa/lport_priv.h +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#ifndef __VP_PRIV_H__ ++#define __VP_PRIV_H__ ++ ++#include ++#include ++ ++/* ++ * Functions exported by vps ++ */ ++void bfa_fcs_vport_init(struct bfa_fcs_vport_s *vport); ++ ++/* ++ * Functions exported by vps ++ */ ++void bfa_fcs_vps_online(struct bfa_fcs_port_s *port); ++void bfa_fcs_vps_offline(struct bfa_fcs_port_s *port); ++void bfa_fcs_vps_lip(struct bfa_fcs_port_s *port); ++ ++/* ++ * Functions exported by port_fab ++ */ ++void bfa_fcs_port_fab_init(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_fab_online(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_fab_rx_frame(struct bfa_fcs_port_s *port, ++ u8 *rx_frame, u32 len); ++ ++/* ++ * Functions exported by VP-NS. ++ */ ++void bfa_fcs_port_ns_init(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_ns_online(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port); ++ ++/* ++ * Functions exported by VP-SCN ++ */ ++void bfa_fcs_port_scn_init(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_scn_online(struct bfa_fcs_port_s *vport); ++void bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_frame, u32 len); ++ ++/* ++ * Functions exported by VP-N2N ++ */ ++ ++void bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_n2n_rx_frame(struct bfa_fcs_port_s *port, ++ u8 *rx_frame, u32 len); ++ ++/* ++ * Functions exported by VP-LOOP ++ */ ++void bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port); ++void bfa_fcs_port_loop_rx_frame(struct bfa_fcs_port_s *port, ++ u8 *rx_frame, u32 len); ++ ++#endif /* __VP_PRIV_H__ */ +diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c +new file mode 100644 +index 0000000..c96b3ca +--- /dev/null ++++ b/drivers/scsi/bfa/ms.c +@@ -0,0 +1,759 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "lport_priv.h" ++ ++BFA_TRC_FILE(FCS, MS); ++ ++#define BFA_FCS_MS_CMD_MAX_RETRIES 2 ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_port_ms_send_plogi(void *ms_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ms_timeout(void *arg); ++static void bfa_fcs_port_ms_plogi_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++ ++static void bfa_fcs_port_ms_send_gmal(void *ms_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ms_gmal_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ms_gfn_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++/** ++ * fcs_ms_sm FCS MS state machine ++ */ ++ ++/** ++ * MS State Machine events ++ */ ++enum port_ms_event { ++ MSSM_EVENT_PORT_ONLINE = 1, ++ MSSM_EVENT_PORT_OFFLINE = 2, ++ MSSM_EVENT_RSP_OK = 3, ++ MSSM_EVENT_RSP_ERROR = 4, ++ MSSM_EVENT_TIMEOUT = 5, ++ MSSM_EVENT_FCXP_SENT = 6, ++ MSSM_EVENT_PORT_FABRIC_RSCN = 7 ++}; ++ ++static void bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++static void bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event); ++/** ++ * Start in offline state - awaiting NS to send start. ++ */ ++static void ++bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_PORT_ONLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending); ++ bfa_fcs_port_ms_send_plogi(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), ++ &ms->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer, ++ bfa_fcs_port_ms_timeout, ms, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case MSSM_EVENT_RSP_OK: ++ /* ++ * since plogi is done, now invoke MS related sub-modules ++ */ ++ bfa_fcs_port_fdmi_online(ms); ++ ++ /** ++ * if this is a Vport, go to online state. ++ */ ++ if (ms->port->vport) { ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online); ++ break; ++ } ++ ++ /* ++ * For a base port we need to get the ++ * switch's IP address. ++ */ ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending); ++ bfa_fcs_port_ms_send_gmal(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_discard(ms->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending); ++ bfa_fcs_port_ms_send_plogi(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_timer_stop(&ms->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ /* ++ * now invoke MS related sub-modules ++ */ ++ bfa_fcs_port_fdmi_offline(ms); ++ break; ++ ++ case MSSM_EVENT_PORT_FABRIC_RSCN: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending); ++ ms->retry_cnt = 0; ++ bfa_fcs_port_ms_send_gfn(ms, NULL); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), ++ &ms->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), ++ &ms->timer, bfa_fcs_port_ms_timeout, ms, ++ BFA_FCS_RETRY_TIMEOUT); ++ } else { ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending); ++ bfa_fcs_port_ms_send_gfn(ms, NULL); ++ ms->retry_cnt = 0; ++ } ++ break; ++ ++ case MSSM_EVENT_RSP_OK: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending); ++ bfa_fcs_port_ms_send_gfn(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_discard(ms->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending); ++ bfa_fcs_port_ms_send_gmal(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_timer_stop(&ms->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * ms_pvt MS local functions ++ */ ++ ++static void ++bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ms_s *ms = ms_cbarg; ++ struct bfa_fcs_port_s *port = ms->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, ++ bfa_fcs_port_ms_send_gmal, ms); ++ return; ++ } ++ ms->fcxp = fcxp; ++ ++ len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), ++ bfa_lps_get_peer_nwwn(port->fabric->lps)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response, ++ (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg; ++ struct bfa_fcs_port_s *port = ms->port; ++ struct ct_hdr_s *cthdr = NULL; ++ struct fcgs_gmal_resp_s *gmal_resp; ++ struct fc_gmal_entry_s *gmal_entry; ++ u32 num_entries; ++ u8 *rsp_str; ++ ++ bfa_trc(port->fcs, req_status); ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); ++ num_entries = bfa_os_ntohl(gmal_resp->ms_len); ++ if (num_entries == 0) { ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ /* ++ * The response could contain multiple Entries. ++ * Entries for SNMP interface, etc. ++ * We look for the entry with a telnet prefix. ++ * First "http://" entry refers to IP addr ++ */ ++ ++ gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma; ++ while (num_entries > 0) { ++ if (strncmp ++ (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP, ++ sizeof(gmal_entry->prefix)) == 0) { ++ ++ /* ++ * if the IP address is terminating with a '/', ++ * remove it. *Byte 0 consists of the length ++ * of the string. ++ */ ++ rsp_str = &(gmal_entry->prefix[0]); ++ if (rsp_str[gmal_entry->len - 1] == '/') ++ rsp_str[gmal_entry->len - 1] = 0; ++ /* ++ * copy IP Address to fabric ++ */ ++ strncpy(bfa_fcs_port_get_fabric_ipaddr(port), ++ gmal_entry->ip_addr, ++ BFA_FCS_FABRIC_IPADDR_SZ); ++ break; ++ } else { ++ --num_entries; ++ ++gmal_entry; ++ } ++ } ++ ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); ++ return; ++ } ++ ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++} ++ ++static void ++bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port), ++ &ms->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) { ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry); ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), ++ &ms->timer, bfa_fcs_port_ms_timeout, ms, ++ BFA_FCS_RETRY_TIMEOUT); ++ } else { ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online); ++ ms->retry_cnt = 0; ++ } ++ break; ++ ++ case MSSM_EVENT_RSP_OK: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_fcxp_discard(ms->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms, ++ enum port_ms_event event) ++{ ++ bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn); ++ bfa_trc(ms->port->fcs, event); ++ ++ switch (event) { ++ case MSSM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending); ++ bfa_fcs_port_ms_send_gfn(ms, NULL); ++ break; ++ ++ case MSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ bfa_timer_stop(&ms->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * ms_pvt MS local functions ++ */ ++ ++static void ++bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ms_s *ms = ms_cbarg; ++ struct bfa_fcs_port_s *port = ms->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, ++ bfa_fcs_port_ms_send_gfn, ms); ++ return; ++ } ++ ms->fcxp = fcxp; ++ ++ len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), ++ bfa_lps_get_peer_nwwn(port->fabric->lps)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response, ++ (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg; ++ struct bfa_fcs_port_s *port = ms->port; ++ struct ct_hdr_s *cthdr = NULL; ++ wwn_t *gfn_resp; ++ ++ bfa_trc(port->fcs, req_status); ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ gfn_resp = (wwn_t *) (cthdr + 1); ++ /* ++ * check if it has actually changed ++ */ ++ if ((memcmp ++ ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp, ++ sizeof(wwn_t)) != 0)) ++ bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); ++ return; ++ } ++ ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++} ++ ++/** ++ * ms_pvt MS local functions ++ */ ++ ++static void ++bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ms_s *ms = ms_cbarg; ++ struct bfa_fcs_port_s *port = ms->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ms_plogi_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, ++ bfa_fcs_port_ms_send_plogi, ms); ++ return; ++ } ++ ms->fcxp = fcxp; ++ ++ len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_os_hton3b(FC_MGMT_SERVER), ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response, ++ (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ port->stats.ms_plogi_sent++; ++ bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg; ++ ++ struct bfa_fcs_port_s *port = ms->port; ++ struct fc_els_cmd_s *els_cmd; ++ struct fc_ls_rjt_s *ls_rjt; ++ ++ bfa_trc(port->fcs, req_status); ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ port->stats.ms_plogi_rsp_err++; ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ switch (els_cmd->els_code) { ++ ++ case FC_ELS_ACC: ++ if (rsp_len < sizeof(struct fc_logi_s)) { ++ bfa_trc(port->fcs, rsp_len); ++ port->stats.ms_plogi_acc_err++; ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ break; ++ } ++ port->stats.ms_plogi_accepts++; ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); ++ break; ++ ++ case FC_ELS_LS_RJT: ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ bfa_trc(port->fcs, ls_rjt->reason_code); ++ bfa_trc(port->fcs, ls_rjt->reason_code_expl); ++ ++ port->stats.ms_rejects++; ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ break; ++ ++ default: ++ port->stats.ms_plogi_unknown_rsp++; ++ bfa_trc(port->fcs, els_cmd->els_code); ++ bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); ++ } ++} ++ ++static void ++bfa_fcs_port_ms_timeout(void *arg) ++{ ++ struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg; ++ ++ ms->port->stats.ms_timeouts++; ++ bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT); ++} ++ ++ ++void ++bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); ++ ++ ms->port = port; ++ bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline); ++ ++ /* ++ * Invoke init routines of sub modules. ++ */ ++ bfa_fcs_port_fdmi_init(ms); ++} ++ ++void ++bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); ++ ++ ms->port = port; ++ bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE); ++} ++ ++void ++bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); ++ ++ ms->port = port; ++ bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE); ++} ++ ++void ++bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port); ++ ++ /* ++ * @todo. Handle this only when in Online state ++ */ ++ if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online)) ++ bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN); ++} +diff --git a/drivers/scsi/bfa/n2n.c b/drivers/scsi/bfa/n2n.c +new file mode 100644 +index 0000000..7354568 +--- /dev/null ++++ b/drivers/scsi/bfa/n2n.c +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * n2n.c n2n implementation. ++ */ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_trcmod.h" ++#include "lport_priv.h" ++ ++BFA_TRC_FILE(FCS, N2N); ++ ++/** ++ * Called by fcs/port to initialize N2N topology. ++ */ ++void ++bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port) ++{ ++} ++ ++/** ++ * Called by fcs/port to notify transition to online state. ++ */ ++void ++bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n; ++ struct bfa_port_cfg_s *pcfg = &port->port_cfg; ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, pcfg->pwwn); ++ ++ /* ++ * If our PWWN is > than that of the r-port, we have to initiate PLOGI ++ * and assign an Address. if not, we need to wait for its PLOGI. ++ * ++ * If our PWWN is < than that of the remote port, it will send a PLOGI ++ * with the PIDs assigned. The rport state machine take care of this ++ * incoming PLOGI. ++ */ ++ if (memcmp ++ ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, ++ sizeof(wwn_t)) > 0) { ++ port->pid = N2N_LOCAL_PID; ++ /** ++ * First, check if we know the device by pwwn. ++ */ ++ rport = bfa_fcs_port_get_rport_by_pwwn(port, ++ n2n_port->rem_port_wwn); ++ if (rport) { ++ bfa_trc(port->fcs, rport->pid); ++ bfa_trc(port->fcs, rport->pwwn); ++ rport->pid = N2N_REMOTE_PID; ++ bfa_fcs_rport_online(rport); ++ return; ++ } ++ ++ /* ++ * In n2n there can be only one rport. Delete the old one whose ++ * pid should be zero, because it is offline. ++ */ ++ if (port->num_rports > 0) { ++ rport = bfa_fcs_port_get_rport_by_pid(port, 0); ++ bfa_assert(rport != NULL); ++ if (rport) { ++ bfa_trc(port->fcs, rport->pwwn); ++ bfa_fcs_rport_delete(rport); ++ } ++ } ++ bfa_fcs_rport_create(port, N2N_REMOTE_PID); ++ } ++} ++ ++/** ++ * Called by fcs/port to notify transition to offline state. ++ */ ++void ++bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n; ++ ++ bfa_trc(port->fcs, port->pid); ++ port->pid = 0; ++ n2n_port->rem_port_wwn = 0; ++ n2n_port->reply_oxid = 0; ++} ++ ++ +diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c +new file mode 100644 +index 0000000..59fea99 +--- /dev/null ++++ b/drivers/scsi/bfa/ns.c +@@ -0,0 +1,1243 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * @page ns_sm_info VPORT NS State Machine ++ * ++ * @section ns_sm_interactions VPORT NS State Machine Interactions ++ * ++ * @section ns_sm VPORT NS State Machine ++ * img ns_sm.jpg ++ */ ++#include ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs.h" ++#include "lport_priv.h" ++ ++BFA_TRC_FILE(FCS, NS); ++ ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_ns_timeout(void *arg); ++static void bfa_fcs_port_ns_plogi_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ns_rspn_id_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ns_rft_id_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ns_rff_id_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port, ++ u32 *pid_buf, ++ u32 n_pids); ++ ++static void bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port); ++/** ++ * fcs_ns_sm FCS nameserver interface state machine ++ */ ++ ++/** ++ * VPort NS State Machine events ++ */ ++enum vport_ns_event { ++ NSSM_EVENT_PORT_ONLINE = 1, ++ NSSM_EVENT_PORT_OFFLINE = 2, ++ NSSM_EVENT_PLOGI_SENT = 3, ++ NSSM_EVENT_RSP_OK = 4, ++ NSSM_EVENT_RSP_ERROR = 5, ++ NSSM_EVENT_TIMEOUT = 6, ++ NSSM_EVENT_NS_QUERY = 7, ++ NSSM_EVENT_RSPNID_SENT = 8, ++ NSSM_EVENT_RFTID_SENT = 9, ++ NSSM_EVENT_RFFID_SENT = 10, ++ NSSM_EVENT_GIDFT_SENT = 11, ++}; ++ ++static void bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++static void bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event); ++/** ++ * Start in offline state - awaiting linkup ++ */ ++static void ++bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_PORT_ONLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending); ++ bfa_fcs_port_ns_send_plogi(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_PLOGI_SENT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), ++ &ns->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_retry); ++ ns->port->stats.ns_retries++; ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer, ++ bfa_fcs_port_ns_timeout, ns, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case NSSM_EVENT_RSP_OK: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id); ++ bfa_fcs_port_ns_send_rspn_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_discard(ns->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending); ++ bfa_fcs_port_ns_send_plogi(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_timer_stop(&ns->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSPNID_SENT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), ++ &ns->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id_retry); ++ ns->port->stats.ns_retries++; ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer, ++ bfa_fcs_port_ns_timeout, ns, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case NSSM_EVENT_RSP_OK: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id); ++ bfa_fcs_port_ns_send_rft_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_fcxp_discard(ns->fcxp); ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_TIMEOUT: ++ /* ++ * Retry Timer Expired. Re-send ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id); ++ bfa_fcs_port_ns_send_rspn_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_timer_stop(&ns->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RFTID_SENT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), ++ &ns->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSP_OK: ++ /* ++ * Now move to register FC4 Features ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id); ++ bfa_fcs_port_ns_send_rff_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id_retry); ++ ns->port->stats.ns_retries++; ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer, ++ bfa_fcs_port_ns_timeout, ns, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_discard(ns->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id); ++ bfa_fcs_port_ns_send_rft_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_timer_stop(&ns->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RFFID_SENT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), ++ &ns->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSP_OK: ++ ++ /* ++ * If min cfg mode is enabled, we donot initiate rport ++ * discovery with the fabric. Instead, we will retrieve the ++ * boot targets from HAL/FW. ++ */ ++ if (__fcs_min_cfg(ns->port->fcs)) { ++ bfa_fcs_port_ns_boot_target_disc(ns->port); ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online); ++ return; ++ } ++ ++ /* ++ * If the port role is Initiator Mode issue NS query. ++ * If it is Target Mode, skip this and go to online. ++ */ ++ if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft); ++ bfa_fcs_port_ns_send_gid_ft(ns, NULL); ++ } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) { ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online); ++ } ++ /* ++ * kick off mgmt srvr state machine ++ */ ++ bfa_fcs_port_ms_online(ns->port); ++ break; ++ ++ case NSSM_EVENT_RSP_ERROR: ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id_retry); ++ ns->port->stats.ns_retries++; ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer, ++ bfa_fcs_port_ns_timeout, ns, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_discard(ns->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id); ++ bfa_fcs_port_ns_send_rff_id(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_timer_stop(&ns->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++static void ++bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_GIDFT_SENT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port), ++ &ns->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_RSP_OK: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online); ++ break; ++ ++ case NSSM_EVENT_RSP_ERROR: ++ /* ++ * TBD: for certain reject codes, we don't need to retry ++ */ ++ /* ++ * Start timer for a delayed retry ++ */ ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft_retry); ++ ns->port->stats.ns_retries++; ++ bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer, ++ bfa_fcs_port_ns_timeout, ns, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_fcxp_discard(ns->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft); ++ bfa_fcs_port_ns_send_gid_ft(ns, NULL); ++ break; ++ ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ bfa_timer_stop(&ns->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns, ++ enum vport_ns_event event) ++{ ++ bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn); ++ bfa_trc(ns->port->fcs, event); ++ ++ switch (event) { ++ case NSSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++ break; ++ ++ case NSSM_EVENT_NS_QUERY: ++ /* ++ * If the port role is Initiator Mode issue NS query. ++ * If it is Target Mode, skip this and go to online. ++ */ ++ if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft); ++ bfa_fcs_port_ns_send_gid_ft(ns, NULL); ++ }; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * ns_pvt Nameserver local functions ++ */ ++ ++static void ++bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ns_s *ns = ns_cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ns_plogi_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, ++ bfa_fcs_port_ns_send_plogi, ns); ++ return; ++ } ++ ns->fcxp = fcxp; ++ ++ len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_os_hton3b(FC_NAME_SERVER), ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, ++ (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); ++ port->stats.ns_plogi_sent++; ++ ++ bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); ++} ++ ++static void ++bfa_fcs_port_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ /* struct fc_logi_s *plogi_resp; */ ++ struct fc_els_cmd_s *els_cmd; ++ struct fc_ls_rjt_s *ls_rjt; ++ ++ bfa_trc(port->fcs, req_status); ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ port->stats.ns_plogi_rsp_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ switch (els_cmd->els_code) { ++ ++ case FC_ELS_ACC: ++ if (rsp_len < sizeof(struct fc_logi_s)) { ++ bfa_trc(port->fcs, rsp_len); ++ port->stats.ns_plogi_acc_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ break; ++ } ++ port->stats.ns_plogi_accepts++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ break; ++ ++ case FC_ELS_LS_RJT: ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ bfa_trc(port->fcs, ls_rjt->reason_code); ++ bfa_trc(port->fcs, ls_rjt->reason_code_expl); ++ ++ port->stats.ns_rejects++; ++ ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ break; ++ ++ default: ++ port->stats.ns_plogi_unknown_rsp++; ++ bfa_trc(port->fcs, els_cmd->els_code); ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ } ++} ++ ++/** ++ * Register the symbolic port name. ++ */ ++static void ++bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ns_s *ns = ns_cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ u8 symbl[256]; ++ u8 *psymbl = &symbl[0]; ++ ++ bfa_os_memset(symbl, 0, sizeof(symbl)); ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ns_rspnid_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, ++ bfa_fcs_port_ns_send_rspn_id, ns); ++ return; ++ } ++ ns->fcxp = fcxp; ++ ++ /* ++ * for V-Port, form a Port Symbolic Name ++ */ ++ if (port->vport) { ++ /**For Vports, ++ * we append the vport's port symbolic name to that of the base port. ++ */ ++ ++ strncpy((char *)psymbl, ++ (char *) ++ &(bfa_fcs_port_get_psym_name ++ (bfa_fcs_get_base_port(port->fcs))), ++ strlen((char *) ++ &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port ++ (port->fcs)))); ++ ++ /* ++ * Ensure we have a null terminating string. ++ */ ++ ((char *) ++ psymbl)[strlen((char *) ++ &bfa_fcs_port_get_psym_name ++ (bfa_fcs_get_base_port(port->fcs)))] = 0; ++ ++ strncat((char *)psymbl, ++ (char *)&(bfa_fcs_port_get_psym_name(port)), ++ strlen((char *)&bfa_fcs_port_get_psym_name(port))); ++ } else { ++ psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port)); ++ } ++ ++ len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), 0, psymbl); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response, ++ (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ port->stats.ns_rspnid_sent++; ++ ++ bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); ++} ++ ++static void ++bfa_fcs_port_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ port->stats.ns_rspnid_rsp_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ port->stats.ns_rspnid_accepts++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ return; ++ } ++ ++ port->stats.ns_rspnid_rejects++; ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++} ++ ++/** ++ * Register FC4-Types ++ * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ? ++ */ ++static void ++bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ns_s *ns = ns_cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ns_rftid_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, ++ bfa_fcs_port_ns_send_rft_id, ns); ++ return; ++ } ++ ns->fcxp = fcxp; ++ ++ len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.roles); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response, ++ (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ port->stats.ns_rftid_sent++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); ++} ++ ++static void ++bfa_fcs_port_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ port->stats.ns_rftid_rsp_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ port->stats.ns_rftid_accepts++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ return; ++ } ++ ++ port->stats.ns_rftid_rejects++; ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++} ++ ++/** ++* Register FC4-Features : Should be done after RFT_ID ++ */ ++static void ++bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ns_s *ns = ns_cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ u8 fc4_ftrs = 0; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ns_rffid_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, ++ bfa_fcs_port_ns_send_rff_id, ns); ++ return; ++ } ++ ns->fcxp = fcxp; ++ ++ if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { ++ fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; ++ } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) { ++ fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET; ++ } ++ ++ len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP, ++ fc4_ftrs); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response, ++ (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ port->stats.ns_rffid_sent++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); ++} ++ ++static void ++bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct ct_hdr_s *cthdr = NULL; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ port->stats.ns_rffid_rsp_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ port->stats.ns_rffid_accepts++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ return; ++ } ++ ++ port->stats.ns_rffid_rejects++; ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ ++ if (cthdr->reason_code == CT_RSN_NOT_SUPP) { ++ /* ++ * if this command is not supported, we don't retry ++ */ ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ } else { ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ } ++} ++ ++/** ++ * Query Fabric for FC4-Types Devices. ++ * ++* TBD : Need to use a local (FCS private) response buffer, since the response ++ * can be larger than 2K. ++ */ ++static void ++bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_ns_s *ns = ns_cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ port->stats.ns_gidft_alloc_wait++; ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, ++ bfa_fcs_port_ns_send_gid_ft, ns); ++ return; ++ } ++ ns->fcxp = fcxp; ++ ++ /* ++ * This query is only initiated for FCP initiator mode. ++ */ ++ len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid, ++ FC_TYPE_FCP); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response, ++ (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa), ++ FC_RA_TOV); ++ ++ port->stats.ns_gidft_sent++; ++ ++ bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); ++} ++ ++static void ++bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; ++ struct bfa_fcs_port_s *port = ns->port; ++ struct ct_hdr_s *cthdr = NULL; ++ u32 n_pids; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ port->stats.ns_gidft_rsp_err++; ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ if (resid_len != 0) { ++ /* ++ * TBD : we will need to allocate a larger buffer & retry the ++ * command ++ */ ++ bfa_trc(port->fcs, rsp_len); ++ bfa_trc(port->fcs, resid_len); ++ return; ++ } ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ switch (cthdr->cmd_rsp_code) { ++ ++ case CT_RSP_ACCEPT: ++ ++ port->stats.ns_gidft_accepts++; ++ n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); ++ bfa_trc(port->fcs, n_pids); ++ bfa_fcs_port_ns_process_gidft_pids(port, ++ (u32 *) (cthdr + 1), ++ n_pids); ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ break; ++ ++ case CT_RSP_REJECT: ++ ++ /* ++ * Check the reason code & explanation. ++ * There may not have been any FC4 devices in the fabric ++ */ ++ port->stats.ns_gidft_rejects++; ++ bfa_trc(port->fcs, cthdr->reason_code); ++ bfa_trc(port->fcs, cthdr->exp_code); ++ ++ if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) ++ && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { ++ ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); ++ } else { ++ /* ++ * for all other errors, retry ++ */ ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ } ++ break; ++ ++ default: ++ port->stats.ns_gidft_unknown_rsp++; ++ bfa_trc(port->fcs, cthdr->cmd_rsp_code); ++ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); ++ } ++} ++ ++/** ++ * This routine will be called by bfa_timer on timer timeouts. ++ * ++ * param[in] port - pointer to bfa_fcs_port_t. ++ * ++ * return ++ * void ++ * ++* Special Considerations: ++ * ++ * note ++ */ ++static void ++bfa_fcs_port_ns_timeout(void *arg) ++{ ++ struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg; ++ ++ ns->port->stats.ns_timeouts++; ++ bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT); ++} ++ ++/* ++ * Process the PID list in GID_FT response ++ */ ++static void ++bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port, ++ u32 *pid_buf, u32 n_pids) ++{ ++ struct fcgs_gidft_resp_s *gidft_entry; ++ struct bfa_fcs_rport_s *rport; ++ u32 ii; ++ ++ for (ii = 0; ii < n_pids; ii++) { ++ gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; ++ ++ if (gidft_entry->pid == port->pid) ++ continue; ++ ++ /* ++ * Check if this rport already exists ++ */ ++ rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid); ++ if (rport == NULL) { ++ /* ++ * this is a new device. create rport ++ */ ++ rport = bfa_fcs_rport_create(port, gidft_entry->pid); ++ } else { ++ /* ++ * this rport already exists ++ */ ++ bfa_fcs_rport_scn(rport); ++ } ++ ++ bfa_trc(port->fcs, gidft_entry->pid); ++ ++ /* ++ * if the last entry bit is set, bail out. ++ */ ++ if (gidft_entry->last) ++ return; ++ } ++} ++ ++/** ++ * fcs_ns_public FCS nameserver public interfaces ++ */ ++ ++/* ++ * Functions called by port/fab. ++ * These will send relevant Events to the ns state machine. ++ */ ++void ++bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); ++ ++ ns->port = port; ++ bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline); ++} ++ ++void ++bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); ++ ++ ns->port = port; ++ bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE); ++} ++ ++void ++bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); ++ ++ ns->port = port; ++ bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE); ++} ++ ++void ++bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); ++ ++ bfa_trc(port->fcs, port->pid); ++ bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); ++} ++ ++static void ++bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port) ++{ ++ ++ struct bfa_fcs_rport_s *rport; ++ u8 nwwns; ++ wwn_t *wwns; ++ int ii; ++ ++ bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns); ++ ++ for (ii = 0; ii < nwwns; ++ii) { ++ rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]); ++ bfa_assert(rport); ++ } ++} ++ ++ +diff --git a/drivers/scsi/bfa/plog.c b/drivers/scsi/bfa/plog.c +new file mode 100644 +index 0000000..86af818 +--- /dev/null ++++ b/drivers/scsi/bfa/plog.c +@@ -0,0 +1,184 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++ ++static int ++plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec) ++{ ++ if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) ++ && (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING)) ++ return 1; ++ ++ if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) ++ && (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ)) ++ return 1; ++ ++ return 0; ++} ++ ++static void ++bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec) ++{ ++ u16 tail; ++ struct bfa_plog_rec_s *pl_recp; ++ ++ if (plog->plog_enabled == 0) ++ return; ++ ++ if (plkd_validate_logrec(pl_rec)) { ++ bfa_assert(0); ++ return; ++ } ++ ++ tail = plog->tail; ++ ++ pl_recp = &(plog->plog_recs[tail]); ++ ++ bfa_os_memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s)); ++ ++ pl_recp->tv = BFA_TRC_TS(plog); ++ BFA_PL_LOG_REC_INCR(plog->tail); ++ ++ if (plog->head == plog->tail) ++ BFA_PL_LOG_REC_INCR(plog->head); ++} ++ ++void ++bfa_plog_init(struct bfa_plog_s *plog) ++{ ++ bfa_os_memset((char *)plog, 0, sizeof(struct bfa_plog_s)); ++ ++ bfa_os_memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN); ++ plog->head = plog->tail = 0; ++ plog->plog_enabled = 1; ++} ++ ++void ++bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, ++ u16 misc, char *log_str) ++{ ++ struct bfa_plog_rec_s lp; ++ ++ if (plog->plog_enabled) { ++ bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); ++ lp.mid = mid; ++ lp.eid = event; ++ lp.log_type = BFA_PL_LOG_TYPE_STRING; ++ lp.misc = misc; ++ strncpy(lp.log_entry.string_log, log_str, ++ BFA_PL_STRING_LOG_SZ - 1); ++ lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; ++ bfa_plog_add(plog, &lp); ++ } ++} ++ ++void ++bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, ++ u16 misc, u32 *intarr, u32 num_ints) ++{ ++ struct bfa_plog_rec_s lp; ++ u32 i; ++ ++ if (num_ints > BFA_PL_INT_LOG_SZ) ++ num_ints = BFA_PL_INT_LOG_SZ; ++ ++ if (plog->plog_enabled) { ++ bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); ++ lp.mid = mid; ++ lp.eid = event; ++ lp.log_type = BFA_PL_LOG_TYPE_INT; ++ lp.misc = misc; ++ ++ for (i = 0; i < num_ints; i++) ++ bfa_os_assign(lp.log_entry.int_log[i], ++ intarr[i]); ++ ++ lp.log_num_ints = (u8) num_ints; ++ ++ bfa_plog_add(plog, &lp); ++ } ++} ++ ++void ++bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, ++ u16 misc, struct fchs_s *fchdr) ++{ ++ struct bfa_plog_rec_s lp; ++ u32 *tmp_int = (u32 *) fchdr; ++ u32 ints[BFA_PL_INT_LOG_SZ]; ++ ++ if (plog->plog_enabled) { ++ bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); ++ ++ ints[0] = tmp_int[0]; ++ ints[1] = tmp_int[1]; ++ ints[2] = tmp_int[4]; ++ ++ bfa_plog_intarr(plog, mid, event, misc, ints, 3); ++ } ++} ++ ++void ++bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid, ++ enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr, ++ u32 pld_w0) ++{ ++ struct bfa_plog_rec_s lp; ++ u32 *tmp_int = (u32 *) fchdr; ++ u32 ints[BFA_PL_INT_LOG_SZ]; ++ ++ if (plog->plog_enabled) { ++ bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s)); ++ ++ ints[0] = tmp_int[0]; ++ ints[1] = tmp_int[1]; ++ ints[2] = tmp_int[4]; ++ ints[3] = pld_w0; ++ ++ bfa_plog_intarr(plog, mid, event, misc, ints, 4); ++ } ++} ++ ++void ++bfa_plog_clear(struct bfa_plog_s *plog) ++{ ++ plog->head = plog->tail = 0; ++} ++ ++void ++bfa_plog_enable(struct bfa_plog_s *plog) ++{ ++ plog->plog_enabled = 1; ++} ++ ++void ++bfa_plog_disable(struct bfa_plog_s *plog) ++{ ++ plog->plog_enabled = 0; ++} ++ ++bfa_boolean_t ++bfa_plog_get_setting(struct bfa_plog_s *plog) ++{ ++ return((bfa_boolean_t)plog->plog_enabled); ++} +diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c +new file mode 100644 +index 0000000..9cf58bb +--- /dev/null ++++ b/drivers/scsi/bfa/rport.c +@@ -0,0 +1,2618 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * rport.c Remote port implementation. ++ */ ++ ++#include ++#include ++#include "fcbuild.h" ++#include "fcs_vport.h" ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_fcpim.h" ++#include "fcs_fcptm.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs.h" ++#include ++#include ++ ++BFA_TRC_FILE(FCS, RPORT); ++ ++#define BFA_FCS_RPORT_MAX_RETRIES (5) ++ ++/* In millisecs */ ++static u32 bfa_fcs_rport_del_timeout = ++ BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000; ++ ++/* ++ * forward declarations ++ */ ++static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port, ++ wwn_t pwwn, u32 rpid); ++static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, ++ struct fc_logi_s *plogi); ++static void bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport); ++static void bfa_fcs_rport_timeout(void *arg); ++static void bfa_fcs_rport_send_plogi(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rport_plogi_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_rport_send_adisc(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rport_adisc_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_rport_send_gidpn(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rport_gidpn_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_rport_send_logo(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg); ++static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u16 len); ++static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u8 reason_code, ++ u8 reason_code_expl); ++static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u16 len); ++/** ++ * fcs_rport_sm FCS rport state machine events ++ */ ++ ++enum rport_event { ++ RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */ ++ RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */ ++ RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */ ++ RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */ ++ RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */ ++ RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */ ++ RPSM_EVENT_DELETE = 7, /* RPORT delete request */ ++ RPSM_EVENT_SCN = 8, /* state change notification */ ++ RPSM_EVENT_ACCEPTED = 9,/* Good response from remote device */ ++ RPSM_EVENT_FAILED = 10, /* Request to rport failed. */ ++ RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */ ++ RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */ ++ RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */ ++ RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */ ++ RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */ ++ RPSM_EVENT_ADDRESS_DISC = 16 /* Need to Discover rport's PID */ ++}; ++ ++static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, ++ enum rport_event event); ++ ++static struct bfa_sm_table_s rport_sm_table[] = { ++ {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT}, ++ {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI}, ++ {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY}, ++ {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI}, ++ {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, ++ {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY}, ++ {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC}, ++ {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC}, ++ {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV}, ++ {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO}, ++ {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV}, ++ {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO}, ++ {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO}, ++ {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE}, ++ {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC}, ++ {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC}, ++ {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC}, ++}; ++ ++/** ++ * Beginning state. ++ */ ++static void ++bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_PLOGI_SEND: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); ++ rport->plogi_retries = 0; ++ bfa_fcs_rport_send_plogi(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ case RPSM_EVENT_ADDRESS_DISC: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * PLOGI is being sent. ++ */ ++static void ++bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * PLOGI is being sent. ++ */ ++static void ++bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * Ignore, SCN is possibly online notification. ++ */ ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_HCB_OFFLINE: ++ /** ++ * Ignore BFA callback, on a PLOGI receive we call bfa offline. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * PLOGI is sent. ++ */ ++static void ++bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_SCN: ++ bfa_timer_stop(&rport->timer); ++ /* ++ * !! fall through !! ++ */ ++ ++ case RPSM_EVENT_TIMEOUT: ++ rport->plogi_retries++; ++ if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) { ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); ++ bfa_fcs_rport_send_plogi(rport, NULL); ++ } else { ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ } ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_timer_stop(&rport->timer); ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_stop(&rport->timer); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * PLOGI is sent. ++ */ ++static void ++bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_ACCEPTED: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ rport->plogi_retries = 0; ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_fcs_rport_send_logo_acc(rport); ++ bfa_fcxp_discard(rport->fcxp); ++ /* ++ * !! fall through !! ++ */ ++ case RPSM_EVENT_FAILED: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * Ignore SCN - wait for PLOGI response. ++ */ ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * PLOGI is complete. Awaiting BFA rport online callback. FC-4s ++ * are offline. ++ */ ++static void ++bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_HCB_ONLINE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); ++ bfa_fcs_rport_online_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_rport_offline(rport->bfa_rport); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * @todo ++ * Ignore SCN - PLOGI just completed, FC-4 login should detect ++ * device failures. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is ONLINE. FC-4s active. ++ */ ++static void ++bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_SCN: ++ /** ++ * Pause FC-4 activity till rport is authenticated. ++ * In switched fabrics, check presence of device in nameserver ++ * first. ++ */ ++ bfa_fcs_rport_fc4_pause(rport); ++ ++ if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsquery_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } else { ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); ++ bfa_fcs_rport_send_adisc(rport, NULL); ++ } ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ case RPSM_EVENT_LOGO_IMP: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * An SCN event is received in ONLINE state. NS query is being sent ++ * prior to ADISC authentication with rport. FC-4s are paused. ++ */ ++static void ++bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * ignore SCN, wait for response to query itself ++ */ ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * An SCN event is received in ONLINE state. NS query is sent to rport. ++ * FC-4s are paused. ++ */ ++static void ++bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_ACCEPTED: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending); ++ bfa_fcs_rport_send_adisc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_FAILED: ++ rport->ns_retries++; ++ if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsquery_sending); ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } else { ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcs_rport_offline_action(rport); ++ } ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ case RPSM_EVENT_PLOGI_RCVD: ++ case RPSM_EVENT_LOGO_IMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * An SCN event is received in ONLINE state. ADISC is being sent for ++ * authenticating with rport. FC-4s are paused. ++ */ ++static void ++bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * An SCN event is received in ONLINE state. ADISC is to rport. ++ * FC-4s are paused. ++ */ ++static void ++bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_ACCEPTED: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); ++ bfa_fcs_rport_fc4_resume(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ /** ++ * Too complex to cleanup FC-4 & rport and then acc to PLOGI. ++ * At least go offline when a PLOGI is received. ++ */ ++ bfa_fcxp_discard(rport->fcxp); ++ /* ++ * !!! fall through !!! ++ */ ++ ++ case RPSM_EVENT_FAILED: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * already processing RSCN ++ */ ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_offline_action(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport has sent LOGO. Awaiting FC-4 offline completion callback. ++ */ ++static void ++bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FC4_OFFLINE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * LOGO needs to be sent to rport. Awaiting FC-4 offline completion ++ * callback. ++ */ ++static void ++bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FC4_OFFLINE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is going offline. Awaiting FC-4 offline completion callback. ++ */ ++static void ++bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FC4_OFFLINE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); ++ bfa_rport_offline(rport->bfa_rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_LOGO_IMP: ++ case RPSM_EVENT_LOGO_RCVD: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ /** ++ * rport is already going offline. ++ * SCN - ignore and wait till transitioning to offline state ++ */ ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is offline. FC-4s are offline. Awaiting BFA rport offline ++ * callback. ++ */ ++static void ++bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_HCB_OFFLINE: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ if (bfa_fcs_port_is_online(rport->port)) { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } else { ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ } ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_LOGO_RCVD: ++ /** ++ * Ignore, already offline. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is offline. FC-4s are offline. Awaiting BFA rport offline ++ * callback to send LOGO accept. ++ */ ++static void ++bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_HCB_OFFLINE: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ if (rport->pid) ++ bfa_fcs_rport_send_logo_acc(rport); ++ /* ++ * If the lport is online and if the rport is not a well known ++ * address port, we try to re-discover the r-port. ++ */ ++ if (bfa_fcs_port_is_online(rport->port) ++ && (!BFA_FCS_PID_IS_WKA(rport->pid))) { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } else { ++ /* ++ * if it is not a well known address, reset the pid to ++ * ++ */ ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ } ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ /** ++ * Ignore - already processing a LOGO. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is being deleted. FC-4s are offline. Awaiting BFA rport offline ++ * callback to send LOGO. ++ */ ++static void ++bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_HCB_OFFLINE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending); ++ bfa_fcs_rport_send_logo(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is being deleted. FC-4s are offline. LOGO is being sent. ++ */ ++static void ++bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ /* ++ * Once LOGO is sent, we donot wait for the response ++ */ ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport is offline. FC-4s are offline. BFA rport is offline. ++ * Timer active to delete stale rport. ++ */ ++static void ++bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ bfa_timer_stop(&rport->timer); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ case RPSM_EVENT_LOGO_IMP: ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_SEND: ++ bfa_timer_stop(&rport->timer); ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); ++ rport->plogi_retries = 0; ++ bfa_fcs_rport_send_plogi(rport, NULL); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport address has changed. Nameserver discovery request is being sent. ++ */ ++static void ++bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_LOGO_RCVD: ++ case RPSM_EVENT_PLOGI_SEND: ++ break; ++ ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ rport->ns_retries = 0; /* reset the retry count */ ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Nameserver discovery failed. Waiting for timeout to retry. ++ */ ++static void ++bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending); ++ bfa_timer_stop(&rport->timer); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_stop(&rport->timer); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ bfa_fcs_rport_send_logo_acc(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_timer_stop(&rport->timer); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Rport address has changed. Nameserver discovery request is sent. ++ */ ++static void ++bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, ++ enum rport_event event) ++{ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPSM_EVENT_ACCEPTED: ++ case RPSM_EVENT_ADDRESS_CHANGE: ++ if (rport->pid) { ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); ++ bfa_fcs_rport_send_plogi(rport, NULL); ++ } else { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsdisc_sending); ++ rport->ns_retries = 0; ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } ++ break; ++ ++ case RPSM_EVENT_FAILED: ++ rport->ns_retries++; ++ if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) { ++ bfa_sm_set_state(rport, ++ bfa_fcs_rport_sm_nsdisc_sending); ++ bfa_fcs_rport_send_gidpn(rport, NULL); ++ } else { ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ }; ++ break; ++ ++ case RPSM_EVENT_DELETE: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_free(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_RCVD: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_send_plogiacc(rport, NULL); ++ break; ++ ++ case RPSM_EVENT_LOGO_IMP: ++ rport->pid = 0; ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_timer_start(rport->fcs->bfa, &rport->timer, ++ bfa_fcs_rport_timeout, rport, ++ bfa_fcs_rport_del_timeout); ++ break; ++ ++ case RPSM_EVENT_SCN: ++ /** ++ * ignore, wait for NS query response ++ */ ++ break; ++ ++ case RPSM_EVENT_LOGO_RCVD: ++ /** ++ * Not logged-in yet. Accept LOGO. ++ */ ++ bfa_fcs_rport_send_logo_acc(rport); ++ break; ++ ++ case RPSM_EVENT_PLOGI_COMP: ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_fcs_rport_hal_online(rport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * fcs_rport_private FCS RPORT provate functions ++ */ ++ ++static void ++bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, ++ bfa_fcs_rport_send_plogi, rport); ++ return; ++ } ++ rport->fcxp = fcxp; ++ ++ len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response, ++ (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ rport->stats.plogis++; ++ bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ struct fc_logi_s *plogi_rsp; ++ struct fc_ls_rjt_s *ls_rjt; ++ struct bfa_fcs_rport_s *twin; ++ struct list_head *qe; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(rport->fcs, req_status); ++ rport->stats.plogi_failed++; ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++ return; ++ } ++ ++ plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ /** ++ * Check for failure first. ++ */ ++ if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) { ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ bfa_trc(rport->fcs, ls_rjt->reason_code); ++ bfa_trc(rport->fcs, ls_rjt->reason_code_expl); ++ ++ rport->stats.plogi_rejects++; ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++ return; ++ } ++ ++ /** ++ * PLOGI is complete. Make sure this device is not one of the known ++ * device with a new FC port address. ++ */ ++ list_for_each(qe, &rport->port->rport_q) { ++ twin = (struct bfa_fcs_rport_s *)qe; ++ if (twin == rport) ++ continue; ++ if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) { ++ bfa_trc(rport->fcs, twin->pid); ++ bfa_trc(rport->fcs, rport->pid); ++ ++ /* ++ * Update plogi stats in twin ++ */ ++ twin->stats.plogis += rport->stats.plogis; ++ twin->stats.plogi_rejects += rport->stats.plogi_rejects; ++ twin->stats.plogi_timeouts += ++ rport->stats.plogi_timeouts; ++ twin->stats.plogi_failed += rport->stats.plogi_failed; ++ twin->stats.plogi_rcvd += rport->stats.plogi_rcvd; ++ twin->stats.plogi_accs++; ++ ++ bfa_fcs_rport_delete(rport); ++ ++ bfa_fcs_rport_update(twin, plogi_rsp); ++ twin->pid = rsp_fchs->s_id; ++ bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP); ++ return; ++ } ++ } ++ ++ /** ++ * Normal login path -- no evil twins. ++ */ ++ rport->stats.plogi_accs++; ++ bfa_fcs_rport_update(rport, plogi_rsp); ++ bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); ++} ++ ++static void ++bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->reply_oxid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, ++ bfa_fcs_rport_send_plogiacc, rport); ++ return; ++ } ++ rport->fcxp = fcxp; ++ ++ len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), rport->reply_oxid, ++ port->port_cfg.pwwn, port->port_cfg.nwwn, ++ bfa_pport_get_maxfrsize(port->fcs->bfa)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); ++ ++ bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, ++ bfa_fcs_rport_send_adisc, rport); ++ return; ++ } ++ rport->fcxp = fcxp; ++ ++ len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), 0, ++ port->port_cfg.pwwn, port->port_cfg.nwwn); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response, ++ rport, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ rport->stats.adisc_sent++; ++ bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ void *pld = bfa_fcxp_get_rspbuf(fcxp); ++ struct fc_ls_rjt_s *ls_rjt; ++ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(rport->fcs, req_status); ++ rport->stats.adisc_failed++; ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++ return; ++ } ++ ++ if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn, ++ rport->nwwn) == FC_PARSE_OK) { ++ rport->stats.adisc_accs++; ++ bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); ++ return; ++ } ++ ++ rport->stats.adisc_rejects++; ++ ls_rjt = pld; ++ bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code); ++ bfa_trc(rport->fcs, ls_rjt->reason_code); ++ bfa_trc(rport->fcs, ls_rjt->reason_code_expl); ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++} ++ ++static void ++bfa_fcs_rport_send_gidpn(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, ++ bfa_fcs_rport_send_gidpn, rport); ++ return; ++ } ++ rport->fcxp = fcxp; ++ ++ len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_fcs_port_get_fcid(port), 0, rport->pwwn); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_rport_gidpn_response, ++ (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); ++} ++ ++static void ++bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ struct bfa_fcs_rport_s *twin; ++ struct list_head *qe; ++ struct ct_hdr_s *cthdr; ++ struct fcgs_gidpn_resp_s *gidpn_rsp; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ ++ cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); ++ cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); ++ ++ if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { ++ /* ++ * Check if the pid is the same as before. ++ */ ++ gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1); ++ ++ if (gidpn_rsp->dap == rport->pid) { ++ /* ++ * Device is online ++ */ ++ bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED); ++ } else { ++ /* ++ * Device's PID has changed. We need to cleanup and ++ * re-login. If there is another device with the the ++ * newly discovered pid, send an scn notice so that its ++ * new pid can be discovered. ++ */ ++ list_for_each(qe, &rport->port->rport_q) { ++ twin = (struct bfa_fcs_rport_s *)qe; ++ if (twin == rport) ++ continue; ++ if (gidpn_rsp->dap == twin->pid) { ++ bfa_trc(rport->fcs, twin->pid); ++ bfa_trc(rport->fcs, rport->pid); ++ ++ twin->pid = 0; ++ bfa_sm_send_event(twin, ++ RPSM_EVENT_ADDRESS_CHANGE); ++ } ++ } ++ rport->pid = gidpn_rsp->dap; ++ bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE); ++ } ++ return; ++ } ++ ++ /* ++ * Reject Response ++ */ ++ switch (cthdr->reason_code) { ++ case CT_RSN_LOGICAL_BUSY: ++ /* ++ * Need to retry ++ */ ++ bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); ++ break; ++ ++ case CT_RSN_UNABLE_TO_PERF: ++ /* ++ * device doesn't exist : Start timer to cleanup this later. ++ */ ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++ break; ++ ++ default: ++ bfa_sm_send_event(rport, RPSM_EVENT_FAILED); ++ break; ++ } ++} ++ ++/** ++ * Called to send a logout to the rport. ++ */ ++static void ++bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ u16 len; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ ++ port = rport->port; ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe, ++ bfa_fcs_rport_send_logo, rport); ++ return; ++ } ++ rport->fcxp = fcxp; ++ ++ len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), 0, ++ bfa_fcs_port_get_pwwn(port)); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, rport, FC_MAX_PDUSZ, ++ FC_ED_TOV); ++ ++ rport->stats.logos++; ++ bfa_fcxp_discard(rport->fcxp); ++ bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT); ++} ++ ++/** ++ * Send ACC for a LOGO received. ++ */ ++static void ++bfa_fcs_rport_send_logo_acc(void *rport_cbarg) ++{ ++ struct bfa_fcs_rport_s *rport = rport_cbarg; ++ struct bfa_fcs_port_s *port; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ u16 len; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ ++ port = rport->port; ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ rport->stats.logo_rcvd++; ++ len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), rport->reply_oxid); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); ++} ++ ++/** ++ * This routine will be called by bfa_timer on timer timeouts. ++ * ++ * param[in] rport - pointer to bfa_fcs_port_ns_t. ++ * param[out] rport_status - pointer to return vport status in ++ * ++ * return ++ * void ++ * ++* Special Considerations: ++ * ++ * note ++ */ ++static void ++bfa_fcs_rport_timeout(void *arg) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)arg; ++ ++ rport->stats.plogi_timeouts++; ++ bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT); ++} ++ ++static void ++bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u16 len) ++{ ++ struct bfa_fcxp_s *fcxp; ++ struct fchs_s fchs; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fc_prli_s *prli; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ ++ rport->stats.prli_rcvd++; ++ ++ if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) { ++ /* ++ * Target Mode : Let the fcptm handle it ++ */ ++ bfa_fcs_tin_rx_prli(rport->tin, rx_fchs, len); ++ return; ++ } ++ ++ /* ++ * We are either in Initiator or ipfc Mode ++ */ ++ prli = (struct fc_prli_s *) (rx_fchs + 1); ++ ++ if (prli->parampage.servparams.initiator) { ++ bfa_trc(rport->fcs, prli->parampage.type); ++ rport->scsi_function = BFA_RPORT_INITIATOR; ++ bfa_fcs_itnim_is_initiator(rport->itnim); ++ } else { ++ /* ++ * @todo: PRLI from a target ? ++ */ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ rport->scsi_function = BFA_RPORT_TARGET; ++ } ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id, ++ port->port_cfg.roles); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); ++} ++ ++static void ++bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u16 len) ++{ ++ struct bfa_fcxp_s *fcxp; ++ struct fchs_s fchs; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fc_rpsc_speed_info_s speeds; ++ struct bfa_pport_attr_s pport_attr; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ ++ rport->stats.rpsc_rcvd++; ++ speeds.port_speed_cap = ++ RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G | ++ RPSC_SPEED_CAP_8G; ++ ++ /* ++ * get curent speed from pport attributes from BFA ++ */ ++ bfa_pport_get_attr(port->fcs->bfa, &pport_attr); ++ ++ speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed); ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id, ++ &speeds); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); ++} ++ ++static void ++bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, ++ struct fchs_s *rx_fchs, u16 len) ++{ ++ struct bfa_fcxp_s *fcxp; ++ struct fchs_s fchs; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fc_adisc_s *adisc; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ ++ rport->stats.adisc_rcvd++; ++ ++ if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) { ++ /* ++ * @todo : Target Mode handling ++ */ ++ bfa_trc(port->fcs, rx_fchs->d_id); ++ bfa_assert(0); ++ return; ++ } ++ ++ adisc = (struct fc_adisc_s *) (rx_fchs + 1); ++ ++ /* ++ * Accept if the itnim for this rport is online. Else reject the ADISC ++ */ ++ if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) { ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), ++ rx_fchs->ox_id, port->port_cfg.pwwn, ++ port->port_cfg.nwwn); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, ++ FC_MAX_PDUSZ, 0); ++ } else { ++ rport->stats.adisc_rejected++; ++ bfa_fcs_rport_send_ls_rjt(rport, rx_fchs, ++ FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD, ++ FC_LS_RJT_EXP_LOGIN_REQUIRED); ++ } ++ ++} ++ ++static void ++bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ struct bfa_rport_info_s rport_info; ++ ++ rport_info.pid = rport->pid; ++ rport_info.local_pid = port->pid; ++ rport_info.lp_tag = port->lp_tag; ++ rport_info.vf_id = port->fabric->vf_id; ++ rport_info.vf_en = port->fabric->is_vf; ++ rport_info.fc_class = rport->fc_cos; ++ rport_info.cisc = rport->cisc; ++ rport_info.max_frmsz = rport->maxfrsize; ++ bfa_rport_online(rport->bfa_rport, &rport_info); ++} ++ ++static void ++bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport) ++{ ++ if (bfa_fcs_port_is_initiator(rport->port)) ++ bfa_fcs_itnim_pause(rport->itnim); ++ ++ if (bfa_fcs_port_is_target(rport->port)) ++ bfa_fcs_tin_pause(rport->tin); ++} ++ ++static void ++bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport) ++{ ++ if (bfa_fcs_port_is_initiator(rport->port)) ++ bfa_fcs_itnim_resume(rport->itnim); ++ ++ if (bfa_fcs_port_is_target(rport->port)) ++ bfa_fcs_tin_resume(rport->tin); ++} ++ ++static struct bfa_fcs_rport_s * ++bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port, wwn_t pwwn, u32 rpid) ++{ ++ struct bfa_fcs_s *fcs = port->fcs; ++ struct bfa_fcs_rport_s *rport; ++ struct bfad_rport_s *rport_drv; ++ ++ /** ++ * allocate rport ++ */ ++ if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv) ++ != BFA_STATUS_OK) { ++ bfa_trc(fcs, rpid); ++ return NULL; ++ } ++ ++ /* ++ * Initialize r-port ++ */ ++ rport->port = port; ++ rport->fcs = fcs; ++ rport->rp_drv = rport_drv; ++ rport->pid = rpid; ++ rport->pwwn = pwwn; ++ ++ /** ++ * allocate BFA rport ++ */ ++ rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport); ++ if (!rport->bfa_rport) { ++ bfa_trc(fcs, rpid); ++ kfree(rport_drv); ++ return NULL; ++ } ++ ++ /** ++ * allocate FC-4s ++ */ ++ bfa_assert(bfa_fcs_port_is_initiator(port) ^ ++ bfa_fcs_port_is_target(port)); ++ ++ if (bfa_fcs_port_is_initiator(port)) { ++ rport->itnim = bfa_fcs_itnim_create(rport); ++ if (!rport->itnim) { ++ bfa_trc(fcs, rpid); ++ bfa_rport_delete(rport->bfa_rport); ++ kfree(rport_drv); ++ return NULL; ++ } ++ } ++ ++ if (bfa_fcs_port_is_target(port)) { ++ rport->tin = bfa_fcs_tin_create(rport); ++ if (!rport->tin) { ++ bfa_trc(fcs, rpid); ++ bfa_rport_delete(rport->bfa_rport); ++ kfree(rport_drv); ++ return NULL; ++ } ++ } ++ ++ bfa_fcs_port_add_rport(port, rport); ++ ++ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); ++ ++ /* ++ * Initialize the Rport Features(RPF) Sub Module ++ */ ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) ++ bfa_fcs_rpf_init(rport); ++ ++ return rport; ++} ++ ++ ++static void ++bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ ++ /** ++ * - delete FC-4s ++ * - delete BFA rport ++ * - remove from queue of rports ++ */ ++ if (bfa_fcs_port_is_initiator(port)) ++ bfa_fcs_itnim_delete(rport->itnim); ++ ++ if (bfa_fcs_port_is_target(port)) ++ bfa_fcs_tin_delete(rport->tin); ++ ++ bfa_rport_delete(rport->bfa_rport); ++ bfa_fcs_port_del_rport(port, rport); ++ kfree(rport->rp_drv); ++} ++ ++static void ++bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport, ++ enum bfa_rport_aen_event event, ++ struct bfa_rport_aen_data_s *data) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = rport->fcs->logm; ++ wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port); ++ wwn_t rpwwn = rport->pwwn; ++ char lpwwn_ptr[BFA_STRING_32]; ++ char rpwwn_ptr[BFA_STRING_32]; ++ char *prio_str[] = { "unknown", "high", "medium", "low" }; ++ ++ wwn2str(lpwwn_ptr, lpwwn); ++ wwn2str(rpwwn_ptr, rpwwn); ++ ++ switch (event) { ++ case BFA_RPORT_AEN_ONLINE: ++ bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_RPORT_AEN_OFFLINE: ++ bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_RPORT_AEN_DISCONNECT: ++ bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_RPORT_AEN_QOS_PRIO: ++ aen_data.rport.priv.qos = data->priv.qos; ++ bfa_log(logmod, BFA_AEN_RPORT_QOS_PRIO, ++ prio_str[aen_data.rport.priv.qos.qos_priority], ++ rpwwn_ptr, lpwwn_ptr); ++ break; ++ case BFA_RPORT_AEN_QOS_FLOWID: ++ aen_data.rport.priv.qos = data->priv.qos; ++ bfa_log(logmod, BFA_AEN_RPORT_QOS_FLOWID, ++ aen_data.rport.priv.qos.qos_flow_id, rpwwn_ptr, ++ lpwwn_ptr); ++ break; ++ default: ++ break; ++ } ++ ++ aen_data.rport.vf_id = rport->port->fabric->vf_id; ++ aen_data.rport.ppwwn = ++ bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(rport->fcs)); ++ aen_data.rport.lpwwn = lpwwn; ++ aen_data.rport.rpwwn = rpwwn; ++} ++ ++static void ++bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ ++ rport->stats.onlines++; ++ ++ if (bfa_fcs_port_is_initiator(port)) { ++ bfa_fcs_itnim_rport_online(rport->itnim); ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) ++ bfa_fcs_rpf_rport_online(rport); ++ }; ++ ++ if (bfa_fcs_port_is_target(port)) ++ bfa_fcs_tin_rport_online(rport->tin); ++ ++ /* ++ * Don't post events for well known addresses ++ */ ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) ++ bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL); ++} ++ ++static void ++bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ ++ rport->stats.offlines++; ++ ++ /* ++ * Don't post events for well known addresses ++ */ ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) { ++ if (bfa_fcs_port_is_online(rport->port) == BFA_TRUE) { ++ bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_DISCONNECT, ++ NULL); ++ } else { ++ bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_OFFLINE, ++ NULL); ++ } ++ } ++ ++ if (bfa_fcs_port_is_initiator(port)) { ++ bfa_fcs_itnim_rport_offline(rport->itnim); ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) ++ bfa_fcs_rpf_rport_offline(rport); ++ } ++ ++ if (bfa_fcs_port_is_target(port)) ++ bfa_fcs_tin_rport_offline(rport->tin); ++} ++ ++/** ++ * Update rport parameters from PLOGI or PLOGI accept. ++ */ ++static void ++bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ ++ /** ++ * - port name ++ * - node name ++ */ ++ rport->pwwn = plogi->port_name; ++ rport->nwwn = plogi->node_name; ++ ++ /** ++ * - class of service ++ */ ++ rport->fc_cos = 0; ++ if (plogi->class3.class_valid) ++ rport->fc_cos = FC_CLASS_3; ++ ++ if (plogi->class2.class_valid) ++ rport->fc_cos |= FC_CLASS_2; ++ ++ /** ++ * - CISC ++ * - MAX receive frame size ++ */ ++ rport->cisc = plogi->csp.cisc; ++ rport->maxfrsize = bfa_os_ntohs(plogi->class3.rxsz); ++ ++ bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred)); ++ bfa_trc(port->fcs, port->fabric->bb_credit); ++ /** ++ * Direct Attach P2P mode : ++ * This is to handle a bug (233476) in IBM targets in Direct Attach ++ * Mode. Basically, in FLOGI Accept the target would have erroneously ++ * set the BB Credit to the value used in the FLOGI sent by the HBA. ++ * It uses the correct value (its own BB credit) in PLOGI. ++ */ ++ if ((!bfa_fcs_fabric_is_switched(port->fabric)) ++ && (bfa_os_ntohs(plogi->csp.bbcred) < port->fabric->bb_credit)) { ++ ++ bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred)); ++ bfa_trc(port->fcs, port->fabric->bb_credit); ++ ++ port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred); ++ bfa_pport_set_tx_bbcredit(port->fcs->bfa, ++ port->fabric->bb_credit); ++ } ++ ++} ++ ++/** ++ * Called to handle LOGO received from an existing remote port. ++ */ ++static void ++bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs) ++{ ++ rport->reply_oxid = fchs->ox_id; ++ bfa_trc(rport->fcs, rport->reply_oxid); ++ ++ rport->stats.logo_rcvd++; ++ bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD); ++} ++ ++ ++ ++/** ++ * fcs_rport_public FCS rport public interfaces ++ */ ++ ++/** ++ * Called by bport/vport to create a remote port instance for a discovered ++ * remote device. ++ * ++ * @param[in] port - base port or vport ++ * @param[in] rpid - remote port ID ++ * ++ * @return None ++ */ ++struct bfa_fcs_rport_s * ++bfa_fcs_rport_create(struct bfa_fcs_port_s *port, u32 rpid) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, rpid); ++ rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid); ++ if (!rport) ++ return NULL; ++ ++ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); ++ return rport; ++} ++ ++/** ++ * Called to create a rport for which only the wwn is known. ++ * ++ * @param[in] port - base port ++ * @param[in] rpwwn - remote port wwn ++ * ++ * @return None ++ */ ++struct bfa_fcs_rport_s * ++bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port, wwn_t rpwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, rpwwn); ++ rport = bfa_fcs_rport_alloc(port, rpwwn, 0); ++ if (!rport) ++ return NULL; ++ ++ bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC); ++ return rport; ++} ++ ++/** ++ * Called by bport in private loop topology to indicate that a ++ * rport has been discovered and plogi has been completed. ++ * ++ * @param[in] port - base port or vport ++ * @param[in] rpid - remote port ID ++ */ ++void ++bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *fchs, ++ struct fc_logi_s *plogi) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id); ++ if (!rport) ++ return; ++ ++ bfa_fcs_rport_update(rport, plogi); ++ ++ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP); ++} ++ ++/** ++ * Called by bport/vport to handle PLOGI received from a new remote port. ++ * If an existing rport does a plogi, it will be handled separately. ++ */ ++void ++bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port, struct fchs_s *fchs, ++ struct fc_logi_s *plogi) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); ++ if (!rport) ++ return; ++ ++ bfa_fcs_rport_update(rport, plogi); ++ ++ rport->reply_oxid = fchs->ox_id; ++ bfa_trc(rport->fcs, rport->reply_oxid); ++ ++ rport->stats.plogi_rcvd++; ++ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); ++} ++ ++static int ++wwn_compare(wwn_t wwn1, wwn_t wwn2) ++{ ++ u8 *b1 = (u8 *) &wwn1; ++ u8 *b2 = (u8 *) &wwn2; ++ int i; ++ ++ for (i = 0; i < sizeof(wwn_t); i++) { ++ if (b1[i] < b2[i]) ++ return -1; ++ if (b1[i] > b2[i]) ++ return 1; ++ } ++ return 0; ++} ++ ++/** ++ * Called by bport/vport to handle PLOGI received from an existing ++ * remote port. ++ */ ++void ++bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, ++ struct fc_logi_s *plogi) ++{ ++ /** ++ * @todo Handle P2P and initiator-initiator. ++ */ ++ ++ bfa_fcs_rport_update(rport, plogi); ++ ++ rport->reply_oxid = rx_fchs->ox_id; ++ bfa_trc(rport->fcs, rport->reply_oxid); ++ ++ /** ++ * In Switched fabric topology, ++ * PLOGI to each other. If our pwwn is smaller, ignore it, ++ * if it is not a well known address. ++ * If the link topology is N2N, ++ * this Plogi should be accepted. ++ */ ++ if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1) ++ && (bfa_fcs_fabric_is_switched(rport->port->fabric)) ++ && (!BFA_FCS_PID_IS_WKA(rport->pid))) { ++ bfa_trc(rport->fcs, rport->pid); ++ return; ++ } ++ ++ rport->stats.plogi_rcvd++; ++ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); ++} ++ ++/** ++ * Called by bport/vport to delete a remote port instance. ++ * ++* Rport delete is called under the following conditions: ++ * - vport is deleted ++ * - vf is deleted ++ * - explicit request from OS to delete rport (vmware) ++ */ ++void ++bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_DELETE); ++} ++ ++/** ++ * Called by bport/vport to when a target goes offline. ++ * ++ */ ++void ++bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); ++} ++ ++/** ++ * Called by bport in n2n when a target (attached port) becomes online. ++ * ++ */ ++void ++bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND); ++} ++ ++/** ++ * Called by bport/vport to notify SCN for the remote port ++ */ ++void ++bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport) ++{ ++ ++ rport->stats.rscns++; ++ bfa_sm_send_event(rport, RPSM_EVENT_SCN); ++} ++ ++/** ++ * Called by fcpim to notify that the ITN cleanup is done. ++ */ ++void ++bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE); ++} ++ ++/** ++ * Called by fcptm to notify that the ITN cleanup is done. ++ */ ++void ++bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE); ++} ++ ++/** ++ * This routine BFA callback for bfa_rport_online() call. ++ * ++ * param[in] cb_arg - rport struct. ++ * ++ * return ++ * void ++ * ++* Special Considerations: ++ * ++ * note ++ */ ++void ++bfa_cb_rport_online(void *cbarg) ++{ ++ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE); ++} ++ ++/** ++ * This routine BFA callback for bfa_rport_offline() call. ++ * ++ * param[in] rport - ++ * ++ * return ++ * void ++ * ++ * Special Considerations: ++ * ++ * note ++ */ ++void ++bfa_cb_rport_offline(void *cbarg) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE); ++} ++ ++/** ++ * This routine is a static BFA callback when there is a QoS flow_id ++ * change notification ++ * ++ * @param[in] rport - ++ * ++ * @return void ++ * ++ * Special Considerations: ++ * ++ * @note ++ */ ++void ++bfa_cb_rport_qos_scn_flowid(void *cbarg, ++ struct bfa_rport_qos_attr_s old_qos_attr, ++ struct bfa_rport_qos_attr_s new_qos_attr) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ struct bfa_rport_aen_data_s aen_data; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ aen_data.priv.qos = new_qos_attr; ++ bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data); ++} ++ ++/** ++ * This routine is a static BFA callback when there is a QoS priority ++ * change notification ++ * ++ * @param[in] rport - ++ * ++ * @return void ++ * ++ * Special Considerations: ++ * ++ * @note ++ */ ++void ++bfa_cb_rport_qos_scn_prio(void *cbarg, struct bfa_rport_qos_attr_s old_qos_attr, ++ struct bfa_rport_qos_attr_s new_qos_attr) ++{ ++ struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg; ++ struct bfa_rport_aen_data_s aen_data; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ aen_data.priv.qos = new_qos_attr; ++ bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data); ++} ++ ++/** ++ * Called to process any unsolicted frames from this remote port ++ */ ++void ++bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP); ++} ++ ++/** ++ * Called to process any unsolicted frames from this remote port ++ */ ++void ++bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, ++ u16 len) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fc_els_cmd_s *els_cmd; ++ ++ bfa_trc(rport->fcs, fchs->s_id); ++ bfa_trc(rport->fcs, fchs->d_id); ++ bfa_trc(rport->fcs, fchs->type); ++ ++ if (fchs->type != FC_TYPE_ELS) ++ return; ++ ++ els_cmd = (struct fc_els_cmd_s *) (fchs + 1); ++ ++ bfa_trc(rport->fcs, els_cmd->els_code); ++ ++ switch (els_cmd->els_code) { ++ case FC_ELS_LOGO: ++ bfa_fcs_rport_process_logo(rport, fchs); ++ break; ++ ++ case FC_ELS_ADISC: ++ bfa_fcs_rport_process_adisc(rport, fchs, len); ++ break; ++ ++ case FC_ELS_PRLO: ++ if (bfa_fcs_port_is_initiator(port)) ++ bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len); ++ ++ if (bfa_fcs_port_is_target(port)) ++ bfa_fcs_fcptm_uf_recv(rport->tin, fchs, len); ++ break; ++ ++ case FC_ELS_PRLI: ++ bfa_fcs_rport_process_prli(rport, fchs, len); ++ break; ++ ++ case FC_ELS_RPSC: ++ bfa_fcs_rport_process_rpsc(rport, fchs, len); ++ break; ++ ++ default: ++ bfa_fcs_rport_send_ls_rjt(rport, fchs, ++ FC_LS_RJT_RSN_CMD_NOT_SUPP, ++ FC_LS_RJT_EXP_NO_ADDL_INFO); ++ break; ++ } ++} ++ ++/* ++ * Send a LS reject ++ */ ++static void ++bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, ++ u8 reason_code, u8 reason_code_expl) ++{ ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ int len; ++ ++ bfa_trc(rport->fcs, rx_fchs->s_id); ++ ++ fcxp = bfa_fcs_fcxp_alloc(rport->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id, ++ reason_code, reason_code_expl); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); ++} ++ ++/** ++ * Module initialization ++ */ ++void ++bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs) ++{ ++} ++ ++/** ++ * Module cleanup ++ */ ++void ++bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} ++ ++/** ++ * Return state of rport. ++ */ ++int ++bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport) ++{ ++ return bfa_sm_to_state(rport_sm_table, rport->sm); ++} ++ ++/** ++ * Called by the Driver to set rport delete/ageout timeout ++ * ++ * param[in] rport timeout value in seconds. ++ * ++ * return None ++ */ ++void ++bfa_fcs_rport_set_del_timeout(u8 rport_tmo) ++{ ++ /* ++ * convert to Millisecs ++ */ ++ if (rport_tmo > 0) ++ bfa_fcs_rport_del_timeout = rport_tmo * 1000; ++} +diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c +new file mode 100644 +index 0000000..3dae177 +--- /dev/null ++++ b/drivers/scsi/bfa/rport_api.c +@@ -0,0 +1,180 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++#include ++#include ++#include "fcs_vport.h" ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_trcmod.h" ++ ++BFA_TRC_FILE(FCS, RPORT_API); ++ ++/** ++ * rport_api.c Remote port implementation. ++ */ ++ ++/** ++ * fcs_rport_api FCS rport API. ++ */ ++ ++/** ++ * Direct API to add a target by port wwn. This interface is used, for ++ * example, by bios when target pwwn is known from boot lun configuration. ++ */ ++bfa_status_t ++bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn, ++ struct bfa_fcs_rport_s *rport, ++ struct bfad_rport_s *rport_drv) ++{ ++ bfa_trc(port->fcs, *pwwn); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Direct API to remove a target and its associated resources. This ++ * interface is used, for example, by vmware driver to remove target ++ * ports from the target list for a VM. ++ */ ++bfa_status_t ++bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in) ++{ ++ ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(rport_in->fcs, rport_in->pwwn); ++ ++ rport = bfa_fcs_port_get_rport_by_pwwn(rport_in->port, rport_in->pwwn); ++ if (rport == NULL) { ++ /* ++ * TBD Error handling ++ */ ++ bfa_trc(rport_in->fcs, rport_in->pid); ++ return BFA_STATUS_UNKNOWN_RWWN; ++ } ++ ++ /* ++ * TBD if this remote port is online, send a logo ++ */ ++ return BFA_STATUS_OK; ++ ++} ++ ++/** ++ * Remote device status for display/debug. ++ */ ++void ++bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, ++ struct bfa_rport_attr_s *rport_attr) ++{ ++ struct bfa_rport_qos_attr_s qos_attr; ++ struct bfa_fcs_port_s *port = rport->port; ++ ++ bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s)); ++ ++ rport_attr->pid = rport->pid; ++ rport_attr->pwwn = rport->pwwn; ++ rport_attr->nwwn = rport->nwwn; ++ rport_attr->cos_supported = rport->fc_cos; ++ rport_attr->df_sz = rport->maxfrsize; ++ rport_attr->state = bfa_fcs_rport_get_state(rport); ++ rport_attr->fc_cos = rport->fc_cos; ++ rport_attr->cisc = rport->cisc; ++ rport_attr->scsi_function = rport->scsi_function; ++ rport_attr->curr_speed = rport->rpf.rpsc_speed; ++ rport_attr->assigned_speed = rport->rpf.assigned_speed; ++ ++ bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr); ++ rport_attr->qos_attr = qos_attr; ++ ++ rport_attr->trl_enforced = BFA_FALSE; ++ if (bfa_pport_is_ratelim(port->fcs->bfa)) { ++ if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) || ++ (rport->rpf.rpsc_speed < ++ bfa_fcs_port_get_rport_max_speed(port))) ++ rport_attr->trl_enforced = BFA_TRUE; ++ } ++ ++ /* ++ * TODO ++ * rport->symname ++ */ ++} ++ ++/** ++ * Per remote device statistics. ++ */ ++void ++bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport, ++ struct bfa_rport_stats_s *stats) ++{ ++ *stats = rport->stats; ++} ++ ++void ++bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_os_memset((char *)&rport->stats, 0, ++ sizeof(struct bfa_rport_stats_s)); ++} ++ ++struct bfa_fcs_rport_s * ++bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ rport = bfa_fcs_port_get_rport_by_pwwn(port, rpwwn); ++ if (rport == NULL) { ++ /* ++ * TBD Error handling ++ */ ++ } ++ ++ return rport; ++} ++ ++struct bfa_fcs_rport_s * ++bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_port_s *port, wwn_t rnwwn) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ rport = bfa_fcs_port_get_rport_by_nwwn(port, rnwwn); ++ if (rport == NULL) { ++ /* ++ * TBD Error handling ++ */ ++ } ++ ++ return rport; ++} ++ ++/* ++ * This API is to set the Rport's speed. Should be used when RPSC is not ++ * supported by the rport. ++ */ ++void ++bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, ++ enum bfa_pport_speed speed) ++{ ++ rport->rpf.assigned_speed = speed; ++ ++ /* Set this speed in f/w only if the RPSC speed is not available */ ++ if (rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ++ bfa_rport_speed(rport->bfa_rport, speed); ++} ++ ++ +diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c +new file mode 100644 +index 0000000..8a1f59d +--- /dev/null ++++ b/drivers/scsi/bfa/rport_ftrs.c +@@ -0,0 +1,375 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * rport_ftrs.c Remote port features (RPF) implementation. ++ */ ++ ++#include ++#include ++#include "fcbuild.h" ++#include "fcs_rport.h" ++#include "fcs_lport.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs.h" ++ ++BFA_TRC_FILE(FCS, RPORT_FTRS); ++ ++#define BFA_FCS_RPF_RETRIES (3) ++#define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */ ++ ++static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_rpf_timeout(void *arg); ++ ++/** ++ * fcs_rport_ftrs_sm FCS rport state machine events ++ */ ++ ++enum rpf_event { ++ RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */ ++ RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */ ++ RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */ ++ RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */ ++ RPFSM_EVENT_RPSC_COMP = 5, ++ RPFSM_EVENT_RPSC_FAIL = 6, ++ RPFSM_EVENT_RPSC_ERROR = 7, ++}; ++ ++static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, ++ enum rpf_event event); ++ ++static void ++bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_RPORT_ONLINE : ++ if (!BFA_FCS_PID_IS_WKA(rport->pid)) { ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); ++ rpf->rpsc_retries = 0; ++ bfa_fcs_rpf_send_rpsc2(rpf, NULL); ++ break; ++ }; ++ ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_FCXP_SENT: ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc); ++ break; ++ ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); ++ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe); ++ rpf->rpsc_retries = 0; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_RPSC_COMP: ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); ++ /* Update speed info in f/w via BFA */ ++ if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) { ++ bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed); ++ } else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) { ++ bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed); ++ } ++ break; ++ ++ case RPFSM_EVENT_RPSC_FAIL: ++ /* RPSC not supported by rport */ ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); ++ break; ++ ++ case RPFSM_EVENT_RPSC_ERROR: ++ /* need to retry...delayed a bit. */ ++ if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) { ++ bfa_timer_start(rport->fcs->bfa, &rpf->timer, ++ bfa_fcs_rpf_timeout, rpf, ++ BFA_FCS_RPF_RETRY_TIMEOUT); ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry); ++ } else { ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online); ++ } ++ break; ++ ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); ++ bfa_fcxp_discard(rpf->fcxp); ++ rpf->rpsc_retries = 0; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_TIMEOUT : ++ /* re-send the RPSC */ ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); ++ bfa_fcs_rpf_send_rpsc2(rpf, NULL); ++ break; ++ ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ bfa_timer_stop(&rpf->timer); ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); ++ rpf->rpsc_retries = 0; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline); ++ rpf->rpsc_retries = 0; ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event) ++{ ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_trc(rport->fcs, event); ++ ++ switch (event) { ++ case RPFSM_EVENT_RPORT_ONLINE : ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending); ++ bfa_fcs_rpf_send_rpsc2(rpf, NULL); ++ break; ++ ++ case RPFSM_EVENT_RPORT_OFFLINE : ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++/** ++ * Called when Rport is created. ++ */ ++void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport) ++{ ++ struct bfa_fcs_rpf_s *rpf = &rport->rpf; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ rpf->rport = rport; ++ ++ bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit); ++} ++ ++/** ++ * Called when Rport becomes online ++ */ ++void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_trc(rport->fcs, rport->pid); ++ ++ if (__fcs_min_cfg(rport->port->fcs)) ++ return; ++ ++ if (bfa_fcs_fabric_is_switched(rport->port->fabric)) ++ bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE); ++} ++ ++/** ++ * Called when Rport becomes offline ++ */ ++void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport) ++{ ++ bfa_trc(rport->fcs, rport->pid); ++ ++ if (__fcs_min_cfg(rport->port->fcs)) ++ return; ++ ++ bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE); ++} ++ ++static void ++bfa_fcs_rpf_timeout(void *arg) ++{ ++ struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg; ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ ++ bfa_trc(rport->fcs, rport->pid); ++ bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT); ++} ++ ++static void ++bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ struct bfa_fcs_port_s *port = rport->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(rport->fcs, rport->pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, ++ bfa_fcs_rpf_send_rpsc2, rpf); ++ return; ++ } ++ rpf->fcxp = fcxp; ++ ++ len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, ++ bfa_fcs_port_get_fcid(port), &rport->pid, 1); ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, ++ rpf, FC_MAX_PDUSZ, FC_RA_TOV); ++ rport->stats.rpsc_sent++; ++ bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); ++ ++} ++ ++static void ++bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, ++ bfa_status_t req_status, u32 rsp_len, ++ u32 resid_len, struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; ++ struct bfa_fcs_rport_s *rport = rpf->rport; ++ struct fc_ls_rjt_s *ls_rjt; ++ struct fc_rpsc2_acc_s *rpsc2_acc; ++ u16 num_ents; ++ ++ bfa_trc(rport->fcs, req_status); ++ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(rport->fcs, req_status); ++ if (req_status == BFA_STATUS_ETIMER) ++ rport->stats.rpsc_failed++; ++ bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); ++ return; ++ } ++ ++ rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); ++ if (rpsc2_acc->els_cmd == FC_ELS_ACC) { ++ rport->stats.rpsc_accs++; ++ num_ents = bfa_os_ntohs(rpsc2_acc->num_pids); ++ bfa_trc(rport->fcs, num_ents); ++ if (num_ents > 0) { ++ bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid); ++ bfa_trc(rport->fcs, ++ bfa_os_ntohs(rpsc2_acc->port_info[0].pid)); ++ bfa_trc(rport->fcs, ++ bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); ++ bfa_trc(rport->fcs, ++ bfa_os_ntohs(rpsc2_acc->port_info[0].index)); ++ bfa_trc(rport->fcs, ++ rpsc2_acc->port_info[0].type); ++ ++ if (rpsc2_acc->port_info[0].speed == 0) { ++ bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); ++ return; ++ } ++ ++ rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( ++ bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); ++ ++ bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); ++ } ++ } else { ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ bfa_trc(rport->fcs, ls_rjt->reason_code); ++ bfa_trc(rport->fcs, ls_rjt->reason_code_expl); ++ rport->stats.rpsc_rejects++; ++ if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) { ++ bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); ++ } else { ++ bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); ++ } ++ } ++} +diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c +new file mode 100644 +index 0000000..bd4771f +--- /dev/null ++++ b/drivers/scsi/bfa/scn.c +@@ -0,0 +1,482 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++#include ++#include ++#include "fcs_lport.h" ++#include "fcs_rport.h" ++#include "fcs_ms.h" ++#include "fcs_trcmod.h" ++#include "fcs_fcxp.h" ++#include "fcs.h" ++#include "lport_priv.h" ++ ++BFA_TRC_FILE(FCS, SCN); ++ ++#define FC_QOS_RSCN_EVENT 0x0c ++#define FC_FABRIC_NAME_RSCN_EVENT 0x0d ++ ++/* ++ * forward declarations ++ */ ++static void bfa_fcs_port_scn_send_scr(void *scn_cbarg, ++ struct bfa_fcxp_s *fcxp_alloced); ++static void bfa_fcs_port_scn_scr_response(void *fcsarg, ++ struct bfa_fcxp_s *fcxp, ++ void *cbarg, ++ bfa_status_t req_status, ++ u32 rsp_len, ++ u32 resid_len, ++ struct fchs_s *rsp_fchs); ++static void bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs); ++static void bfa_fcs_port_scn_timeout(void *arg); ++ ++/** ++ * fcs_scm_sm FCS SCN state machine ++ */ ++ ++/** ++ * VPort SCN State Machine events ++ */ ++enum port_scn_event { ++ SCNSM_EVENT_PORT_ONLINE = 1, ++ SCNSM_EVENT_PORT_OFFLINE = 2, ++ SCNSM_EVENT_RSP_OK = 3, ++ SCNSM_EVENT_RSP_ERROR = 4, ++ SCNSM_EVENT_TIMEOUT = 5, ++ SCNSM_EVENT_SCR_SENT = 6, ++}; ++ ++static void bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event); ++static void bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event); ++static void bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event); ++static void bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event); ++static void bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event); ++ ++/** ++ * Starting state - awaiting link up. ++ */ ++static void ++bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event) ++{ ++ switch (event) { ++ case SCNSM_EVENT_PORT_ONLINE: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr); ++ bfa_fcs_port_scn_send_scr(scn, NULL); ++ break; ++ ++ case SCNSM_EVENT_PORT_OFFLINE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event) ++{ ++ switch (event) { ++ case SCNSM_EVENT_SCR_SENT: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr); ++ break; ++ ++ case SCNSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline); ++ bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event) ++{ ++ struct bfa_fcs_port_s *port = scn->port; ++ ++ switch (event) { ++ case SCNSM_EVENT_RSP_OK: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_online); ++ break; ++ ++ case SCNSM_EVENT_RSP_ERROR: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr_retry); ++ bfa_timer_start(port->fcs->bfa, &scn->timer, ++ bfa_fcs_port_scn_timeout, scn, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case SCNSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline); ++ bfa_fcxp_discard(scn->fcxp); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event) ++{ ++ switch (event) { ++ case SCNSM_EVENT_TIMEOUT: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr); ++ bfa_fcs_port_scn_send_scr(scn, NULL); ++ break; ++ ++ case SCNSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline); ++ bfa_timer_stop(&scn->timer); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++static void ++bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn, ++ enum port_scn_event event) ++{ ++ switch (event) { ++ case SCNSM_EVENT_PORT_OFFLINE: ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * fcs_scn_private FCS SCN private functions ++ */ ++ ++/** ++ * This routine will be called to send a SCR command. ++ */ ++static void ++bfa_fcs_port_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced) ++{ ++ struct bfa_fcs_port_scn_s *scn = scn_cbarg; ++ struct bfa_fcs_port_s *port = scn->port; ++ struct fchs_s fchs; ++ int len; ++ struct bfa_fcxp_s *fcxp; ++ ++ bfa_trc(port->fcs, port->pid); ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) { ++ bfa_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe, ++ bfa_fcs_port_scn_send_scr, scn); ++ return; ++ } ++ scn->fcxp = fcxp; ++ ++ /* ++ * Handle VU registrations for Base port only ++ */ ++ if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) { ++ len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ++ bfa_lps_is_brcd_fabric(port->fabric->lps), ++ port->pid, 0); ++ } else { ++ len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), BFA_FALSE, ++ port->pid, 0); ++ } ++ ++ bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, ++ FC_CLASS_3, len, &fchs, bfa_fcs_port_scn_scr_response, ++ (void *)scn, FC_MAX_PDUSZ, FC_RA_TOV); ++ ++ bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT); ++} ++ ++static void ++bfa_fcs_port_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp, ++ void *cbarg, bfa_status_t req_status, ++ u32 rsp_len, u32 resid_len, ++ struct fchs_s *rsp_fchs) ++{ ++ struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)cbarg; ++ struct bfa_fcs_port_s *port = scn->port; ++ struct fc_els_cmd_s *els_cmd; ++ struct fc_ls_rjt_s *ls_rjt; ++ ++ bfa_trc(port->fcs, port->port_cfg.pwwn); ++ ++ /* ++ * Sanity Checks ++ */ ++ if (req_status != BFA_STATUS_OK) { ++ bfa_trc(port->fcs, req_status); ++ bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); ++ return; ++ } ++ ++ els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ switch (els_cmd->els_code) { ++ ++ case FC_ELS_ACC: ++ bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK); ++ break; ++ ++ case FC_ELS_LS_RJT: ++ ++ ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); ++ ++ bfa_trc(port->fcs, ls_rjt->reason_code); ++ bfa_trc(port->fcs, ls_rjt->reason_code_expl); ++ ++ bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); ++ break; ++ ++ default: ++ bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR); ++ } ++} ++ ++/* ++ * Send a LS Accept ++ */ ++static void ++bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port, ++ struct fchs_s *rx_fchs) ++{ ++ struct fchs_s fchs; ++ struct bfa_fcxp_s *fcxp; ++ struct bfa_rport_s *bfa_rport = NULL; ++ int len; ++ ++ bfa_trc(port->fcs, rx_fchs->s_id); ++ ++ fcxp = bfa_fcs_fcxp_alloc(port->fcs); ++ if (!fcxp) ++ return; ++ ++ len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id, ++ bfa_fcs_port_get_fcid(port), rx_fchs->ox_id); ++ ++ bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag, ++ BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, ++ FC_MAX_PDUSZ, 0); ++} ++ ++/** ++ * This routine will be called by bfa_timer on timer timeouts. ++ * ++ * param[in] vport - pointer to bfa_fcs_port_t. ++ * param[out] vport_status - pointer to return vport status in ++ * ++ * return ++ * void ++ * ++* Special Considerations: ++ * ++ * note ++ */ ++static void ++bfa_fcs_port_scn_timeout(void *arg) ++{ ++ struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)arg; ++ ++ bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT); ++} ++ ++ ++ ++/** ++ * fcs_scn_public FCS state change notification public interfaces ++ */ ++ ++/* ++ * Functions called by port/fab ++ */ ++void ++bfa_fcs_port_scn_init(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); ++ ++ scn->port = port; ++ bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline); ++} ++ ++void ++bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); ++ ++ scn->port = port; ++ bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE); ++} ++ ++void ++bfa_fcs_port_scn_online(struct bfa_fcs_port_s *port) ++{ ++ struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port); ++ ++ scn->port = port; ++ bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE); ++} ++ ++static void ++bfa_fcs_port_scn_portid_rscn(struct bfa_fcs_port_s *port, u32 rpid) ++{ ++ struct bfa_fcs_rport_s *rport; ++ ++ bfa_trc(port->fcs, rpid); ++ ++ /** ++ * If this is an unknown device, then it just came online. ++ * Otherwise let rport handle the RSCN event. ++ */ ++ rport = bfa_fcs_port_get_rport_by_pid(port, rpid); ++ if (rport == NULL) { ++ /* ++ * If min cfg mode is enabled, we donot need to ++ * discover any new rports. ++ */ ++ if (!__fcs_min_cfg(port->fcs)) ++ rport = bfa_fcs_rport_create(port, rpid); ++ } else { ++ bfa_fcs_rport_scn(rport); ++ } ++} ++ ++/** ++ * rscn format based PID comparison ++ */ ++#define __fc_pid_match(__c0, __c1, __fmt) \ ++ (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \ ++ (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \ ++ ((__c0)[0] == (__c1)[0])) || \ ++ (((__fmt) == FC_RSCN_FORMAT_AREA) && \ ++ ((__c0)[0] == (__c1)[0]) && \ ++ ((__c0)[1] == (__c1)[1]))) ++ ++static void ++bfa_fcs_port_scn_multiport_rscn(struct bfa_fcs_port_s *port, ++ enum fc_rscn_format format, u32 rscn_pid) ++{ ++ struct bfa_fcs_rport_s *rport; ++ struct list_head *qe, *qe_next; ++ u8 *c0, *c1; ++ ++ bfa_trc(port->fcs, format); ++ bfa_trc(port->fcs, rscn_pid); ++ ++ c0 = (u8 *) &rscn_pid; ++ ++ list_for_each_safe(qe, qe_next, &port->rport_q) { ++ rport = (struct bfa_fcs_rport_s *)qe; ++ c1 = (u8 *) &rport->pid; ++ if (__fc_pid_match(c0, c1, format)) ++ bfa_fcs_rport_scn(rport); ++ } ++} ++ ++void ++bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port, struct fchs_s *fchs, ++ u32 len) ++{ ++ struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1); ++ int num_entries; ++ u32 rscn_pid; ++ bfa_boolean_t nsquery = BFA_FALSE; ++ int i = 0; ++ ++ num_entries = ++ (bfa_os_ntohs(rscn->payldlen) - ++ sizeof(u32)) / sizeof(rscn->event[0]); ++ ++ bfa_trc(port->fcs, num_entries); ++ ++ port->stats.num_rscn++; ++ ++ bfa_fcs_port_scn_send_ls_acc(port, fchs); ++ ++ for (i = 0; i < num_entries; i++) { ++ rscn_pid = rscn->event[i].portid; ++ ++ bfa_trc(port->fcs, rscn->event[i].format); ++ bfa_trc(port->fcs, rscn_pid); ++ ++ switch (rscn->event[i].format) { ++ case FC_RSCN_FORMAT_PORTID: ++ if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) { ++ /* ++ * Ignore this event. f/w would have processed ++ * it ++ */ ++ bfa_trc(port->fcs, rscn_pid); ++ } else { ++ port->stats.num_portid_rscn++; ++ bfa_fcs_port_scn_portid_rscn(port, rscn_pid); ++ } ++ break; ++ ++ case FC_RSCN_FORMAT_FABRIC: ++ if (rscn->event[i].qualifier == ++ FC_FABRIC_NAME_RSCN_EVENT) { ++ bfa_fcs_port_ms_fabric_rscn(port); ++ break; ++ } ++ /* ++ * !!!!!!!!! Fall Through !!!!!!!!!!!!! ++ */ ++ ++ case FC_RSCN_FORMAT_AREA: ++ case FC_RSCN_FORMAT_DOMAIN: ++ nsquery = BFA_TRUE; ++ bfa_fcs_port_scn_multiport_rscn(port, ++ rscn->event[i].format, ++ rscn_pid); ++ break; ++ ++ default: ++ bfa_assert(0); ++ nsquery = BFA_TRUE; ++ } ++ } ++ ++ /** ++ * If any of area, domain or fabric RSCN is received, do a fresh discovery ++ * to find new devices. ++ */ ++ if (nsquery) ++ bfa_fcs_port_ns_query(port); ++} ++ ++ +diff --git a/drivers/scsi/bfa/vfapi.c b/drivers/scsi/bfa/vfapi.c +new file mode 100644 +index 0000000..31d81fe +--- /dev/null ++++ b/drivers/scsi/bfa/vfapi.c +@@ -0,0 +1,292 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * vfapi.c Fabric module implementation. ++ */ ++ ++#include "fcs_fabric.h" ++#include "fcs_trcmod.h" ++ ++BFA_TRC_FILE(FCS, VFAPI); ++ ++/** ++ * fcs_vf_api virtual fabrics API ++ */ ++ ++/** ++ * Enable VF mode. ++ * ++ * @param[in] fcs fcs module instance ++ * @param[in] vf_id default vf_id of port, FC_VF_ID_NULL ++ * to use standard default vf_id of 1. ++ * ++ * @retval BFA_STATUS_OK vf mode is enabled ++ * @retval BFA_STATUS_BUSY Port is active. Port must be disabled ++ * before VF mode can be enabled. ++ */ ++bfa_status_t ++bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id) ++{ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Disable VF mode. ++ * ++ * @param[in] fcs fcs module instance ++ * ++ * @retval BFA_STATUS_OK vf mode is disabled ++ * @retval BFA_STATUS_BUSY VFs are present and being used. All ++ * VFs must be deleted before disabling ++ * VF mode. ++ */ ++bfa_status_t ++bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs) ++{ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Create a new VF instance. ++ * ++ * A new VF is created using the given VF configuration. A VF is identified ++ * by VF id. No duplicate VF creation is allowed with the same VF id. Once ++ * a VF is created, VF is automatically started after link initialization ++ * and EVFP exchange is completed. ++ * ++ * param[in] vf - FCS vf data structure. Memory is ++ * allocated by caller (driver) ++ * param[in] fcs - FCS module ++ * param[in] vf_cfg - VF configuration ++ * param[in] vf_drv - Opaque handle back to the driver's ++ * virtual vf structure ++ * ++ * retval BFA_STATUS_OK VF creation is successful ++ * retval BFA_STATUS_FAILED VF creation failed ++ * retval BFA_STATUS_EEXIST A VF exists with the given vf_id ++ */ ++bfa_status_t ++bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, u16 vf_id, ++ struct bfa_port_cfg_s *port_cfg, struct bfad_vf_s *vf_drv) ++{ ++ bfa_trc(fcs, vf_id); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Use this function to delete a BFA VF object. VF object should ++ * be stopped before this function call. ++ * ++ * param[in] vf - pointer to bfa_vf_t. ++ * ++ * retval BFA_STATUS_OK On vf deletion success ++ * retval BFA_STATUS_BUSY VF is not in a stopped state ++ * retval BFA_STATUS_INPROGRESS VF deletion in in progress ++ */ ++bfa_status_t ++bfa_fcs_vf_delete(bfa_fcs_vf_t *vf) ++{ ++ bfa_trc(vf->fcs, vf->vf_id); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Start participation in VF. This triggers login to the virtual fabric. ++ * ++ * param[in] vf - pointer to bfa_vf_t. ++ * ++ * return None ++ */ ++void ++bfa_fcs_vf_start(bfa_fcs_vf_t *vf) ++{ ++ bfa_trc(vf->fcs, vf->vf_id); ++} ++ ++/** ++ * Logout with the virtual fabric. ++ * ++ * param[in] vf - pointer to bfa_vf_t. ++ * ++ * retval BFA_STATUS_OK On success. ++ * retval BFA_STATUS_INPROGRESS VF is being stopped. ++ */ ++bfa_status_t ++bfa_fcs_vf_stop(bfa_fcs_vf_t *vf) ++{ ++ bfa_trc(vf->fcs, vf->vf_id); ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Returns attributes of the given VF. ++ * ++ * param[in] vf pointer to bfa_vf_t. ++ * param[out] vf_attr vf attributes returned ++ * ++ * return None ++ */ ++void ++bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr) ++{ ++ bfa_trc(vf->fcs, vf->vf_id); ++} ++ ++/** ++ * Return statistics associated with the given vf. ++ * ++ * param[in] vf pointer to bfa_vf_t. ++ * param[out] vf_stats vf statistics returned ++ * ++ * @return None ++ */ ++void ++bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, struct bfa_vf_stats_s *vf_stats) ++{ ++ bfa_os_memcpy(vf_stats, &vf->stats, sizeof(struct bfa_vf_stats_s)); ++ return; ++} ++ ++void ++/** ++ * clear statistics associated with the given vf. ++ * ++ * param[in] vf pointer to bfa_vf_t. ++ * ++ * @return None ++ */ ++bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf) ++{ ++ bfa_os_memset(&vf->stats, 0, sizeof(struct bfa_vf_stats_s)); ++ return; ++} ++ ++/** ++ * Returns FCS vf structure for a given vf_id. ++ * ++ * param[in] vf_id - VF_ID ++ * ++ * return ++ * If lookup succeeds, retuns fcs vf object, otherwise returns NULL ++ */ ++bfa_fcs_vf_t * ++bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id) ++{ ++ bfa_trc(fcs, vf_id); ++ if (vf_id == FC_VF_ID_NULL) ++ return (&fcs->fabric); ++ ++ /** ++ * @todo vf support ++ */ ++ ++ return NULL; ++} ++ ++/** ++ * Returns driver VF structure for a given FCS vf. ++ * ++ * param[in] vf - pointer to bfa_vf_t ++ * ++ * return Driver VF structure ++ */ ++struct bfad_vf_s * ++bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf) ++{ ++ bfa_assert(vf); ++ bfa_trc(vf->fcs, vf->vf_id); ++ return vf->vf_drv; ++} ++ ++/** ++ * Return the list of VFs configured. ++ * ++ * param[in] fcs fcs module instance ++ * param[out] vf_ids returned list of vf_ids ++ * param[in,out] nvfs in:size of vf_ids array, ++ * out:total elements present, ++ * actual elements returned is limited by the size ++ * ++ * return Driver VF structure ++ */ ++void ++bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs) ++{ ++ bfa_trc(fcs, *nvfs); ++} ++ ++/** ++ * Return the list of all VFs visible from fabric. ++ * ++ * param[in] fcs fcs module instance ++ * param[out] vf_ids returned list of vf_ids ++ * param[in,out] nvfs in:size of vf_ids array, ++ * out:total elements present, ++ * actual elements returned is limited by the size ++ * ++ * return Driver VF structure ++ */ ++void ++bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs) ++{ ++ bfa_trc(fcs, *nvfs); ++} ++ ++/** ++ * Return the list of local logical ports present in the given VF. ++ * ++ * param[in] vf vf for which logical ports are returned ++ * param[out] lpwwn returned logical port wwn list ++ * param[in,out] nlports in:size of lpwwn list; ++ * out:total elements present, ++ * actual elements returned is limited by the size ++ * ++ */ ++void ++bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports) ++{ ++ struct list_head *qe; ++ struct bfa_fcs_vport_s *vport; ++ int i; ++ struct bfa_fcs_s *fcs; ++ ++ if (vf == NULL || lpwwn == NULL || *nlports == 0) ++ return; ++ ++ fcs = vf->fcs; ++ ++ bfa_trc(fcs, vf->vf_id); ++ bfa_trc(fcs, (u32) *nlports); ++ ++ i = 0; ++ lpwwn[i++] = vf->bport.port_cfg.pwwn; ++ ++ list_for_each(qe, &vf->vport_q) { ++ if (i >= *nlports) ++ break; ++ ++ vport = (struct bfa_fcs_vport_s *) qe; ++ lpwwn[i++] = vport->lport.port_cfg.pwwn; ++ } ++ ++ bfa_trc(fcs, i); ++ *nlports = i; ++ return; ++} ++ ++ +diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c +new file mode 100644 +index 0000000..c10af06 +--- /dev/null ++++ b/drivers/scsi/bfa/vport.c +@@ -0,0 +1,891 @@ ++/* ++ * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. ++ * All rights reserved ++ * www.brocade.com ++ * ++ * Linux driver for Brocade Fibre Channel Host Bus Adapter. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License (GPL) Version 2 as ++ * published by the Free Software Foundation ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ */ ++ ++/** ++ * bfa_fcs_vport.c FCS virtual port state machine ++ */ ++ ++#include ++#include ++#include ++#include "fcs_fabric.h" ++#include "fcs_lport.h" ++#include "fcs_vport.h" ++#include "fcs_trcmod.h" ++#include "fcs.h" ++#include ++ ++BFA_TRC_FILE(FCS, VPORT); ++ ++#define __vport_fcs(__vp) (__vp)->lport.fcs ++#define __vport_pwwn(__vp) (__vp)->lport.port_cfg.pwwn ++#define __vport_nwwn(__vp) (__vp)->lport.port_cfg.nwwn ++#define __vport_bfa(__vp) (__vp)->lport.fcs->bfa ++#define __vport_fcid(__vp) (__vp)->lport.pid ++#define __vport_fabric(__vp) (__vp)->lport.fabric ++#define __vport_vfid(__vp) (__vp)->lport.fabric->vf_id ++ ++#define BFA_FCS_VPORT_MAX_RETRIES 5 ++/* ++ * Forward declarations ++ */ ++static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport); ++static void bfa_fcs_vport_timeout(void *vport_arg); ++static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport); ++static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport); ++ ++/** ++ * fcs_vport_sm FCS virtual port state machine ++ */ ++ ++/** ++ * VPort State Machine events ++ */ ++enum bfa_fcs_vport_event { ++ BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */ ++ BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */ ++ BFA_FCS_VPORT_SM_START = 3, /* vport start request */ ++ BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */ ++ BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */ ++ BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */ ++ BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */ ++ BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */ ++ BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */ ++ BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */ ++ BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ ++ BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error */ ++ BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ ++}; ++ ++static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event); ++ ++static struct bfa_sm_table_s vport_sm_table[] = { ++ {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, ++ {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED}, ++ {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE}, ++ {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC}, ++ {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY}, ++ {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE}, ++ {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING}, ++ {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP}, ++ {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO}, ++ {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR} ++}; ++ ++/** ++ * Beginning state. ++ */ ++static void ++bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_CREATE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); ++ bfa_fcs_fabric_addvport(__vport_fabric(vport), vport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Created state - a start event is required to start up the state machine. ++ */ ++static void ++bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_START: ++ if (bfa_fcs_fabric_is_online(__vport_fabric(vport)) ++ && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) { ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); ++ bfa_fcs_vport_do_fdisc(vport); ++ } else { ++ /** ++ * Fabric is offline or not NPIV capable, stay in ++ * offline state. ++ */ ++ vport->vport_stats.fab_no_npiv++; ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); ++ } ++ break; ++ ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); ++ bfa_fcs_port_delete(&vport->lport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_ONLINE: ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ /** ++ * Ignore ONLINE/OFFLINE events from fabric till vport is started. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Offline state - awaiting ONLINE event from fabric SM. ++ */ ++static void ++bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); ++ bfa_fcs_port_delete(&vport->lport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_ONLINE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); ++ vport->fdisc_retries = 0; ++ bfa_fcs_vport_do_fdisc(vport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ /* ++ * This can happen if the vport couldn't be initialzied due ++ * the fact that the npiv was not enabled on the switch. In ++ * that case we will put the vport in offline state. However, ++ * the link can go down and cause the this event to be sent when ++ * we are already offline. Ignore it. ++ */ ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * FDISC is sent and awaiting reply from fabric. ++ */ ++static void ++bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); ++ bfa_lps_discard(vport->lps); ++ bfa_fcs_vport_do_logo(vport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); ++ bfa_lps_discard(vport->lps); ++ break; ++ ++ case BFA_FCS_VPORT_SM_RSP_OK: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_online); ++ bfa_fcs_port_online(&vport->lport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_RSP_ERROR: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry); ++ bfa_timer_start(__vport_bfa(vport), &vport->timer, ++ bfa_fcs_vport_timeout, vport, ++ BFA_FCS_RETRY_TIMEOUT); ++ break; ++ ++ case BFA_FCS_VPORT_SM_RSP_FAILED: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); ++ break; ++ ++ case BFA_FCS_VPORT_SM_RSP_DUP_WWN: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_error); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * FDISC attempt failed - a timer is active to retry FDISC. ++ */ ++static void ++bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); ++ bfa_timer_stop(&vport->timer); ++ bfa_fcs_port_delete(&vport->lport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); ++ bfa_timer_stop(&vport->timer); ++ break; ++ ++ case BFA_FCS_VPORT_SM_TIMEOUT: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc); ++ vport->vport_stats.fdisc_retries++; ++ vport->fdisc_retries++; ++ bfa_fcs_vport_do_fdisc(vport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Vport is online (FDISC is complete). ++ */ ++static void ++bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting); ++ bfa_fcs_port_delete(&vport->lport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); ++ bfa_lps_discard(vport->lps); ++ bfa_fcs_port_offline(&vport->lport); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Vport is being deleted - awaiting lport delete completion to send ++ * LOGO to fabric. ++ */ ++static void ++bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ break; ++ ++ case BFA_FCS_VPORT_SM_DELCOMP: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo); ++ bfa_fcs_vport_do_logo(vport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * Error State. ++ * This state will be set when the Vport Creation fails due to errors like ++ * Dup WWN. In this state only operation allowed is a Vport Delete. ++ */ ++static void ++bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELETE: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); ++ bfa_fcs_vport_free(vport); ++ break; ++ ++ default: ++ bfa_trc(__vport_fcs(vport), event); ++ } ++} ++ ++/** ++ * Lport cleanup is in progress since vport is being deleted. Fabric is ++ * offline, so no LOGO is needed to complete vport deletion. ++ */ ++static void ++bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_DELCOMP: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); ++ bfa_fcs_vport_free(vport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_DELETE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++/** ++ * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup ++ * is done. ++ */ ++static void ++bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, ++ enum bfa_fcs_vport_event event) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), event); ++ ++ switch (event) { ++ case BFA_FCS_VPORT_SM_OFFLINE: ++ bfa_lps_discard(vport->lps); ++ /* ++ * !!! fall through !!! ++ */ ++ ++ case BFA_FCS_VPORT_SM_RSP_OK: ++ case BFA_FCS_VPORT_SM_RSP_ERROR: ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); ++ bfa_fcs_vport_free(vport); ++ break; ++ ++ case BFA_FCS_VPORT_SM_DELETE: ++ break; ++ ++ default: ++ bfa_assert(0); ++ } ++} ++ ++ ++ ++/** ++ * fcs_vport_private FCS virtual port private functions ++ */ ++ ++/** ++ * Send AEN notification ++ */ ++static void ++bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event) ++{ ++ union bfa_aen_data_u aen_data; ++ struct bfa_log_mod_s *logmod = port->fcs->logm; ++ enum bfa_port_role role = port->port_cfg.roles; ++ wwn_t lpwwn = bfa_fcs_port_get_pwwn(port); ++ char lpwwn_ptr[BFA_STRING_32]; ++ char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] = ++ { "Initiator", "Target", "IPFC" }; ++ ++ wwn2str(lpwwn_ptr, lpwwn); ++ ++ bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX); ++ ++ switch (event) { ++ case BFA_LPORT_AEN_NPIV_DUP_WWN: ++ bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_NPIV_FABRIC_MAX: ++ bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ case BFA_LPORT_AEN_NPIV_UNKNOWN: ++ bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr, ++ role_str[role / 2]); ++ break; ++ default: ++ break; ++ } ++ ++ aen_data.lport.vf_id = port->fabric->vf_id; ++ aen_data.lport.roles = role; ++ aen_data.lport.ppwwn = ++ bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs)); ++ aen_data.lport.lpwwn = lpwwn; ++} ++ ++/** ++ * This routine will be called to send a FDISC command. ++ */ ++static void ++bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_lps_fdisc(vport->lps, vport, ++ bfa_pport_get_maxfrsize(__vport_bfa(vport)), ++ __vport_pwwn(vport), __vport_nwwn(vport)); ++ vport->vport_stats.fdisc_sent++; ++} ++ ++static void ++bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport) ++{ ++ u8 lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps); ++ u8 lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps); ++ ++ bfa_trc(__vport_fcs(vport), lsrjt_rsn); ++ bfa_trc(__vport_fcs(vport), lsrjt_expl); ++ ++ /* ++ * For certain reason codes, we don't want to retry. ++ */ ++ switch (bfa_lps_get_lsrjt_expl(vport->lps)) { ++ case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */ ++ case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */ ++ if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ else { ++ bfa_fcs_vport_aen_post(&vport->lport, ++ BFA_LPORT_AEN_NPIV_DUP_WWN); ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN); ++ } ++ break; ++ ++ case FC_LS_RJT_EXP_INSUFF_RES: ++ /* ++ * This means max logins per port/switch setting on the ++ * switch was exceeded. ++ */ ++ if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES) ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ else { ++ bfa_fcs_vport_aen_post(&vport->lport, ++ BFA_LPORT_AEN_NPIV_FABRIC_MAX); ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED); ++ } ++ break; ++ ++ default: ++ if (vport->fdisc_retries == 0) /* Print only once */ ++ bfa_fcs_vport_aen_post(&vport->lport, ++ BFA_LPORT_AEN_NPIV_UNKNOWN); ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ } ++} ++ ++/** ++ * Called to send a logout to the fabric. Used when a V-Port is ++ * deleted/stopped. ++ */ ++static void ++bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ ++ vport->vport_stats.logo_sent++; ++ bfa_lps_fdisclogo(vport->lps); ++} ++ ++/** ++ * This routine will be called by bfa_timer on timer timeouts. ++ * ++ * param[in] vport - pointer to bfa_fcs_vport_t. ++ * param[out] vport_status - pointer to return vport status in ++ * ++ * return ++ * void ++ * ++* Special Considerations: ++ * ++ * note ++ */ ++static void ++bfa_fcs_vport_timeout(void *vport_arg) ++{ ++ struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *)vport_arg; ++ ++ vport->vport_stats.fdisc_timeouts++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT); ++} ++ ++static void ++bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_fcs_fabric_delvport(__vport_fabric(vport), vport); ++ bfa_fcb_vport_delete(vport->vport_drv); ++ bfa_lps_delete(vport->lps); ++} ++ ++ ++ ++/** ++ * fcs_vport_public FCS virtual port public interfaces ++ */ ++ ++/** ++ * Online notification from fabric SM. ++ */ ++void ++bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport) ++{ ++ vport->vport_stats.fab_online++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); ++} ++ ++/** ++ * Offline notification from fabric SM. ++ */ ++void ++bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport) ++{ ++ vport->vport_stats.fab_offline++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); ++} ++ ++/** ++ * Cleanup notification from fabric SM on link timer expiry. ++ */ ++void ++bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport) ++{ ++ vport->vport_stats.fab_cleanup++; ++} ++ ++/** ++ * Delete completion callback from associated lport ++ */ ++void ++bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP); ++} ++ ++/** ++ * Module initialization ++ */ ++void ++bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs) ++{ ++} ++ ++/** ++ * Module cleanup ++ */ ++void ++bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs) ++{ ++ bfa_fcs_modexit_comp(fcs); ++} ++ ++u32 ++bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs) ++{ ++ struct bfa_ioc_attr_s ioc_attr; ++ ++ bfa_get_attr(fcs->bfa, &ioc_attr); ++ ++ if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT) ++ return (BFA_FCS_MAX_VPORTS_SUPP_CT); ++ else ++ return (BFA_FCS_MAX_VPORTS_SUPP_CB); ++} ++ ++ ++ ++/** ++ * fcs_vport_api Virtual port API ++ */ ++ ++/** ++ * Use this function to instantiate a new FCS vport object. This ++ * function will not trigger any HW initialization process (which will be ++ * done in vport_start() call) ++ * ++ * param[in] vport - pointer to bfa_fcs_vport_t. This space ++ * needs to be allocated by the driver. ++ * param[in] fcs - FCS instance ++ * param[in] vport_cfg - vport configuration ++ * param[in] vf_id - VF_ID if vport is created within a VF. ++ * FC_VF_ID_NULL to specify base fabric. ++ * param[in] vport_drv - Opaque handle back to the driver's vport ++ * structure ++ * ++ * retval BFA_STATUS_OK - on success. ++ * retval BFA_STATUS_FAILED - on failure. ++ */ ++bfa_status_t ++bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs, ++ u16 vf_id, struct bfa_port_cfg_s *vport_cfg, ++ struct bfad_vport_s *vport_drv) ++{ ++ if (vport_cfg->pwwn == 0) ++ return (BFA_STATUS_INVALID_WWN); ++ ++ if (bfa_fcs_port_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn) ++ return BFA_STATUS_VPORT_WWN_BP; ++ ++ if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL) ++ return BFA_STATUS_VPORT_EXISTS; ++ ++ if (bfa_fcs_fabric_vport_count(&fcs->fabric) == ++ bfa_fcs_vport_get_max(fcs)) ++ return BFA_STATUS_VPORT_MAX; ++ ++ vport->lps = bfa_lps_alloc(fcs->bfa); ++ if (!vport->lps) ++ return BFA_STATUS_VPORT_MAX; ++ ++ vport->vport_drv = vport_drv; ++ bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit); ++ ++ bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport); ++ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Use this function initialize the vport. ++ * ++ * @param[in] vport - pointer to bfa_fcs_vport_t. ++ * ++ * @returns None ++ */ ++bfa_status_t ++bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Use this function quiese the vport object. This function will return ++ * immediately, when the vport is actually stopped, the ++ * bfa_drv_vport_stop_cb() will be called. ++ * ++ * param[in] vport - pointer to bfa_fcs_vport_t. ++ * ++ * return None ++ */ ++bfa_status_t ++bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Use this function to delete a vport object. Fabric object should ++ * be stopped before this function call. ++ * ++ * param[in] vport - pointer to bfa_fcs_vport_t. ++ * ++ * return None ++ */ ++bfa_status_t ++bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); ++ ++ return BFA_STATUS_OK; ++} ++ ++/** ++ * Use this function to get vport's current status info. ++ * ++ * param[in] vport pointer to bfa_fcs_vport_t. ++ * param[out] attr pointer to return vport attributes ++ * ++ * return None ++ */ ++void ++bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport, ++ struct bfa_vport_attr_s *attr) ++{ ++ if (vport == NULL || attr == NULL) ++ return; ++ ++ bfa_os_memset(attr, 0, sizeof(struct bfa_vport_attr_s)); ++ ++ bfa_fcs_port_get_attr(&vport->lport, &attr->port_attr); ++ attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm); ++} ++ ++/** ++ * Use this function to get vport's statistics. ++ * ++ * param[in] vport pointer to bfa_fcs_vport_t. ++ * param[out] stats pointer to return vport statistics in ++ * ++ * return None ++ */ ++void ++bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport, ++ struct bfa_vport_stats_s *stats) ++{ ++ *stats = vport->vport_stats; ++} ++ ++/** ++ * Use this function to clear vport's statistics. ++ * ++ * param[in] vport pointer to bfa_fcs_vport_t. ++ * ++ * return None ++ */ ++void ++bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport) ++{ ++ bfa_os_memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s)); ++} ++ ++/** ++ * Lookup a virtual port. Excludes base port from lookup. ++ */ ++struct bfa_fcs_vport_s * ++bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn) ++{ ++ struct bfa_fcs_vport_s *vport; ++ struct bfa_fcs_fabric_s *fabric; ++ ++ bfa_trc(fcs, vf_id); ++ bfa_trc(fcs, vpwwn); ++ ++ fabric = bfa_fcs_vf_lookup(fcs, vf_id); ++ if (!fabric) { ++ bfa_trc(fcs, vf_id); ++ return NULL; ++ } ++ ++ vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn); ++ return vport; ++} ++ ++/** ++ * FDISC Response ++ */ ++void ++bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) ++{ ++ struct bfa_fcs_vport_s *vport = uarg; ++ ++ bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); ++ bfa_trc(__vport_fcs(vport), status); ++ ++ switch (status) { ++ case BFA_STATUS_OK: ++ /* ++ * Initialiaze the V-Port fields ++ */ ++ __vport_fcid(vport) = bfa_lps_get_pid(vport->lps); ++ vport->vport_stats.fdisc_accepts++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); ++ break; ++ ++ case BFA_STATUS_INVALID_MAC: ++ /* ++ * Only for CNA ++ */ ++ vport->vport_stats.fdisc_acc_bad++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ ++ break; ++ ++ case BFA_STATUS_EPROTOCOL: ++ switch (bfa_lps_get_extstatus(vport->lps)) { ++ case BFA_EPROTO_BAD_ACCEPT: ++ vport->vport_stats.fdisc_acc_bad++; ++ break; ++ ++ case BFA_EPROTO_UNKNOWN_RSP: ++ vport->vport_stats.fdisc_unknown_rsp++; ++ break; ++ ++ default: ++ break; ++ } ++ ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ break; ++ ++ case BFA_STATUS_FABRIC_RJT: ++ vport->vport_stats.fdisc_rejects++; ++ bfa_fcs_vport_fdisc_rejected(vport); ++ break; ++ ++ default: ++ vport->vport_stats.fdisc_rsp_err++; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR); ++ } ++} ++ ++/** ++ * LOGO response ++ */ ++void ++bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) ++{ ++ struct bfa_fcs_vport_s *vport = uarg; ++ bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); ++} ++ ++ diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index d7576f2..5edde1a 100644 --- a/drivers/scsi/bnx2i/bnx2i.h @@ -823764,7 +885904,7 @@ index fd0544f..268189d 100644 kfree(scsi_dh_data); sdev_printk(KERN_ERR, sdev, "%s: not attached\n", diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c -index 0a5609b..704b8e0 100644 +index 0a5609b..025d153 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -1,5 +1,5 @@ @@ -823774,7 +885914,7 @@ index 0a5609b..704b8e0 100644 * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, -@@ -49,9 +49,20 @@ MODULE_AUTHOR("Open-FCoE.org"); +@@ -49,36 +49,101 @@ MODULE_AUTHOR("Open-FCoE.org"); MODULE_DESCRIPTION("FCoE"); MODULE_LICENSE("GPL v2"); @@ -823796,7 +885936,19 @@ index 0a5609b..704b8e0 100644 DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); /* Function Prototypes */ -@@ -66,12 +77,13 @@ static int fcoe_link_ok(struct fc_lport *lp); +-static int fcoe_reset(struct Scsi_Host *shost); ++static int fcoe_reset(struct Scsi_Host *); + static int fcoe_xmit(struct fc_lport *, struct fc_frame *); + static int fcoe_rcv(struct sk_buff *, struct net_device *, + struct packet_type *, struct net_device *); +-static int fcoe_percpu_receive_thread(void *arg); +-static void fcoe_clean_pending_queue(struct fc_lport *lp); +-static void fcoe_percpu_clean(struct fc_lport *lp); +-static int fcoe_link_ok(struct fc_lport *lp); ++static int fcoe_percpu_receive_thread(void *); ++static void fcoe_clean_pending_queue(struct fc_lport *); ++static void fcoe_percpu_clean(struct fc_lport *); ++static int fcoe_link_ok(struct fc_lport *); static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); static int fcoe_hostlist_add(const struct fc_lport *); @@ -823806,22 +885958,134 @@ index 0a5609b..704b8e0 100644 static int fcoe_device_notification(struct notifier_block *, ulong, void *); static void fcoe_dev_setup(void); static void fcoe_dev_cleanup(void); -+static struct fcoe_interface * -+ fcoe_hostlist_lookup_port(const struct net_device *dev); ++static struct fcoe_interface ++*fcoe_hostlist_lookup_port(const struct net_device *); ++ ++static int fcoe_fip_recv(struct sk_buff *, struct net_device *, ++ struct packet_type *, struct net_device *); ++ ++static void fcoe_fip_send(struct fcoe_ctlr *, struct sk_buff *); ++static void fcoe_update_src_mac(struct fc_lport *, u8 *); ++static u8 *fcoe_get_src_mac(struct fc_lport *); ++static void fcoe_destroy_work(struct work_struct *); ++ ++static int fcoe_ddp_setup(struct fc_lport *, u16, struct scatterlist *, ++ unsigned int); ++static int fcoe_ddp_done(struct fc_lport *, u16); ++ ++static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); ++ ++static int fcoe_create(const char *, struct kernel_param *); ++static int fcoe_destroy(const char *, struct kernel_param *); ++ ++static u8 *fcoe_get_src_mac(struct fc_lport *); ++static void fcoe_destroy_work(struct work_struct *); - /* notification function from net device */ +-/* notification function from net device */ ++static struct fc_seq *fcoe_elsct_send(struct fc_lport *, ++ u32 did, struct fc_frame *, ++ unsigned int op, ++ void (*resp)(struct fc_seq *, ++ struct fc_frame *, ++ void *), ++ void *, u32 timeout); ++ ++module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); ++__MODULE_PARM_TYPE(create, "string"); ++MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); ++module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); ++__MODULE_PARM_TYPE(destroy, "string"); ++MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); ++ ++/* notification function for packets from net device */ static struct notifier_block fcoe_notifier = { -@@ -132,6 +144,180 @@ static struct scsi_host_template fcoe_shost_template = { - .max_sectors = 0xffff, + .notifier_call = fcoe_device_notification, }; -+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, -+ struct packet_type *ptype, -+ struct net_device *orig_dev); -+/** -+ * fcoe_interface_setup() -+ * @fcoe: new fcoe_interface -+ * @netdev : ptr to the associated netdevice struct +-static struct scsi_transport_template *scsi_transport_fcoe_sw; ++/* notification function for CPU hotplug events */ ++static struct notifier_block fcoe_cpu_notifier = { ++ .notifier_call = fcoe_cpu_callback, ++}; ++ ++static struct scsi_transport_template *fcoe_transport_template; ++static struct scsi_transport_template *fcoe_vport_transport_template; ++ ++static int fcoe_vport_destroy(struct fc_vport *); ++static int fcoe_vport_create(struct fc_vport *, bool disabled); ++static int fcoe_vport_disable(struct fc_vport *, bool disable); ++static void fcoe_set_vport_symbolic_name(struct fc_vport *); ++ ++static struct libfc_function_template fcoe_libfc_fcn_templ = { ++ .frame_send = fcoe_xmit, ++ .ddp_setup = fcoe_ddp_setup, ++ .ddp_done = fcoe_ddp_done, ++ .elsct_send = fcoe_elsct_send, ++}; + + struct fc_function_template fcoe_transport_function = { + .show_host_node_name = 1, +@@ -111,6 +176,48 @@ struct fc_function_template fcoe_transport_function = { + .issue_fc_host_lip = fcoe_reset, + + .terminate_rport_io = fc_rport_terminate_io, ++ ++ .vport_create = fcoe_vport_create, ++ .vport_delete = fcoe_vport_destroy, ++ .vport_disable = fcoe_vport_disable, ++ .set_vport_symbolic_name = fcoe_set_vport_symbolic_name, ++ ++ .bsg_request = fc_lport_bsg_request, ++}; ++ ++struct fc_function_template fcoe_vport_transport_function = { ++ .show_host_node_name = 1, ++ .show_host_port_name = 1, ++ .show_host_supported_classes = 1, ++ .show_host_supported_fc4s = 1, ++ .show_host_active_fc4s = 1, ++ .show_host_maxframe_size = 1, ++ ++ .show_host_port_id = 1, ++ .show_host_supported_speeds = 1, ++ .get_host_speed = fc_get_host_speed, ++ .show_host_speed = 1, ++ .show_host_port_type = 1, ++ .get_host_port_state = fc_get_host_port_state, ++ .show_host_port_state = 1, ++ .show_host_symbolic_name = 1, ++ ++ .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv), ++ .show_rport_maxframe_size = 1, ++ .show_rport_supported_classes = 1, ++ ++ .show_host_fabric_name = 1, ++ .show_starget_node_name = 1, ++ .show_starget_port_name = 1, ++ .show_starget_port_id = 1, ++ .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo, ++ .show_rport_dev_loss_tmo = 1, ++ .get_fc_host_stats = fc_get_host_stats, ++ .issue_fc_host_lip = fcoe_reset, ++ ++ .terminate_rport_io = fc_rport_terminate_io, ++ ++ .bsg_request = fc_lport_bsg_request, + }; + + static struct scsi_host_template fcoe_shost_template = { +@@ -133,527 +240,705 @@ static struct scsi_host_template fcoe_shost_template = { + }; + + /** +- * fcoe_fip_recv - handle a received FIP frame. +- * @skb: the receive skb +- * @dev: associated &net_device +- * @ptype: the &packet_type structure which was used to register this handler. +- * @orig_dev: original receive &net_device, in case @dev is a bond. ++ * fcoe_interface_setup() - Setup a FCoE interface ++ * @fcoe: The new FCoE interface ++ * @netdev: The net device that the fcoe interface is on + * + * Returns : 0 for success + * Locking: must be called with the RTNL mutex held @@ -823887,13 +886151,9 @@ index 0a5609b..704b8e0 100644 + return 0; +} + -+static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb); -+static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new); -+static void fcoe_destroy_work(struct work_struct *work); -+ +/** -+ * fcoe_interface_create() -+ * @netdev: network interface ++ * fcoe_interface_create() - Create a FCoE interface on a net device ++ * @netdev: The net device to create the FCoE interface on + * + * Returns: pointer to a struct fcoe_interface or NULL on error + */ @@ -823916,6 +886176,7 @@ index 0a5609b..704b8e0 100644 + fcoe_ctlr_init(&fcoe->ctlr); + fcoe->ctlr.send = fcoe_fip_send; + fcoe->ctlr.update_mac = fcoe_update_src_mac; ++ fcoe->ctlr.get_src_addr = fcoe_get_src_mac; + + fcoe_interface_setup(fcoe, netdev); + @@ -823923,8 +886184,8 @@ index 0a5609b..704b8e0 100644 +} + +/** -+ * fcoe_interface_cleanup() - clean up netdev configurations -+ * @fcoe: ++ * fcoe_interface_cleanup() - Clean up a FCoE interface ++ * @fcoe: The FCoE interface to be cleaned up + * + * Caller must be holding the RTNL mutex + */ @@ -823947,8 +886208,6 @@ index 0a5609b..704b8e0 100644 + /* Delete secondary MAC addresses */ + memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); + dev_unicast_delete(netdev, flogi_maddr); -+ if (!is_zero_ether_addr(fip->data_src_addr)) -+ dev_unicast_delete(netdev, fip->data_src_addr); + if (fip->spma) + dev_unicast_delete(netdev, fip->ctl_src_addr); + dev_mc_delete(netdev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); @@ -823956,7 +886215,7 @@ index 0a5609b..704b8e0 100644 + +/** + * fcoe_interface_release() - fcoe_port kref release function -+ * @kref: embedded reference count in an fcoe_interface struct ++ * @kref: Embedded reference count in an fcoe_interface struct + */ +static void fcoe_interface_release(struct kref *kref) +{ @@ -823972,8 +886231,8 @@ index 0a5609b..704b8e0 100644 +} + +/** -+ * fcoe_interface_get() -+ * @fcoe: ++ * fcoe_interface_get() - Get a reference to a FCoE interface ++ * @fcoe: The FCoE interface to be held + */ +static inline void fcoe_interface_get(struct fcoe_interface *fcoe) +{ @@ -823981,18 +886240,26 @@ index 0a5609b..704b8e0 100644 +} + +/** -+ * fcoe_interface_put() -+ * @fcoe: ++ * fcoe_interface_put() - Put a reference to a FCoE interface ++ * @fcoe: The FCoE interface to be released + */ +static inline void fcoe_interface_put(struct fcoe_interface *fcoe) +{ + kref_put(&fcoe->kref, fcoe_interface_release); +} + - /** - * fcoe_fip_recv - handle a received FIP frame. - * @skb: the receive skb -@@ -145,10 +331,10 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, ++/** ++ * fcoe_fip_recv() - Handler for received FIP frames ++ * @skb: The receive skb ++ * @netdev: The associated net device ++ * @ptype: The packet_type structure which was used to register this handler ++ * @orig_dev: The original net_device the the skb was received on. ++ * (in case dev is a bond) + * + * Returns: 0 for success + */ +-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, ++static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *netdev, struct packet_type *ptype, struct net_device *orig_dev) { @@ -824006,7 +886273,13 @@ index 0a5609b..704b8e0 100644 return 0; } -@@ -159,7 +345,7 @@ static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev, + /** +- * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame. +- * @fip: FCoE controller. +- * @skb: FIP Packet. ++ * fcoe_fip_send() - Send an Ethernet-encapsulated FIP frame ++ * @fip: The FCoE controller ++ * @skb: The FIP packet to be sent */ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) { @@ -824015,39 +886288,105 @@ index 0a5609b..704b8e0 100644 dev_queue_xmit(skb); } -@@ -174,13 +360,13 @@ static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb) + /** +- * fcoe_update_src_mac() - Update Ethernet MAC filters. +- * @fip: FCoE controller. +- * @old: Unicast MAC address to delete if the MAC is non-zero. +- * @new: Unicast MAC address to add. ++ * fcoe_update_src_mac() - Update the Ethernet MAC filters ++ * @lport: The local port to update the source MAC on ++ * @addr: Unicast MAC address to add + * + * Remove any previously-set unicast MAC filter. + * Add secondary FCoE MAC address filter for our OUI. */ - static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) +-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new) ++static void fcoe_update_src_mac(struct fc_lport *lport, u8 *addr) { - struct fcoe_softc *fc; -+ struct fcoe_interface *fcoe; ++ struct fcoe_port *port = lport_priv(lport); ++ struct fcoe_interface *fcoe = port->fcoe; - fc = fcoe_from_ctlr(fip); -+ fcoe = fcoe_from_ctlr(fip); rtnl_lock(); - if (!is_zero_ether_addr(old)) +- if (!is_zero_ether_addr(old)) - dev_unicast_delete(fc->real_dev, old); - dev_unicast_add(fc->real_dev, new); -+ dev_unicast_delete(fcoe->netdev, old); -+ dev_unicast_add(fcoe->netdev, new); ++ if (!is_zero_ether_addr(port->data_src_addr)) ++ dev_unicast_delete(fcoe->netdev, port->data_src_addr); ++ if (!is_zero_ether_addr(addr)) ++ dev_unicast_add(fcoe->netdev, addr); ++ memcpy(port->data_src_addr, addr, ETH_ALEN); rtnl_unlock(); } -@@ -217,30 +403,6 @@ static int fcoe_lport_config(struct fc_lport *lp) + /** +- * fcoe_lport_config() - sets up the fc_lport +- * @lp: ptr to the fc_lport +- * +- * Returns: 0 for success ++ * fcoe_get_src_mac() - return the Ethernet source address for an lport ++ * @lport: libfc lport + */ +-static int fcoe_lport_config(struct fc_lport *lp) ++static u8 *fcoe_get_src_mac(struct fc_lport *lport) + { +- lp->link_up = 0; +- lp->qfull = 0; +- lp->max_retry_count = 3; +- lp->max_rport_retry_count = 3; +- lp->e_d_tov = 2 * 1000; /* FC-FS default */ +- lp->r_a_tov = 2 * 2 * 1000; +- lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | +- FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL); ++ struct fcoe_port *port = lport_priv(lport); + +- fc_lport_init_stats(lp); +- +- /* lport fc_lport related configuration */ +- fc_lport_config(lp); +- +- /* offload related configuration */ +- lp->crc_offload = 0; +- lp->seq_offload = 0; +- lp->lro_enabled = 0; +- lp->lro_xid = 0; +- lp->lso_max = 0; +- +- return 0; ++ return port->data_src_addr; } /** - * fcoe_netdev_cleanup() - clean up netdev configurations - * @fc: ptr to the fcoe_softc -- */ ++ * fcoe_lport_config() - Set up a local port ++ * @lport: The local port to be setup ++ * ++ * Returns: 0 for success + */ -void fcoe_netdev_cleanup(struct fcoe_softc *fc) --{ ++static int fcoe_lport_config(struct fc_lport *lport) + { - u8 flogi_maddr[ETH_ALEN]; -- ++ lport->link_up = 0; ++ lport->qfull = 0; ++ lport->max_retry_count = 3; ++ lport->max_rport_retry_count = 3; ++ lport->e_d_tov = 2 * 1000; /* FC-FS default */ ++ lport->r_a_tov = 2 * 2 * 1000; ++ lport->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | ++ FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL); ++ lport->does_npiv = 1; ++ ++ fc_lport_init_stats(lport); + - /* Don't listen for Ethernet packets anymore */ - dev_remove_pack(&fc->fcoe_packet_type); - dev_remove_pack(&fc->fip_packet_type); -- ++ /* lport fc_lport related configuration */ ++ fc_lport_config(lport); + - /* Delete secondary MAC addresses */ - rtnl_lock(); - memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN); @@ -824058,13 +886397,48 @@ index 0a5609b..704b8e0 100644 - dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr); - dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0); - rtnl_unlock(); --} -- --/** - * fcoe_queue_timer() - fcoe queue timer - * @lp: the fc_lport pointer ++ /* offload related configuration */ ++ lport->crc_offload = 0; ++ lport->seq_offload = 0; ++ lport->lro_enabled = 0; ++ lport->lro_xid = 0; ++ lport->lso_max = 0; ++ ++ return 0; + } + + /** +- * fcoe_queue_timer() - fcoe queue timer +- * @lp: the fc_lport pointer ++ * fcoe_queue_timer() - The fcoe queue timer ++ * @lport: The local port * -@@ -265,116 +427,53 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) + * Calls fcoe_check_wait_queue on timeout +- * + */ +-static void fcoe_queue_timer(ulong lp) ++static void fcoe_queue_timer(ulong lport) + { +- fcoe_check_wait_queue((struct fc_lport *)lp, NULL); ++ fcoe_check_wait_queue((struct fc_lport *)lport, NULL); + } + + /** +- * fcoe_netdev_config() - Set up netdev for SW FCoE +- * @lp : ptr to the fc_lport +- * @netdev : ptr to the associated netdevice struct ++ * fcoe_netdev_config() - Set up net devive for SW FCoE ++ * @lport: The local port that is associated with the net device ++ * @netdev: The associated net device + * +- * Must be called after fcoe_lport_config() as it will use lport mutex ++ * Must be called after fcoe_lport_config() as it will use local port mutex + * +- * Returns : 0 for success ++ * Returns: 0 for success + */ +-static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) ++static int fcoe_netdev_config(struct fc_lport *lport, struct net_device *netdev) { u32 mfs; u64 wwnn, wwpn; @@ -824090,7 +886464,7 @@ index 0a5609b..704b8e0 100644 - (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) { - return -EOPNOTSUPP; - } -+ port = lport_priv(lp); ++ port = lport_priv(lport); + fcoe = port->fcoe; /* @@ -824100,35 +886474,44 @@ index 0a5609b..704b8e0 100644 */ - mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) + - sizeof(struct fcoe_crc_eof)); +- if (fc_set_mfs(lp, mfs)) + mfs = netdev->mtu - (sizeof(struct fcoe_hdr) + + sizeof(struct fcoe_crc_eof)); - if (fc_set_mfs(lp, mfs)) ++ if (fc_set_mfs(lport, mfs)) return -EINVAL; /* offload features support */ - if (fc->real_dev->features & NETIF_F_SG) +- lp->sg_supp = 1; + if (netdev->features & NETIF_F_SG) - lp->sg_supp = 1; ++ lport->sg_supp = 1; -#ifdef NETIF_F_FCOE_CRC if (netdev->features & NETIF_F_FCOE_CRC) { - lp->crc_offload = 1; +- lp->crc_offload = 1; ++ lport->crc_offload = 1; FCOE_NETDEV_DBG(netdev, "Supports FCCRC offload\n"); } -#endif -#ifdef NETIF_F_FSO if (netdev->features & NETIF_F_FSO) { - lp->seq_offload = 1; - lp->lso_max = netdev->gso_max_size; +- lp->seq_offload = 1; +- lp->lso_max = netdev->gso_max_size; ++ lport->seq_offload = 1; ++ lport->lso_max = netdev->gso_max_size; FCOE_NETDEV_DBG(netdev, "Supports LSO for max len 0x%x\n", - lp->lso_max); +- lp->lso_max); ++ lport->lso_max); } -#endif if (netdev->fcoe_ddp_xid) { - lp->lro_enabled = 1; - lp->lro_xid = netdev->fcoe_ddp_xid; +- lp->lro_enabled = 1; +- lp->lro_xid = netdev->fcoe_ddp_xid; ++ lport->lro_enabled = 1; ++ lport->lro_xid = netdev->fcoe_ddp_xid; FCOE_NETDEV_DBG(netdev, "Supports LRO for max xid 0x%x\n", - lp->lro_xid); +- lp->lro_xid); ++ lport->lro_xid); } - skb_queue_head_init(&fc->fcoe_pending_queue); - fc->fcoe_pending_queue_active = 0; @@ -824144,25 +886527,30 @@ index 0a5609b..704b8e0 100644 - fc->ctlr.spma = 1; - break; - } -- } ++ skb_queue_head_init(&port->fcoe_pending_queue); ++ port->fcoe_pending_queue_active = 0; ++ setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lport); ++ ++ if (!lport->vport) { ++ wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0); ++ fc_set_wwnn(lport, wwnn); ++ /* XXX - 3rd arg needs to be vlan id */ ++ wwpn = fcoe_wwn_from_mac(netdev->dev_addr, 2, 0); ++ fc_set_wwpn(lport, wwpn); + } - rcu_read_unlock(); - - /* setup Source Mac Address */ - if (!fc->ctlr.spma) - memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr, - fc->real_dev->addr_len); -+ skb_queue_head_init(&port->fcoe_pending_queue); -+ port->fcoe_pending_queue_active = 0; -+ setup_timer(&port->timer, fcoe_queue_timer, (unsigned long)lp); - +- - wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0); -+ wwnn = fcoe_wwn_from_mac(netdev->dev_addr, 1, 0); - fc_set_wwnn(lp, wwnn); - /* XXX - 3rd arg needs to be vlan id */ +- fc_set_wwnn(lp, wwnn); +- /* XXX - 3rd arg needs to be vlan id */ - wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0); -+ wwpn = fcoe_wwn_from_mac(netdev->dev_addr, 2, 0); - fc_set_wwpn(lp, wwpn); - +- fc_set_wwpn(lp, wwpn); +- - /* - * Add FCoE MAC address as second unicast MAC address - * or enter promiscuous mode if not capable of listening @@ -824189,52 +886577,118 @@ index 0a5609b..704b8e0 100644 - fc->fip_packet_type.type = htons(ETH_P_FIP); - fc->fip_packet_type.dev = fc->real_dev; - dev_add_pack(&fc->fip_packet_type); + + return 0; + } + + /** +- * fcoe_shost_config() - Sets up fc_lport->host +- * @lp : ptr to the fc_lport +- * @shost : ptr to the associated scsi host +- * @dev : device associated to scsi host ++ * fcoe_shost_config() - Set up the SCSI host associated with a local port ++ * @lport: The local port ++ * @shost: The SCSI host to associate with the local port ++ * @dev: The device associated with the SCSI host + * + * Must be called after fcoe_lport_config() and fcoe_netdev_config() + * +- * Returns : 0 for success ++ * Returns: 0 for success + */ +-static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, +- struct device *dev) ++static int fcoe_shost_config(struct fc_lport *lport, struct Scsi_Host *shost, ++ struct device *dev) + { + int rc = 0; + + /* lport scsi host config */ +- lp->host = shost; - +- lp->host->max_lun = FCOE_MAX_LUN; +- lp->host->max_id = FCOE_MAX_FCP_TARGET; +- lp->host->max_channel = 0; +- lp->host->transportt = scsi_transport_fcoe_sw; ++ lport->host->max_lun = FCOE_MAX_LUN; ++ lport->host->max_id = FCOE_MAX_FCP_TARGET; ++ lport->host->max_channel = 0; ++ if (lport->vport) ++ lport->host->transportt = fcoe_vport_transport_template; ++ else ++ lport->host->transportt = fcoe_transport_template; + + /* add the new host to the SCSI-ml */ +- rc = scsi_add_host(lp->host, dev); ++ rc = scsi_add_host(lport->host, dev); + if (rc) { +- FCOE_NETDEV_DBG(fcoe_netdev(lp), "fcoe_shost_config: " ++ FCOE_NETDEV_DBG(fcoe_netdev(lport), "fcoe_shost_config: " + "error on scsi_add_host\n"); + return rc; + } +- sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s", +- FCOE_NAME, FCOE_VERSION, +- fcoe_netdev(lp)->name); ++ ++ if (!lport->vport) ++ fc_host_max_npiv_vports(lport->host) = USHORT_MAX; ++ ++ snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE, ++ "%s v%s over %s", FCOE_NAME, FCOE_VERSION, ++ fcoe_netdev(lport)->name); + return 0; } -@@ -415,86 +514,140 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost, - return 0; - } - -+/* -+ * fcoe_oem_match() - match for read types IO -+ * @fp: the fc_frame for new IO. + /** +- * fcoe_em_config() - allocates em for this lport +- * @lp: the port that em is to allocated for ++ * fcoe_oem_match() - The match routine for the offloaded exchange manager ++ * @fp: The I/O frame + * -+ * Returns : true for read types IO, otherwise returns false. -+ */ ++ * This routine will be associated with an exchange manager (EM). When ++ * the libfc exchange handling code is looking for an EM to use it will ++ * call this routine and pass it the frame that it wishes to send. This ++ * routine will return True if the associated EM is to be used and False ++ * if the echange code should continue looking for an EM. ++ * ++ * The offload EM that this routine is associated with will handle any ++ * packets that are for SCSI read requests. + * +- * Returns : 0 on success ++ * Returns: True for read types I/O, otherwise returns false. + */ +-static inline int fcoe_em_config(struct fc_lport *lp) +bool fcoe_oem_match(struct fc_frame *fp) -+{ + { +- BUG_ON(lp->emp); + return fc_fcp_is_read(fr_fsp(fp)) && + (fr_fsp(fp)->data_len > fcoe_ddp_min); +} + - /** - * fcoe_em_config() - allocates em for this lport -- * @lp: the port that em is to allocated for -+ * @lp: the fcoe that em is to allocated for - * - * Returns : 0 on success - */ - static inline int fcoe_em_config(struct fc_lport *lp) - { -- BUG_ON(lp->emp); -+ struct fcoe_port *port = lport_priv(lp); ++/** ++ * fcoe_em_config() - Allocate and configure an exchange manager ++ * @lport: The local port that the new EM will be associated with ++ * ++ * Returns: 0 on success ++ */ ++static inline int fcoe_em_config(struct fc_lport *lport) ++{ ++ struct fcoe_port *port = lport_priv(lport); + struct fcoe_interface *fcoe = port->fcoe; + struct fcoe_interface *oldfcoe = NULL; + struct net_device *old_real_dev, *cur_real_dev; + u16 min_xid = FCOE_MIN_XID; + u16 max_xid = FCOE_MAX_XID; - -- lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, -- FCOE_MIN_XID, FCOE_MAX_XID); -- if (!lp->emp) ++ + /* + * Check if need to allocate an em instance for + * offload exchange ids to be shared across all VN_PORTs/lport. + */ -+ if (!lp->lro_enabled || !lp->lro_xid || (lp->lro_xid >= max_xid)) { -+ lp->lro_xid = 0; ++ if (!lport->lro_enabled || !lport->lro_xid || ++ (lport->lro_xid >= max_xid)) { ++ lport->lro_xid = 0; + goto skip_oem; + } + @@ -824252,7 +886706,10 @@ index 0a5609b..704b8e0 100644 + old_real_dev = vlan_dev_real_dev(oldfcoe->netdev); + else + old_real_dev = oldfcoe->netdev; -+ + +- lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3, +- FCOE_MIN_XID, FCOE_MAX_XID); +- if (!lp->emp) + if (cur_real_dev == old_real_dev) { + fcoe->oem = oldfcoe->oem; + break; @@ -824260,16 +886717,16 @@ index 0a5609b..704b8e0 100644 + } + + if (fcoe->oem) { -+ if (!fc_exch_mgr_add(lp, fcoe->oem, fcoe_oem_match)) { ++ if (!fc_exch_mgr_add(lport, fcoe->oem, fcoe_oem_match)) { + printk(KERN_ERR "fcoe_em_config: failed to add " + "offload em:%p on interface:%s\n", + fcoe->oem, fcoe->netdev->name); + return -ENOMEM; + } + } else { -+ fcoe->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3, -+ FCOE_MIN_XID, lp->lro_xid, -+ fcoe_oem_match); ++ fcoe->oem = fc_exch_mgr_alloc(lport, FC_CLASS_3, ++ FCOE_MIN_XID, lport->lro_xid, ++ fcoe_oem_match); + if (!fcoe->oem) { + printk(KERN_ERR "fcoe_em_config: failed to allocate " + "em for offload exches on interface:%s\n", @@ -824281,10 +886738,10 @@ index 0a5609b..704b8e0 100644 + /* + * Exclude offload EM xid range from next EM xid range. + */ -+ min_xid += lp->lro_xid + 1; ++ min_xid += lport->lro_xid + 1; + +skip_oem: -+ if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) { ++ if (!fc_exch_mgr_alloc(lport, FC_CLASS_3, min_xid, max_xid, NULL)) { + printk(KERN_ERR "fcoe_em_config: failed to " + "allocate em on interface %s\n", fcoe->netdev->name); return -ENOMEM; @@ -824294,11 +886751,12 @@ index 0a5609b..704b8e0 100644 } /** - * fcoe_if_destroy() - FCoE software HBA tear-down function +- * fcoe_if_destroy() - FCoE software HBA tear-down function - * @netdev: ptr to the associated net_device - * - * Returns: 0 if link is OK for use by FCoE. -+ * @lport: fc_lport to destroy ++ * fcoe_if_destroy() - Tear down a SW FCoE instance ++ * @lport: The local port to be destroyed */ -static int fcoe_if_destroy(struct net_device *netdev) +static void fcoe_if_destroy(struct fc_lport *lport) @@ -824316,35 +886774,39 @@ index 0a5609b..704b8e0 100644 - lp = fcoe_hostlist_lookup(netdev); - if (!lp) - return -ENODEV; -- -- fc = lport_priv(lp); -- - /* Logout of the fabric */ -- fc_fabric_logoff(lp); ++ /* Logout of the fabric */ + fc_fabric_logoff(lport); -- /* Remove the instance from fcoe's list */ -- fcoe_hostlist_remove(lp); +- fc = lport_priv(lp); + /* Cleanup the fc_lport */ + fc_lport_destroy(lport); + fc_fcp_destroy(lport); -- /* clean up netdev configurations */ -- fcoe_netdev_cleanup(fc); +- /* Logout of the fabric */ +- fc_fabric_logoff(lp); + /* Stop the transmit retry timer */ + del_timer_sync(&port->timer); -- /* tear-down the FCoE controller */ -- fcoe_ctlr_destroy(&fc->ctlr); +- /* Remove the instance from fcoe's list */ +- fcoe_hostlist_remove(lp); + /* Free existing transmit skbs */ + fcoe_clean_pending_queue(lport); +- /* clean up netdev configurations */ +- fcoe_netdev_cleanup(fc); ++ rtnl_lock(); ++ if (!is_zero_ether_addr(port->data_src_addr)) ++ dev_unicast_delete(netdev, port->data_src_addr); ++ rtnl_unlock(); + +- /* tear-down the FCoE controller */ +- fcoe_ctlr_destroy(&fc->ctlr); ++ /* receives may not be stopped until after this */ ++ fcoe_interface_put(fcoe); + - /* Cleanup the fc_lport */ - fc_lport_destroy(lp); - fc_fcp_destroy(lp); -+ /* receives may not be stopped until after this */ -+ fcoe_interface_put(fcoe); -+ + /* Free queued packets for the per-CPU receive threads */ + fcoe_percpu_clean(lport); @@ -824370,48 +886832,116 @@ index 0a5609b..704b8e0 100644 /* Free memory used by statistical counters */ - fc_lport_free_stats(lp); -- ++ fc_lport_free_stats(lport); + - /* Release the net_device and Scsi_Host */ - dev_put(fc->real_dev); - scsi_host_put(lp->host); -+ fc_lport_free_stats(lport); - +- - return 0; + /* Release the Scsi_Host */ + scsi_host_put(lport->host); } - /* -@@ -540,106 +693,96 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = { - }; +-/* +- * fcoe_ddp_setup - calls LLD's ddp_setup through net_device +- * @lp: the corresponding fc_lport +- * @xid: the exchange id for this ddp transfer +- * @sgl: the scatterlist describing this transfer +- * @sgc: number of sg items ++/** ++ * fcoe_ddp_setup() - Call a LLD's ddp_setup through the net device ++ * @lport: The local port to setup DDP for ++ * @xid: The exchange ID for this DDP transfer ++ * @sgl: The scatterlist describing this transfer ++ * @sgc: The number of sg items + * +- * Returns : 0 no ddp ++ * Returns: 0 if the DDP context was not configured + */ +-static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid, +- struct scatterlist *sgl, unsigned int sgc) ++static int fcoe_ddp_setup(struct fc_lport *lport, u16 xid, ++ struct scatterlist *sgl, unsigned int sgc) + { +- struct net_device *n = fcoe_netdev(lp); ++ struct net_device *netdev = fcoe_netdev(lport); +- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup) +- return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc); ++ if (netdev->netdev_ops->ndo_fcoe_ddp_setup) ++ return netdev->netdev_ops->ndo_fcoe_ddp_setup(netdev, ++ xid, sgl, ++ sgc); + + return 0; + } + +-/* +- * fcoe_ddp_done - calls LLD's ddp_done through net_device +- * @lp: the corresponding fc_lport +- * @xid: the exchange id for this ddp transfer ++/** ++ * fcoe_ddp_done() - Call a LLD's ddp_done through the net device ++ * @lport: The local port to complete DDP on ++ * @xid: The exchange ID for this DDP transfer + * +- * Returns : the length of data that have been completed by ddp ++ * Returns: the length of data that have been completed by DDP + */ +-static int fcoe_ddp_done(struct fc_lport *lp, u16 xid) ++static int fcoe_ddp_done(struct fc_lport *lport, u16 xid) + { +- struct net_device *n = fcoe_netdev(lp); ++ struct net_device *netdev = fcoe_netdev(lport); + +- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done) +- return n->netdev_ops->ndo_fcoe_ddp_done(n, xid); ++ if (netdev->netdev_ops->ndo_fcoe_ddp_done) ++ return netdev->netdev_ops->ndo_fcoe_ddp_done(netdev, xid); + return 0; + } + +-static struct libfc_function_template fcoe_libfc_fcn_templ = { +- .frame_send = fcoe_xmit, +- .ddp_setup = fcoe_ddp_setup, +- .ddp_done = fcoe_ddp_done, +-}; +- /** - * fcoe_if_create() - this function creates the fcoe interface - * @netdev: pointer the associated netdevice -+ * fcoe_if_create() - this function creates the fcoe port -+ * @fcoe: fcoe_interface structure to create an fc_lport instance on -+ * @parent: device pointer to be the parent in sysfs for the SCSI host ++ * fcoe_if_create() - Create a FCoE instance on an interface ++ * @fcoe: The FCoE interface to create a local port on ++ * @parent: The device pointer to be the parent in sysfs for the SCSI host ++ * @npiv: Indicates if the port is a vport or not * - * Creates fc_lport struct and scsi_host for lport, configures lport - * and starts fabric login. -+ * Creates fc_lport struct and scsi_host for lport, configures lport. ++ * Creates a fc_lport instance and a Scsi_Host instance and configure them. * - * Returns : 0 on success -+ * Returns : The allocated fc_lport or an error pointer ++ * Returns: The allocated fc_lport or an error pointer */ -static int fcoe_if_create(struct net_device *netdev) +static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, -+ struct device *parent) ++ struct device *parent, int npiv) { - int rc; +- int rc; - struct fc_lport *lp = NULL; - struct fcoe_softc *fc; ++ struct net_device *netdev = fcoe->netdev; + struct fc_lport *lport = NULL; + struct fcoe_port *port; struct Scsi_Host *shost; - - BUG_ON(!netdev); -+ struct net_device *netdev = fcoe->netdev; ++ int rc; ++ /* ++ * parent is only a vport if npiv is 1, ++ * but we'll only use vport in that case so go ahead and set it ++ */ ++ struct fc_vport *vport = dev_to_vport(parent); FCOE_NETDEV_DBG(netdev, "Create Interface\n"); @@ -824419,10 +886949,17 @@ index 0a5609b..704b8e0 100644 - if (lp) - return -EEXIST; - - shost = libfc_host_alloc(&fcoe_shost_template, +- shost = libfc_host_alloc(&fcoe_shost_template, - sizeof(struct fcoe_softc)); -+ sizeof(struct fcoe_port)); - if (!shost) { +- if (!shost) { ++ if (!npiv) { ++ lport = libfc_host_alloc(&fcoe_shost_template, ++ sizeof(struct fcoe_port)); ++ } else { ++ lport = libfc_vport_create(vport, ++ sizeof(struct fcoe_port)); ++ } ++ if (!lport) { FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); - return -ENOMEM; + rc = -ENOMEM; @@ -824430,14 +886967,16 @@ index 0a5609b..704b8e0 100644 } - lp = shost_priv(shost); - fc = lport_priv(lp); -+ lport = shost_priv(shost); +- +- /* configure fc_lport, e.g., em */ +- rc = fcoe_lport_config(lp); ++ shost = lport->host; + port = lport_priv(lport); + port->lport = lport; + port->fcoe = fcoe; + INIT_WORK(&port->destroy_work, fcoe_destroy_work); - - /* configure fc_lport, e.g., em */ -- rc = fcoe_lport_config(lp); ++ ++ /* configure a fc_lport including the exchange manager */ + rc = fcoe_lport_config(lport); if (rc) { FCOE_NETDEV_DBG(netdev, "Could not configure lport for the " @@ -824451,7 +886990,13 @@ index 0a5609b..704b8e0 100644 - fcoe_ctlr_init(&fc->ctlr); - fc->ctlr.send = fcoe_fip_send; - fc->ctlr.update_mac = fcoe_update_src_mac; -- ++ if (npiv) { ++ FCOE_NETDEV_DBG(netdev, "Setting vport names, 0x%llX 0x%llX\n", ++ vport->node_name, vport->port_name); ++ fc_set_wwnn(lport, vport->node_name); ++ fc_set_wwpn(lport, vport->port_name); ++ } + /* configure lport network properties */ - rc = fcoe_netdev_config(lp, netdev); + rc = fcoe_netdev_config(lport, netdev); @@ -824498,22 +887043,25 @@ index 0a5609b..704b8e0 100644 - - if (!fcoe_link_ok(lp)) - fcoe_ctlr_link_up(&fc->ctlr); -+ /* -+ * fcoe_em_alloc() and fcoe_hostlist_add() both -+ * need to be atomic with respect to other changes to the hostlist -+ * since fcoe_em_alloc() looks for an existing EM -+ * instance on host list updated by fcoe_hostlist_add(). -+ * -+ * This is currently handled through the fcoe_config_mutex begin held. -+ */ ++ if (!npiv) { ++ /* ++ * fcoe_em_alloc() and fcoe_hostlist_add() both ++ * need to be atomic with respect to other changes to the ++ * hostlist since fcoe_em_alloc() looks for an existing EM ++ * instance on host list updated by fcoe_hostlist_add(). ++ * ++ * This is currently handled through the fcoe_config_mutex ++ * begin held. ++ */ - dev_hold(netdev); -+ /* lport exch manager allocation */ -+ rc = fcoe_em_config(lport); -+ if (rc) { -+ FCOE_NETDEV_DBG(netdev, "Could not configure the EM for the " -+ "interface\n"); -+ goto out_lp_destroy; ++ /* lport exch manager allocation */ ++ rc = fcoe_em_config(lport); ++ if (rc) { ++ FCOE_NETDEV_DBG(netdev, "Could not configure the EM " ++ "for the interface\n"); ++ goto out_lp_destroy; ++ } + } - return rc; @@ -824534,15 +887082,59 @@ index 0a5609b..704b8e0 100644 } /** -@@ -669,6 +812,7 @@ static int __init fcoe_if_init(void) +- * fcoe_if_init() - attach to scsi transport ++ * fcoe_if_init() - Initialization routine for fcoe.ko + * +- * Returns : 0 on success ++ * Attaches the SW FCoE transport to the FC transport ++ * ++ * Returns: 0 on success + */ + static int __init fcoe_if_init(void) + { + /* attach to scsi transport */ +- scsi_transport_fcoe_sw = +- fc_attach_transport(&fcoe_transport_function); ++ fcoe_transport_template = fc_attach_transport(&fcoe_transport_function); ++ fcoe_vport_transport_template = ++ fc_attach_transport(&fcoe_vport_transport_function); + +- if (!scsi_transport_fcoe_sw) { ++ if (!fcoe_transport_template) { + printk(KERN_ERR "fcoe: Failed to attach to the FC transport\n"); + return -ENODEV; + } +@@ -662,19 +947,24 @@ static int __init fcoe_if_init(void) + } + + /** +- * fcoe_if_exit() - detach from scsi transport ++ * fcoe_if_exit() - Tear down fcoe.ko ++ * ++ * Detaches the SW FCoE transport from the FC transport + * +- * Returns : 0 on success ++ * Returns: 0 on success + */ int __exit fcoe_if_exit(void) { - fc_release_transport(scsi_transport_fcoe_sw); -+ scsi_transport_fcoe_sw = NULL; +- fc_release_transport(scsi_transport_fcoe_sw); ++ fc_release_transport(fcoe_transport_template); ++ fc_release_transport(fcoe_vport_transport_template); ++ fcoe_transport_template = NULL; ++ fcoe_vport_transport_template = NULL; return 0; } -@@ -686,7 +830,7 @@ static void fcoe_percpu_thread_create(unsigned int cpu) + /** +- * fcoe_percpu_thread_create() - Create a receive thread for an online cpu +- * @cpu: cpu index for the online cpu ++ * fcoe_percpu_thread_create() - Create a receive thread for an online CPU ++ * @cpu: The CPU index of the CPU to create a receive thread for + */ + static void fcoe_percpu_thread_create(unsigned int cpu) + { +@@ -686,7 +976,7 @@ static void fcoe_percpu_thread_create(unsigned int cpu) thread = kthread_create(fcoe_percpu_receive_thread, (void *)p, "fcoethread/%d", cpu); @@ -824551,9 +887143,76 @@ index 0a5609b..704b8e0 100644 kthread_bind(thread, cpu); wake_up_process(thread); -@@ -838,14 +982,13 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, +@@ -697,8 +987,8 @@ static void fcoe_percpu_thread_create(unsigned int cpu) + } + + /** +- * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu +- * @cpu: cpu index the rx thread is to be removed ++ * fcoe_percpu_thread_destroy() - Remove the receive thread of a CPU ++ * @cpu: The CPU index of the CPU whose receive thread is to be destroyed + * + * Destroys a per-CPU Rx thread. Any pending skbs are moved to the + * current CPU's Rx thread. If the thread being destroyed is bound to +@@ -746,7 +1036,7 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) + } else { + /* + * The targeted CPU is not initialized and cannot accept +- * new skbs. Unlock the targeted CPU and drop the skbs ++ * new skbs. Unlock the targeted CPU and drop the skbs + * on the CPU that is going offline. + */ + while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL) +@@ -787,12 +1077,12 @@ static void fcoe_percpu_thread_destroy(unsigned int cpu) + } + + /** +- * fcoe_cpu_callback() - fcoe cpu hotplug event callback +- * @nfb: callback data block +- * @action: event triggering the callback +- * @hcpu: index for the cpu of this event ++ * fcoe_cpu_callback() - Handler for CPU hotplug events ++ * @nfb: The callback data block ++ * @action: The event triggering the callback ++ * @hcpu: The index of the CPU that the event is for + * +- * This creates or destroys per cpu data for fcoe ++ * This creates or destroys per-CPU data for fcoe + * + * Returns NOTIFY_OK always. + */ +@@ -818,42 +1108,38 @@ static int fcoe_cpu_callback(struct notifier_block *nfb, + return NOTIFY_OK; + } + +-static struct notifier_block fcoe_cpu_notifier = { +- .notifier_call = fcoe_cpu_callback, +-}; +- + /** +- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ +- * @skb: the receive skb +- * @dev: associated net device +- * @ptype: context +- * @olddev: last device ++ * fcoe_rcv() - Receive packets from a net device ++ * @skb: The received packet ++ * @netdev: The net device that the packet was received on ++ * @ptype: The packet type context ++ * @olddev: The last device net device + * +- * this function will receive the packet and build fc frame and pass it up ++ * This routine is called by NET_RX_SOFTIRQ. It receives a packet, builds a ++ * FC frame and passes the frame to libfc. + * + * Returns: 0 for success + */ +-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, ++int fcoe_rcv(struct sk_buff *skb, struct net_device *netdev, + struct packet_type *ptype, struct net_device *olddev) { - struct fc_lport *lp; +- struct fc_lport *lp; ++ struct fc_lport *lport; struct fcoe_rcv_info *fr; - struct fcoe_softc *fc; + struct fcoe_interface *fcoe; @@ -824565,19 +887224,48 @@ index 0a5609b..704b8e0 100644 - fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type); - lp = fc->ctlr.lp; +- if (unlikely(lp == NULL)) { +- FCOE_NETDEV_DBG(dev, "Cannot find hba structure"); + fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); -+ lp = fcoe->ctlr.lp; - if (unlikely(lp == NULL)) { - FCOE_NETDEV_DBG(dev, "Cannot find hba structure"); ++ lport = fcoe->ctlr.lp; ++ if (unlikely(!lport)) { ++ FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); goto err2; -@@ -876,20 +1019,20 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + } +- if (!lp->link_up) ++ if (!lport->link_up) + goto err2; + +- FCOE_NETDEV_DBG(dev, "skb_info: len:%d data_len:%d head:%p " ++ FCOE_NETDEV_DBG(netdev, "skb_info: len:%d data_len:%d head:%p " + "data:%p tail:%p end:%p sum:%d dev:%s", + skb->len, skb->data_len, skb->head, skb->data, + skb_tail_pointer(skb), skb_end_pointer(skb), +@@ -861,7 +1147,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + + /* check for FCOE packet type */ + if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { +- FCOE_NETDEV_DBG(dev, "Wrong FC type frame"); ++ FCOE_NETDEV_DBG(netdev, "Wrong FC type frame"); + goto err; + } + +@@ -870,26 +1156,26 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + * and FC headers are pulled into the linear data area. + */ + if (unlikely((skb->len < FCOE_MIN_FRAME) || +- !pskb_may_pull(skb, FCOE_HEADER_LEN))) ++ !pskb_may_pull(skb, FCOE_HEADER_LEN))) + goto err; + skb_set_transport_header(skb, sizeof(struct fcoe_hdr)); fh = (struct fc_frame_header *) skb_transport_header(skb); - oxid = ntohs(fh->fh_ox_id); - fr = fcoe_dev_from_skb(skb); - fr->fr_dev = lp; +- fr->fr_dev = lp; ++ fr->fr_dev = lport; fr->ptype = ptype; -#ifdef CONFIG_SMP @@ -824599,30 +887287,111 @@ index 0a5609b..704b8e0 100644 fps = &per_cpu(fcoe_percpu, cpu); spin_lock_bh(&fps->fcoe_rx_list.lock); -@@ -996,7 +1139,7 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) - * fcoe_fc_crc() - calculates FC CRC in this fcoe skb - * @fp: the fc_frame containing data to be checksummed - * -- * This uses crc32() to calculate the crc for fc frame -+ * This uses crc32() to calculate the crc for port frame - * Return : 32 bit crc - */ - u32 fcoe_fc_crc(struct fc_frame *fp) -@@ -1029,7 +1172,7 @@ u32 fcoe_fc_crc(struct fc_frame *fp) +@@ -899,7 +1185,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + * the first CPU now. For non-SMP systems this + * will check the same CPU twice. + */ +- FCOE_NETDEV_DBG(dev, "CPU is online, but no receive thread " ++ FCOE_NETDEV_DBG(netdev, "CPU is online, but no receive thread " + "ready for incoming skb- using first online " + "CPU.\n"); + +@@ -926,7 +1212,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev, + + return 0; + err: +- fc_lport_get_stats(lp)->ErrorFrames++; ++ fc_lport_get_stats(lport)->ErrorFrames++; + + err2: + kfree_skb(skb); +@@ -934,17 +1220,21 @@ err2: + } /** - * fcoe_xmit() - FCoE frame transmit function -- * @lp: the associated local port -+ * @lp: the associated local fcoe - * @fp: the fc_frame to be transmitted +- * fcoe_start_io() - pass to netdev to start xmit for fcoe +- * @skb: the skb to be xmitted ++ * fcoe_start_io() - Start FCoE I/O ++ * @skb: The packet to be transmitted ++ * ++ * This routine is called from the net device to start transmitting ++ * FCoE packets. * - * Return : 0 for success -@@ -1046,13 +1189,13 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + * Returns: 0 for success + */ + static inline int fcoe_start_io(struct sk_buff *skb) + { ++ struct sk_buff *nskb; + int rc; + +- skb_get(skb); +- rc = dev_queue_xmit(skb); ++ nskb = skb_clone(skb, GFP_ATOMIC); ++ rc = dev_queue_xmit(nskb); + if (rc != 0) + return rc; + kfree_skb(skb); +@@ -952,9 +1242,15 @@ static inline int fcoe_start_io(struct sk_buff *skb) + } + + /** +- * fcoe_get_paged_crc_eof() - in case we need to alloc a page for crc_eof +- * @skb: the skb to be xmitted +- * @tlen: total len ++ * fcoe_get_paged_crc_eof() - Allocate a page to be used for the trailer CRC ++ * @skb: The packet to be transmitted ++ * @tlen: The total length of the trailer ++ * ++ * This routine allocates a page for frame trailers. The page is re-used if ++ * there is enough room left on it for the current trailer. If there isn't ++ * enough buffer left a new page is allocated for the trailer. Reference to ++ * the page from this function as well as the skbs using the page fragments ++ * ensure that the page is freed at the appropriate time. + * + * Returns: 0 for success + */ +@@ -993,11 +1289,12 @@ static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen) + } + + /** +- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb +- * @fp: the fc_frame containing data to be checksummed ++ * fcoe_fc_crc() - Calculates the CRC for a given frame ++ * @fp: The frame to be checksumed ++ * ++ * This uses crc32() routine to calculate the CRC for a frame + * +- * This uses crc32() to calculate the crc for fc frame +- * Return : 32 bit crc ++ * Return: The 32 bit CRC value + */ + u32 fcoe_fc_crc(struct fc_frame *fp) + { +@@ -1028,13 +1325,13 @@ u32 fcoe_fc_crc(struct fc_frame *fp) + } + + /** +- * fcoe_xmit() - FCoE frame transmit function +- * @lp: the associated local port +- * @fp: the fc_frame to be transmitted ++ * fcoe_xmit() - Transmit a FCoE frame ++ * @lport: The local port that the frame is to be transmitted for ++ * @fp: The frame to be transmitted + * +- * Return : 0 for success ++ * Return: 0 for success + */ +-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) ++int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) + { + int wlen; + u32 crc; +@@ -1046,24 +1343,24 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) unsigned int hlen; /* header length implies the version */ unsigned int tlen; /* trailer length */ unsigned int elen; /* eth header, may include vlan */ - struct fcoe_softc *fc; -+ struct fcoe_port *port = lport_priv(lp); ++ struct fcoe_port *port = lport_priv(lport); + struct fcoe_interface *fcoe = port->fcoe; u8 sof, eof; struct fcoe_hdr *hp; @@ -824633,16 +887402,29 @@ index 0a5609b..704b8e0 100644 fh = fc_frame_header_get(fp); skb = fp_skb(fp); wlen = skb->len / FCOE_WORD_TO_BYTE; -@@ -1063,7 +1206,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + +- if (!lp->link_up) { ++ if (!lport->link_up) { + kfree_skb(skb); + return 0; } if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) && - fcoe_ctlr_els_send(&fc->ctlr, skb)) -+ fcoe_ctlr_els_send(&fcoe->ctlr, skb)) ++ fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) return 0; sof = fr_sof(fp); -@@ -1085,7 +1228,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) +@@ -1075,7 +1372,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE; + + /* crc offload */ +- if (likely(lp->crc_offload)) { ++ if (likely(lport->crc_offload)) { + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = skb_headroom(skb); + skb->csum_offset = skb->len; +@@ -1085,7 +1382,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) crc = fcoe_fc_crc(fp); } @@ -824651,7 +887433,7 @@ index 0a5609b..704b8e0 100644 if (skb_is_nonlinear(skb)) { skb_frag_t *frag; if (fcoe_get_paged_crc_eof(skb, tlen)) { -@@ -1108,27 +1251,27 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) +@@ -1108,27 +1405,27 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) cp = NULL; } @@ -824682,41 +887464,50 @@ index 0a5609b..704b8e0 100644 + memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); else - memcpy(eh->h_source, fc->ctlr.data_src_addr, ETH_ALEN); -+ memcpy(eh->h_source, fcoe->ctlr.data_src_addr, ETH_ALEN); ++ memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); hp = (struct fcoe_hdr *)(eh + 1); memset(hp, 0, sizeof(*hp)); -@@ -1136,7 +1279,6 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) +@@ -1136,34 +1433,41 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER); hp->fcoe_sof = sof; -#ifdef NETIF_F_FSO /* fcoe lso, mss is in max_payload which is non-zero for FCP data */ - if (lp->seq_offload && fr_max_payload(fp)) { +- if (lp->seq_offload && fr_max_payload(fp)) { ++ if (lport->seq_offload && fr_max_payload(fp)) { skb_shinfo(skb)->gso_type = SKB_GSO_FCOE; -@@ -1145,7 +1287,6 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + skb_shinfo(skb)->gso_size = fr_max_payload(fp); + } else { skb_shinfo(skb)->gso_type = 0; skb_shinfo(skb)->gso_size = 0; } -#endif /* update tx stats: regardless if LLD fails */ - stats = fc_lport_get_stats(lp); +- stats = fc_lport_get_stats(lp); ++ stats = fc_lport_get_stats(lport); stats->TxFrames++; -@@ -1153,7 +1294,7 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) + stats->TxWords += wlen; /* send down to lld */ - fr_dev(fp) = lp; +- fr_dev(fp) = lp; - if (fc->fcoe_pending_queue.qlen) +- fcoe_check_wait_queue(lp, skb); ++ fr_dev(fp) = lport; + if (port->fcoe_pending_queue.qlen) - fcoe_check_wait_queue(lp, skb); ++ fcoe_check_wait_queue(lport, skb); else if (fcoe_start_io(skb)) - fcoe_check_wait_queue(lp, skb); -@@ -1162,6 +1303,15 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp) +- fcoe_check_wait_queue(lp, skb); ++ fcoe_check_wait_queue(lport, skb); + + return 0; } /** -+ * fcoe_percpu_flush_done() - Indicate percpu queue flush completion. -+ * @skb: the skb being completed. +- * fcoe_percpu_receive_thread() - recv thread per cpu +- * @arg: ptr to the fcoe per cpu struct ++ * fcoe_percpu_flush_done() - Indicate per-CPU queue flush completion ++ * @skb: The completed skb (argument required by destructor) + */ +static void fcoe_percpu_flush_done(struct sk_buff *skb) +{ @@ -824724,10 +887515,21 @@ index 0a5609b..704b8e0 100644 +} + +/** - * fcoe_percpu_receive_thread() - recv thread per cpu - * @arg: ptr to the fcoe per cpu struct ++ * fcoe_percpu_receive_thread() - The per-CPU packet receive thread ++ * @arg: The per-CPU context * -@@ -1179,7 +1329,7 @@ int fcoe_percpu_receive_thread(void *arg) + * Return: 0 for success + */ +@@ -1171,7 +1475,7 @@ int fcoe_percpu_receive_thread(void *arg) + { + struct fcoe_percpu_s *p = arg; + u32 fr_len; +- struct fc_lport *lp; ++ struct fc_lport *lport; + struct fcoe_rcv_info *fr; + struct fcoe_dev_stats *stats; + struct fc_frame_header *fh; +@@ -1179,7 +1483,7 @@ int fcoe_percpu_receive_thread(void *arg) struct fcoe_crc_eof crc_eof; struct fc_frame *fp; u8 *mac = NULL; @@ -824736,56 +887538,107 @@ index 0a5609b..704b8e0 100644 struct fcoe_hdr *hp; set_user_nice(current, -20); -@@ -1200,7 +1350,8 @@ int fcoe_percpu_receive_thread(void *arg) +@@ -1198,9 +1502,10 @@ int fcoe_percpu_receive_thread(void *arg) + } + spin_unlock_bh(&p->fcoe_rx_list.lock); fr = fcoe_dev_from_skb(skb); - lp = fr->fr_dev; - if (unlikely(lp == NULL)) { +- lp = fr->fr_dev; +- if (unlikely(lp == NULL)) { - FCOE_NETDEV_DBG(skb->dev, "Invalid HBA Structure"); ++ lport = fr->fr_dev; ++ if (unlikely(!lport)) { + if (skb->destructor != fcoe_percpu_flush_done) + FCOE_NETDEV_DBG(skb->dev, "NULL lport in skb"); kfree_skb(skb); continue; } -@@ -1215,7 +1366,7 @@ int fcoe_percpu_receive_thread(void *arg) +@@ -1215,7 +1520,7 @@ int fcoe_percpu_receive_thread(void *arg) /* * Save source MAC address before discarding header. */ - fc = lport_priv(lp); -+ port = lport_priv(lp); ++ port = lport_priv(lport); if (skb_is_nonlinear(skb)) skb_linearize(skb); /* not ideal */ mac = eth_hdr(skb)->h_source; -@@ -1277,7 +1428,7 @@ int fcoe_percpu_receive_thread(void *arg) +@@ -1227,7 +1532,7 @@ int fcoe_percpu_receive_thread(void *arg) + hp = (struct fcoe_hdr *) skb_network_header(skb); + fh = (struct fc_frame_header *) skb_transport_header(skb); + +- stats = fc_lport_get_stats(lp); ++ stats = fc_lport_get_stats(lport); + if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { + if (stats->ErrorFrames < 5) + printk(KERN_WARNING "fcoe: FCoE version " +@@ -1249,7 +1554,7 @@ int fcoe_percpu_receive_thread(void *arg) + + fp = (struct fc_frame *)skb; + fc_frame_init(fp); +- fr_dev(fp) = lp; ++ fr_dev(fp) = lport; + fr_sof(fp) = hp->fcoe_sof; + + /* Copy out the CRC and EOF trailer for access */ +@@ -1269,7 +1574,8 @@ int fcoe_percpu_receive_thread(void *arg) + * it's solicited data, in which case, the FCP layer would + * check it during the copy. + */ +- if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY) ++ if (lport->crc_offload && ++ skb->ip_summed == CHECKSUM_UNNECESSARY) + fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; + else + fr_flags(fp) |= FCPHF_CRC_UNCHECKED; +@@ -1277,7 +1583,7 @@ int fcoe_percpu_receive_thread(void *arg) fh = fc_frame_header_get(fp); if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA && fh->fh_type == FC_TYPE_FCP) { - fc_exch_recv(lp, lp->emp, fp); -+ fc_exch_recv(lp, fp); ++ fc_exch_recv(lport, fp); continue; } if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { -@@ -1293,12 +1444,12 @@ int fcoe_percpu_receive_thread(void *arg) +@@ -1293,76 +1599,71 @@ int fcoe_percpu_receive_thread(void *arg) } fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED; } - if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN) && - fcoe_ctlr_recv_flogi(&fc->ctlr, fp, mac)) { -+ if (unlikely(port->fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN) && -+ fcoe_ctlr_recv_flogi(&port->fcoe->ctlr, fp, mac)) { - fc_frame_free(fp); - continue; - } +- fc_frame_free(fp); +- continue; +- } - fc_exch_recv(lp, lp->emp, fp); -+ fc_exch_recv(lp, fp); ++ fc_exch_recv(lport, fp); } return 0; } -@@ -1318,46 +1469,46 @@ int fcoe_percpu_receive_thread(void *arg) + + /** +- * fcoe_check_wait_queue() - attempt to clear the transmit backlog +- * @lp: the fc_lport ++ * fcoe_check_wait_queue() - Attempt to clear the transmit backlog ++ * @lport: The local port whose backlog is to be cleared + * +- * This empties the wait_queue, dequeue the head of the wait_queue queue +- * and calls fcoe_start_io() for each packet, if all skb have been +- * transmitted, return qlen or -1 if a error occurs, then restore +- * wait_queue and try again later. ++ * This empties the wait_queue, dequeues the head of the wait_queue queue ++ * and calls fcoe_start_io() for each packet. If all skb have been ++ * transmitted it returns the qlen. If an error occurs it restores ++ * wait_queue (to try again later) and returns -1. + * +- * The wait_queue is used when the skb transmit fails. skb will go +- * in the wait_queue which will be emptied by the timer function or ++ * The wait_queue is used when the skb transmit fails. The failed skb ++ * will go in the wait_queue which will be emptied by the timer function or + * by the next skb transmit. */ - static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) +-static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) ++static void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb) { - struct fcoe_softc *fc = lport_priv(lp); -+ struct fcoe_port *port = lport_priv(lp); ++ struct fcoe_port *port = lport_priv(lport); int rc; - spin_lock_bh(&fc->fcoe_pending_queue.lock); @@ -824829,29 +887682,65 @@ index 0a5609b..704b8e0 100644 } - if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) -+ if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) - lp->qfull = 0; +- lp->qfull = 0; - if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer)) - mod_timer(&fc->timer, jiffies + 2); - fc->fcoe_pending_queue_active = 0; ++ if (port->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) ++ lport->qfull = 0; + if (port->fcoe_pending_queue.qlen && !timer_pending(&port->timer)) + mod_timer(&port->timer, jiffies + 2); + port->fcoe_pending_queue_active = 0; out: - if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) -+ if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) - lp->qfull = 1; +- lp->qfull = 1; - spin_unlock_bh(&fc->fcoe_pending_queue.lock); ++ if (port->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) ++ lport->qfull = 1; + spin_unlock_bh(&port->fcoe_pending_queue.lock); return; } -@@ -1391,21 +1542,20 @@ static int fcoe_device_notification(struct notifier_block *notifier, + /** +- * fcoe_dev_setup() - setup link change notification interface ++ * fcoe_dev_setup() - Setup the link change notification interface + */ + static void fcoe_dev_setup(void) + { +@@ -1370,7 +1671,7 @@ static void fcoe_dev_setup(void) + } + + /** +- * fcoe_dev_cleanup() - cleanup link change notification interface ++ * fcoe_dev_cleanup() - Cleanup the link change notification interface + */ + static void fcoe_dev_cleanup(void) + { +@@ -1378,35 +1679,34 @@ static void fcoe_dev_cleanup(void) + } + + /** +- * fcoe_device_notification() - netdev event notification callback +- * @notifier: context of the notification +- * @event: type of event +- * @ptr: fixed array for output parsed ifname ++ * fcoe_device_notification() - Handler for net device events ++ * @notifier: The context of the notification ++ * @event: The type of event ++ * @ptr: The net device that the event was on + * +- * This function is called by the ethernet driver in case of link change event ++ * This function is called by the Ethernet driver in case of link change event. + * + * Returns: 0 for success + */ + static int fcoe_device_notification(struct notifier_block *notifier, ulong event, void *ptr) { - struct fc_lport *lp = NULL; +- struct fc_lport *lp = NULL; - struct net_device *real_dev = ptr; - struct fcoe_softc *fc; ++ struct fc_lport *lport = NULL; + struct net_device *netdev = ptr; + struct fcoe_interface *fcoe; + struct fcoe_port *port; @@ -824866,15 +887755,17 @@ index 0a5609b..704b8e0 100644 - lp = fc->ctlr.lp; + list_for_each_entry(fcoe, &fcoe_hostlist, list) { + if (fcoe->netdev == netdev) { -+ lp = fcoe->ctlr.lp; ++ lport = fcoe->ctlr.lp; break; } } - read_unlock(&fcoe_hostlist_lock); - if (lp == NULL) { +- if (lp == NULL) { ++ if (!lport) { rc = NOTIFY_DONE; goto out; -@@ -1420,21 +1570,27 @@ static int fcoe_device_notification(struct notifier_block *notifier, + } +@@ -1420,34 +1720,40 @@ static int fcoe_device_notification(struct notifier_block *notifier, case NETDEV_CHANGE: break; case NETDEV_CHANGEMTU: @@ -824884,7 +887775,8 @@ index 0a5609b..704b8e0 100644 + mfs = netdev->mtu - (sizeof(struct fcoe_hdr) + + sizeof(struct fcoe_crc_eof)); if (mfs >= FC_MIN_MAX_FRAME) - fc_set_mfs(lp, mfs); +- fc_set_mfs(lp, mfs); ++ fc_set_mfs(lport, mfs); break; case NETDEV_REGISTER: break; @@ -824900,21 +887792,43 @@ index 0a5609b..704b8e0 100644 + FCOE_NETDEV_DBG(netdev, "Unknown event %ld " "from netdev netlink\n", event); } - if (link_possible && !fcoe_link_ok(lp)) +- if (link_possible && !fcoe_link_ok(lp)) - fcoe_ctlr_link_up(&fc->ctlr); - else if (fcoe_ctlr_link_down(&fc->ctlr)) { +- stats = fc_lport_get_stats(lp); ++ if (link_possible && !fcoe_link_ok(lport)) + fcoe_ctlr_link_up(&fcoe->ctlr); + else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { - stats = fc_lport_get_stats(lp); ++ stats = fc_lport_get_stats(lport); stats->LinkFailureCount++; - fcoe_clean_pending_queue(lp); -@@ -1465,75 +1621,6 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) +- fcoe_clean_pending_queue(lp); ++ fcoe_clean_pending_queue(lport); + } + out: + return rc; + } + + /** +- * fcoe_if_to_netdev() - parse a name buffer to get netdev +- * @buffer: incoming buffer to be copied ++ * fcoe_if_to_netdev() - Parse a name buffer to get a net device ++ * @buffer: The name of the net device + * +- * Returns: NULL or ptr to net_device ++ * Returns: NULL or a ptr to net_device + */ + static struct net_device *fcoe_if_to_netdev(const char *buffer) + { +@@ -1465,160 +1771,158 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer) } /** - * fcoe_netdev_to_module_owner() - finds out the driver module of the netdev - * @netdev: the target netdev -- * ++ * fcoe_destroy() - Destroy a FCoE interface ++ * @buffer: The name of the Ethernet interface to be destroyed ++ * @kp: The associated kernel parameter + * - * Returns: ptr to the struct module, NULL for failure - */ -static struct module * @@ -824981,10 +887895,12 @@ index 0a5609b..704b8e0 100644 -} - -/** - * fcoe_destroy() - handles the destroy from sysfs - * @buffer: expected to be an eth if name - * @kp: associated kernel param -@@ -1542,34 +1629,57 @@ static int fcoe_ethdrv_put(const struct net_device *netdev) +- * fcoe_destroy() - handles the destroy from sysfs +- * @buffer: expected to be an eth if name +- * @kp: associated kernel param ++ * Called from sysfs. + * + * Returns: 0 for success */ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) { @@ -825041,6 +887957,13 @@ index 0a5609b..704b8e0 100644 return rc; } + /** +- * fcoe_create() - Handles the create call from sysfs +- * @buffer: expected to be an eth if name +- * @kp: associated kernel param ++ * fcoe_destroy_work() - Destroy a FCoE port in a deferred work context ++ * @work: Handle to the FCoE port to be destroyed ++ */ +static void fcoe_destroy_work(struct work_struct *work) +{ + struct fcoe_port *port; @@ -825051,10 +887974,15 @@ index 0a5609b..704b8e0 100644 + mutex_unlock(&fcoe_config_mutex); +} + - /** - * fcoe_create() - Handles the create call from sysfs - * @buffer: expected to be an eth if name -@@ -1580,41 +1690,84 @@ out_nodev: ++/** ++ * fcoe_create() - Create a fcoe interface ++ * @buffer: The name of the Ethernet interface to create on ++ * @kp: The associated kernel param ++ * ++ * Called from sysfs. + * + * Returns: 0 for success + */ static int fcoe_create(const char *buffer, struct kernel_param *kp) { int rc; @@ -825097,7 +888025,7 @@ index 0a5609b..704b8e0 100644 + goto out_putdev; + } + -+ lport = fcoe_if_create(fcoe, &netdev->dev); ++ lport = fcoe_if_create(fcoe, &netdev->dev, 0); + if (IS_ERR(lport)) { printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", netdev->name); @@ -825135,25 +888063,32 @@ index 0a5609b..704b8e0 100644 return rc; } - module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); - __MODULE_PARM_TYPE(create, "string"); +-module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR); +-__MODULE_PARM_TYPE(create, "string"); -MODULE_PARM_DESC(create, "Create fcoe port using net device passed in."); -+MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in."); - module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); - __MODULE_PARM_TYPE(destroy, "string"); +-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR); +-__MODULE_PARM_TYPE(destroy, "string"); -MODULE_PARM_DESC(destroy, "Destroy fcoe port"); -+MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe"); - +- /** - * fcoe_link_ok() - Check if link is ok for the fc_lport -@@ -1632,37 +1785,40 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port"); +- * fcoe_link_ok() - Check if link is ok for the fc_lport +- * @lp: ptr to the fc_lport ++ * fcoe_link_ok() - Check if the link is OK for a local port ++ * @lport: The local port to check link on + * + * Any permanently-disqualifying conditions have been previously checked. + * This also updates the speed setting, which may change with link for 100/1000. +@@ -1630,41 +1934,44 @@ MODULE_PARM_DESC(destroy, "Destroy fcoe port"); + * Returns: 0 if link is OK for use by FCoE. + * */ - int fcoe_link_ok(struct fc_lport *lp) +-int fcoe_link_ok(struct fc_lport *lp) ++int fcoe_link_ok(struct fc_lport *lport) { - struct fcoe_softc *fc = lport_priv(lp); - struct net_device *dev = fc->real_dev; -+ struct fcoe_port *port = lport_priv(lp); -+ struct net_device *dev = port->fcoe->netdev; ++ struct fcoe_port *port = lport_priv(lport); ++ struct net_device *netdev = port->fcoe->netdev; struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - int rc = 0; @@ -825176,20 +888111,20 @@ index 0a5609b..704b8e0 100644 - } - } else - rc = -1; -+ if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && -+ (!dev_ethtool_get_settings(dev, &ecmd))) { -+ lp->link_supported_speeds &= ++ if ((netdev->flags & IFF_UP) && netif_carrier_ok(netdev) && ++ (!dev_ethtool_get_settings(netdev, &ecmd))) { ++ lport->link_supported_speeds &= + ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); + if (ecmd.supported & (SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full)) -+ lp->link_supported_speeds |= FC_PORTSPEED_1GBIT; ++ lport->link_supported_speeds |= FC_PORTSPEED_1GBIT; + if (ecmd.supported & SUPPORTED_10000baseT_Full) -+ lp->link_supported_speeds |= ++ lport->link_supported_speeds |= + FC_PORTSPEED_10GBIT; + if (ecmd.speed == SPEED_1000) -+ lp->link_speed = FC_PORTSPEED_1GBIT; ++ lport->link_speed = FC_PORTSPEED_1GBIT; + if (ecmd.speed == SPEED_10000) -+ lp->link_speed = FC_PORTSPEED_10GBIT; ++ lport->link_speed = FC_PORTSPEED_10GBIT; - return rc; + return 0; @@ -825198,8 +888133,10 @@ index 0a5609b..704b8e0 100644 } /** - * fcoe_percpu_clean() - Clear the pending skbs for an lport - * @lp: the fc_lport +- * fcoe_percpu_clean() - Clear the pending skbs for an lport +- * @lp: the fc_lport ++ * fcoe_percpu_clean() - Clear all pending skbs for an local port ++ * @lport: The local port whose skbs are to be cleared + * + * Must be called with fcoe_create_mutex held to single-thread completion. + * @@ -825208,9 +888145,18 @@ index 0a5609b..704b8e0 100644 + * there no packets that will be handled by the lport, but also that any + * threads already handling packet have returned. */ - void fcoe_percpu_clean(struct fc_lport *lp) +-void fcoe_percpu_clean(struct fc_lport *lp) ++void fcoe_percpu_clean(struct fc_lport *lport) { -@@ -1687,7 +1843,25 @@ void fcoe_percpu_clean(struct fc_lport *lp) + struct fcoe_percpu_s *pp; + struct fcoe_rcv_info *fr; +@@ -1682,40 +1989,56 @@ void fcoe_percpu_clean(struct fc_lport *lp) + skb = next) { + next = skb->next; + fr = fcoe_dev_from_skb(skb); +- if (fr->fr_dev == lp) { ++ if (fr->fr_dev == lport) { + __skb_unlink(skb, list); kfree_skb(skb); } } @@ -825236,12 +888182,18 @@ index 0a5609b..704b8e0 100644 } } -@@ -1699,16 +1873,16 @@ void fcoe_percpu_clean(struct fc_lport *lp) + /** + * fcoe_clean_pending_queue() - Dequeue a skb and free it +- * @lp: the corresponding fc_lport +- * +- * Returns: none ++ * @lport: The local port to dequeue a skb on */ - void fcoe_clean_pending_queue(struct fc_lport *lp) +-void fcoe_clean_pending_queue(struct fc_lport *lp) ++void fcoe_clean_pending_queue(struct fc_lport *lport) { - struct fcoe_softc *fc = lport_priv(lp); -+ struct fcoe_port *port = lport_priv(lp); ++ struct fcoe_port *port = lport_priv(lport); struct sk_buff *skb; - spin_lock_bh(&fc->fcoe_pending_queue.lock); @@ -825259,22 +888211,34 @@ index 0a5609b..704b8e0 100644 } /** -@@ -1725,24 +1899,21 @@ int fcoe_reset(struct Scsi_Host *shost) +- * fcoe_reset() - Resets the fcoe +- * @shost: shost the reset is from ++ * fcoe_reset() - Reset a local port ++ * @shost: The SCSI host associated with the local port to be reset + * +- * Returns: always 0 ++ * Returns: Always 0 (return value required by FC transport template) + */ + int fcoe_reset(struct Scsi_Host *shost) + { +@@ -1725,94 +2048,77 @@ int fcoe_reset(struct Scsi_Host *shost) } /** - * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device -+ * fcoe_hostlist_lookup_port() - find the corresponding lport by a given device - * @dev: this is currently ptr to net_device +- * @dev: this is currently ptr to net_device ++ * fcoe_hostlist_lookup_port() - Find the FCoE interface associated with a net device ++ * @netdev: The net device used as a key ++ * ++ * Locking: Must be called with the RNL mutex held. * - * Returns: NULL or the located fcoe_softc -+ * Returns: NULL or the located fcoe_port -+ * Locking: must be called with the RNL mutex held ++ * Returns: NULL or the FCoE interface */ -static struct fcoe_softc * -fcoe_hostlist_lookup_softc(const struct net_device *dev) +static struct fcoe_interface * -+fcoe_hostlist_lookup_port(const struct net_device *dev) ++fcoe_hostlist_lookup_port(const struct net_device *netdev) { - struct fcoe_softc *fc; + struct fcoe_interface *fcoe; @@ -825286,18 +888250,24 @@ index 0a5609b..704b8e0 100644 - return fc; - } + list_for_each_entry(fcoe, &fcoe_hostlist, list) { -+ if (fcoe->netdev == dev) ++ if (fcoe->netdev == netdev) + return fcoe; } - read_unlock(&fcoe_hostlist_lock); return NULL; } -@@ -1751,14 +1922,14 @@ fcoe_hostlist_lookup_softc(const struct net_device *dev) - * @netdev: ptr to net_device + /** +- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev +- * @netdev: ptr to net_device ++ * fcoe_hostlist_lookup() - Find the local port associated with a ++ * given net device ++ * @netdev: The netdevice used as a key * - * Returns: 0 for success -+ * Locking: must be called with the RTNL mutex held +- * Returns: 0 for success ++ * Locking: Must be called with the RTNL mutex held ++ * ++ * Returns: NULL or the local port */ -struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) +static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) @@ -825313,15 +888283,16 @@ index 0a5609b..704b8e0 100644 } /** -@@ -1766,41 +1937,23 @@ struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) - * @lp: ptr to the fc_lport to be added +- * fcoe_hostlist_add() - Add a lport to lports list +- * @lp: ptr to the fc_lport to be added ++ * fcoe_hostlist_add() - Add the FCoE interface identified by a local ++ * port to the hostlist ++ * @lport: The local port that identifies the FCoE interface to be added * - * Returns: 0 for success -+ * Locking: must be called with the RTNL mutex held - */ +- * Returns: 0 for success +- */ -int fcoe_hostlist_add(const struct fc_lport *lp) -+static int fcoe_hostlist_add(const struct fc_lport *lport) - { +-{ - struct fcoe_softc *fc; - - fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); @@ -825330,26 +888301,20 @@ index 0a5609b..704b8e0 100644 - write_lock_bh(&fcoe_hostlist_lock); - list_add_tail(&fc->list, &fcoe_hostlist); - write_unlock_bh(&fcoe_hostlist_lock); -+ struct fcoe_interface *fcoe; -+ struct fcoe_port *port; -+ -+ fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); -+ if (!fcoe) { -+ port = lport_priv(lport); -+ fcoe = port->fcoe; -+ list_add_tail(&fcoe->list, &fcoe_hostlist); - } - return 0; - } - - /** +- } +- return 0; +-} +- +-/** - * fcoe_hostlist_remove() - remove a lport from lports list - * @lp: ptr to the fc_lport to be removed -- * -- * Returns: 0 for success -- */ ++ * Locking: must be called with the RTNL mutex held + * + * Returns: 0 for success + */ -int fcoe_hostlist_remove(const struct fc_lport *lp) --{ ++static int fcoe_hostlist_add(const struct fc_lport *lport) + { - struct fcoe_softc *fc; - - fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp)); @@ -825358,16 +888323,31 @@ index 0a5609b..704b8e0 100644 - list_del(&fc->list); - write_unlock_bh(&fcoe_hostlist_lock); - -- return 0; --} -- --/** - * fcoe_init() - fcoe module loading initialization ++ struct fcoe_interface *fcoe; ++ struct fcoe_port *port; ++ ++ fcoe = fcoe_hostlist_lookup_port(fcoe_netdev(lport)); ++ if (!fcoe) { ++ port = lport_priv(lport); ++ fcoe = port->fcoe; ++ list_add_tail(&fcoe->list, &fcoe_hostlist); ++ } + return 0; + } + + /** +- * fcoe_init() - fcoe module loading initialization ++ * fcoe_init() - Initialize fcoe.ko * - * Returns 0 on success, negative on failure -@@ -1811,8 +1964,7 @@ static int __init fcoe_init(void) +- * Returns 0 on success, negative on failure ++ * Returns: 0 on success, or a negative value on failure + */ + static int __init fcoe_init(void) + { ++ struct fcoe_percpu_s *p; + unsigned int cpu; int rc = 0; - struct fcoe_percpu_s *p; +- struct fcoe_percpu_s *p; - INIT_LIST_HEAD(&fcoe_hostlist); - rwlock_init(&fcoe_hostlist_lock); @@ -825375,7 +888355,7 @@ index 0a5609b..704b8e0 100644 for_each_possible_cpu(cpu) { p = &per_cpu(fcoe_percpu, cpu); -@@ -1830,15 +1982,18 @@ static int __init fcoe_init(void) +@@ -1830,42 +2136,263 @@ static int __init fcoe_init(void) /* Setup link change notification */ fcoe_dev_setup(); @@ -825396,13 +888376,20 @@ index 0a5609b..704b8e0 100644 return rc; } module_init(fcoe_init); -@@ -1851,21 +2006,36 @@ module_init(fcoe_init); + + /** +- * fcoe_exit() - fcoe module unloading cleanup ++ * fcoe_exit() - Clean up fcoe.ko + * +- * Returns 0 on success, negative on failure ++ * Returns: 0 on success or a negative value on failure + */ static void __exit fcoe_exit(void) { - unsigned int cpu; -- struct fcoe_softc *fc, *tmp; + struct fcoe_interface *fcoe, *tmp; + struct fcoe_port *port; + unsigned int cpu; +- struct fcoe_softc *fc, *tmp; + + mutex_lock(&fcoe_config_mutex); @@ -825433,17 +888420,226 @@ index 0a5609b..704b8e0 100644 + /* flush any asyncronous interface destroys, + * this should happen after the netdev notifier is unregistered */ + flush_scheduled_work(); ++ /* That will flush out all the N_Ports on the hostlist, but now we ++ * may have NPIV VN_Ports scheduled for destruction */ ++ flush_scheduled_work(); + + /* detach from scsi transport + * must happen after all destroys are done, therefor after the flush */ fcoe_if_exit(); } module_exit(fcoe_exit); ++ ++/** ++ * fcoe_flogi_resp() - FCoE specific FLOGI and FDISC response handler ++ * @seq: active sequence in the FLOGI or FDISC exchange ++ * @fp: response frame, or error encoded in a pointer (timeout) ++ * @arg: pointer the the fcoe_ctlr structure ++ * ++ * This handles MAC address managment for FCoE, then passes control on to ++ * the libfc FLOGI response handler. ++ */ ++static void fcoe_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) ++{ ++ struct fcoe_ctlr *fip = arg; ++ struct fc_exch *exch = fc_seq_exch(seq); ++ struct fc_lport *lport = exch->lp; ++ u8 *mac; ++ ++ if (IS_ERR(fp)) ++ goto done; ++ ++ mac = fr_cb(fp)->granted_mac; ++ if (is_zero_ether_addr(mac)) { ++ /* pre-FIP */ ++ mac = eth_hdr(&fp->skb)->h_source; ++ if (fcoe_ctlr_recv_flogi(fip, lport, fp, mac)) { ++ fc_frame_free(fp); ++ return; ++ } ++ } else { ++ /* FIP, libfcoe has already seen it */ ++ fip->update_mac(lport, fr_cb(fp)->granted_mac); ++ } ++done: ++ fc_lport_flogi_resp(seq, fp, lport); ++} ++ ++/** ++ * fcoe_logo_resp() - FCoE specific LOGO response handler ++ * @seq: active sequence in the LOGO exchange ++ * @fp: response frame, or error encoded in a pointer (timeout) ++ * @arg: pointer the the fcoe_ctlr structure ++ * ++ * This handles MAC address managment for FCoE, then passes control on to ++ * the libfc LOGO response handler. ++ */ ++static void fcoe_logo_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg) ++{ ++ struct fcoe_ctlr *fip = arg; ++ struct fc_exch *exch = fc_seq_exch(seq); ++ struct fc_lport *lport = exch->lp; ++ static u8 zero_mac[ETH_ALEN] = { 0 }; ++ ++ if (!IS_ERR(fp)) ++ fip->update_mac(lport, zero_mac); ++ fc_lport_logo_resp(seq, fp, lport); ++} ++ ++/** ++ * fcoe_elsct_send - FCoE specific ELS handler ++ * ++ * This does special case handling of FIP encapsualted ELS exchanges for FCoE, ++ * using FCoE specific response handlers and passing the FIP controller as ++ * the argument (the lport is still available from the exchange). ++ * ++ * Most of the work here is just handed off to the libfc routine. ++ */ ++static struct fc_seq *fcoe_elsct_send(struct fc_lport *lport, u32 did, ++ struct fc_frame *fp, unsigned int op, ++ void (*resp)(struct fc_seq *, ++ struct fc_frame *, ++ void *), ++ void *arg, u32 timeout) ++{ ++ struct fcoe_port *port = lport_priv(lport); ++ struct fcoe_interface *fcoe = port->fcoe; ++ struct fcoe_ctlr *fip = &fcoe->ctlr; ++ struct fc_frame_header *fh = fc_frame_header_get(fp); ++ ++ switch (op) { ++ case ELS_FLOGI: ++ case ELS_FDISC: ++ return fc_elsct_send(lport, did, fp, op, fcoe_flogi_resp, ++ fip, timeout); ++ case ELS_LOGO: ++ /* only hook onto fabric logouts, not port logouts */ ++ if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI) ++ break; ++ return fc_elsct_send(lport, did, fp, op, fcoe_logo_resp, ++ fip, timeout); ++ } ++ return fc_elsct_send(lport, did, fp, op, resp, arg, timeout); ++} ++ ++/** ++ * fcoe_vport_create() - create an fc_host/scsi_host for a vport ++ * @vport: fc_vport object to create a new fc_host for ++ * @disabled: start the new fc_host in a disabled state by default? ++ * ++ * Returns: 0 for success ++ */ ++static int fcoe_vport_create(struct fc_vport *vport, bool disabled) ++{ ++ struct Scsi_Host *shost = vport_to_shost(vport); ++ struct fc_lport *n_port = shost_priv(shost); ++ struct fcoe_port *port = lport_priv(n_port); ++ struct fcoe_interface *fcoe = port->fcoe; ++ struct net_device *netdev = fcoe->netdev; ++ struct fc_lport *vn_port; ++ ++ mutex_lock(&fcoe_config_mutex); ++ vn_port = fcoe_if_create(fcoe, &vport->dev, 1); ++ mutex_unlock(&fcoe_config_mutex); ++ ++ if (IS_ERR(vn_port)) { ++ printk(KERN_ERR "fcoe: fcoe_vport_create(%s) failed\n", ++ netdev->name); ++ return -EIO; ++ } ++ ++ if (disabled) { ++ fc_vport_set_state(vport, FC_VPORT_DISABLED); ++ } else { ++ vn_port->boot_time = jiffies; ++ fc_fabric_login(vn_port); ++ fc_vport_setlink(vn_port); ++ } ++ return 0; ++} ++ ++/** ++ * fcoe_vport_destroy() - destroy the fc_host/scsi_host for a vport ++ * @vport: fc_vport object that is being destroyed ++ * ++ * Returns: 0 for success ++ */ ++static int fcoe_vport_destroy(struct fc_vport *vport) ++{ ++ struct Scsi_Host *shost = vport_to_shost(vport); ++ struct fc_lport *n_port = shost_priv(shost); ++ struct fc_lport *vn_port = vport->dd_data; ++ struct fcoe_port *port = lport_priv(vn_port); ++ ++ mutex_lock(&n_port->lp_mutex); ++ list_del(&vn_port->list); ++ mutex_unlock(&n_port->lp_mutex); ++ schedule_work(&port->destroy_work); ++ return 0; ++} ++ ++/** ++ * fcoe_vport_disable() - change vport state ++ * @vport: vport to bring online/offline ++ * @disable: should the vport be disabled? ++ */ ++static int fcoe_vport_disable(struct fc_vport *vport, bool disable) ++{ ++ struct fc_lport *lport = vport->dd_data; ++ ++ if (disable) { ++ fc_vport_set_state(vport, FC_VPORT_DISABLED); ++ fc_fabric_logoff(lport); ++ } else { ++ lport->boot_time = jiffies; ++ fc_fabric_login(lport); ++ fc_vport_setlink(lport); ++ } ++ ++ return 0; ++} ++ ++/** ++ * fcoe_vport_set_symbolic_name() - append vport string to symbolic name ++ * @vport: fc_vport with a new symbolic name string ++ * ++ * After generating a new symbolic name string, a new RSPN_ID request is ++ * sent to the name server. There is no response handler, so if it fails ++ * for some reason it will not be retried. ++ */ ++static void fcoe_set_vport_symbolic_name(struct fc_vport *vport) ++{ ++ struct fc_lport *lport = vport->dd_data; ++ struct fc_frame *fp; ++ size_t len; ++ ++ snprintf(fc_host_symbolic_name(lport->host), FC_SYMBOLIC_NAME_SIZE, ++ "%s v%s over %s : %s", FCOE_NAME, FCOE_VERSION, ++ fcoe_netdev(lport)->name, vport->symbolic_name); ++ ++ if (lport->state != LPORT_ST_READY) ++ return; ++ ++ len = strnlen(fc_host_symbolic_name(lport->host), 255); ++ fp = fc_frame_alloc(lport, ++ sizeof(struct fc_ct_hdr) + ++ sizeof(struct fc_ns_rspn) + len); ++ if (!fp) ++ return; ++ lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID, ++ NULL, NULL, lport->e_d_tov); ++} diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h -index 0d724fa..ce7f60f 100644 +index 0d724fa..fc2da8a 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h -@@ -37,8 +37,8 @@ +@@ -32,19 +32,19 @@ + #define FCOE_NAME "fcoe" + #define FCOE_VENDOR "Open-FCoE.org" + +-#define FCOE_MAX_LUN 255 ++#define FCOE_MAX_LUN 0xFFFF + #define FCOE_MAX_FCP_TARGET 256 #define FCOE_MAX_OUTSTANDING_COMMANDS 1024 @@ -825454,6 +888650,13 @@ index 0d724fa..ce7f60f 100644 unsigned int fcoe_debug_logging; module_param_named(debug_logging, fcoe_debug_logging, int, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); + +-#define FCOE_LOGGING 0x01 /* General logging, not categorized */ ++#define FCOE_LOGGING 0x01 /* General logging, not categorized */ + #define FCOE_NETDEV_LOGGING 0x02 /* Netdevice logging */ + + #define FCOE_CHECK_LOGGING(LEVEL, CMD) \ @@ -53,7 +53,7 @@ do { \ do { \ CMD; \ @@ -825463,7 +888666,7 @@ index 0d724fa..ce7f60f 100644 #define FCOE_DBG(fmt, args...) \ FCOE_CHECK_LOGGING(FCOE_LOGGING, \ -@@ -61,7 +61,7 @@ do { \ +@@ -61,11 +61,16 @@ do { \ #define FCOE_NETDEV_DBG(netdev, fmt, args...) \ FCOE_CHECK_LOGGING(FCOE_NETDEV_LOGGING, \ @@ -825471,39 +888674,79 @@ index 0d724fa..ce7f60f 100644 + printk(KERN_INFO "fcoe: %s: " fmt, \ netdev->name, ##args);) - /* -@@ -75,26 +75,36 @@ struct fcoe_percpu_s { +-/* +- * this percpu struct for fcoe ++/** ++ * struct fcoe_percpu_s - The per-CPU context for FCoE receive threads ++ * @thread: The thread context ++ * @fcoe_rx_list: The queue of pending packets to process ++ * @page: The memory page for calculating frame trailer CRCs ++ * @crc_eof_offset: The offset into the CRC page pointing to available ++ * memory for a new trailer + */ + struct fcoe_percpu_s { + struct task_struct *thread; +@@ -74,27 +79,62 @@ struct fcoe_percpu_s { + int crc_eof_offset; }; - /* +-/* - * the fcoe sw transport private data -+ * an FCoE interface, 1:1 with netdev - */ --struct fcoe_softc { ++/** ++ * struct fcoe_interface - A FCoE interface ++ * @list: Handle for a list of FCoE interfaces ++ * @netdev: The associated net device ++ * @fcoe_packet_type: FCoE packet type ++ * @fip_packet_type: FIP packet type ++ * @ctlr: The FCoE controller (for FIP) ++ * @oem: The offload exchange manager for all local port ++ * instances associated with this port ++ * @kref: The kernel reference ++ * ++ * This structure is 1:1 with a net devive. ++ */ +struct fcoe_interface { - struct list_head list; -- struct net_device *real_dev; -- struct net_device *phys_dev; /* device with ethtool_ops */ -+ struct net_device *netdev; - struct packet_type fcoe_packet_type; - struct packet_type fip_packet_type; -+ struct fcoe_ctlr ctlr; -+ struct fc_exch_mgr *oem; /* offload exchange manager */ -+ struct kref kref; ++ struct list_head list; ++ struct net_device *netdev; ++ struct packet_type fcoe_packet_type; ++ struct packet_type fip_packet_type; ++ struct fcoe_ctlr ctlr; ++ struct fc_exch_mgr *oem; ++ struct kref kref; +}; + -+/* -+ * the FCoE private structure that's allocated along with the -+ * Scsi_Host and libfc fc_lport structures -+ */ ++/** ++ * struct fcoe_port - The FCoE private structure ++ * @fcoe: The associated fcoe interface ++ * @lport: The associated local port ++ * @fcoe_pending_queue: The pending Rx queue of skbs ++ * @fcoe_pending_queue_active: Indicates if the pending queue is active ++ * @timer: The queue timer ++ * @destroy_work: Handle for work context ++ * (to prevent RTNL deadlocks) ++ * @data_srt_addr: Source address for data ++ * ++ * An instance of this structure is to be allocated along with the ++ * Scsi_Host and libfc fc_lport structures. + */ +-struct fcoe_softc { +- struct list_head list; +- struct net_device *real_dev; +- struct net_device *phys_dev; /* device with ethtool_ops */ +- struct packet_type fcoe_packet_type; +- struct packet_type fip_packet_type; +- struct sk_buff_head fcoe_pending_queue; +- u8 fcoe_pending_queue_active; +- struct timer_list timer; /* queue timer */ +- struct fcoe_ctlr ctlr; +struct fcoe_port { + struct fcoe_interface *fcoe; -+ struct fc_lport *lport; - struct sk_buff_head fcoe_pending_queue; - u8 fcoe_pending_queue_active; - struct timer_list timer; /* queue timer */ -- struct fcoe_ctlr ctlr; -+ struct work_struct destroy_work; /* to prevent rtnl deadlocks */ ++ struct fc_lport *lport; ++ struct sk_buff_head fcoe_pending_queue; ++ u8 fcoe_pending_queue_active; ++ struct timer_list timer; ++ struct work_struct destroy_work; ++ u8 data_src_addr[ETH_ALEN]; }; -#define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr) @@ -825511,15 +888754,19 @@ index 0d724fa..ce7f60f 100644 -static inline struct net_device *fcoe_netdev( - const struct fc_lport *lp) -+static inline struct net_device *fcoe_netdev(const struct fc_lport *lp) ++/** ++ * fcoe_netdev() - Return the net device associated with a local port ++ * @lport: The local port to get the net device from ++ */ ++static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) { - return ((struct fcoe_softc *)lport_priv(lp))->real_dev; -+ return ((struct fcoe_port *)lport_priv(lp))->fcoe->netdev; ++ return ((struct fcoe_port *)lport_priv(lport))->fcoe->netdev; } #endif /* _FCOE_H_ */ diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c -index f544340..11ae5c9 100644 +index f544340..6b07a84 100644 --- a/drivers/scsi/fcoe/libfcoe.c +++ b/drivers/scsi/fcoe/libfcoe.c @@ -29,7 +29,6 @@ @@ -825530,16 +888777,89 @@ index f544340..11ae5c9 100644 #include #include #include -@@ -69,7 +68,7 @@ do { \ - do { \ - CMD; \ - } while (0); \ +@@ -60,16 +59,16 @@ unsigned int libfcoe_debug_logging; + module_param_named(debug_logging, libfcoe_debug_logging, int, S_IRUGO|S_IWUSR); + MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); + +-#define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ ++#define LIBFCOE_LOGGING 0x01 /* General logging, not categorized */ + #define LIBFCOE_FIP_LOGGING 0x02 /* FIP logging */ + +-#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ +-do { \ +- if (unlikely(libfcoe_debug_logging & LEVEL)) \ +- do { \ +- CMD; \ +- } while (0); \ -} while (0); ++#define LIBFCOE_CHECK_LOGGING(LEVEL, CMD) \ ++do { \ ++ if (unlikely(libfcoe_debug_logging & LEVEL)) \ ++ do { \ ++ CMD; \ ++ } while (0); \ +} while (0) #define LIBFCOE_DBG(fmt, args...) \ LIBFCOE_CHECK_LOGGING(LIBFCOE_LOGGING, \ -@@ -148,13 +147,17 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) +@@ -79,7 +78,10 @@ do { \ + LIBFCOE_CHECK_LOGGING(LIBFCOE_FIP_LOGGING, \ + printk(KERN_INFO "fip: " fmt, ##args);) + +-/* ++/** ++ * fcoe_ctlr_mtu_valid() - Check if a FCF's MTU is valid ++ * @fcf: The FCF to check ++ * + * Return non-zero if FCF fcoe_size has been validated. + */ + static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf) +@@ -87,7 +89,10 @@ static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf) + return (fcf->flags & FIP_FL_SOL) != 0; + } + +-/* ++/** ++ * fcoe_ctlr_fcf_usable() - Check if a FCF is usable ++ * @fcf: The FCF to check ++ * + * Return non-zero if the FCF is usable. + */ + static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf) +@@ -98,8 +103,8 @@ static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf) + } + + /** +- * fcoe_ctlr_init() - Initialize the FCoE Controller instance. +- * @fip: FCoE controller. ++ * fcoe_ctlr_init() - Initialize the FCoE Controller instance ++ * @fip: The FCoE controller to initialize + */ + void fcoe_ctlr_init(struct fcoe_ctlr *fip) + { +@@ -115,8 +120,8 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip) + EXPORT_SYMBOL(fcoe_ctlr_init); + + /** +- * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller. +- * @fip: FCoE controller. ++ * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller ++ * @fip: The FCoE controller whose FCFs are to be reset + * + * Called with &fcoe_ctlr lock held. + */ +@@ -135,8 +140,8 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) + } + + /** +- * fcoe_ctlr_destroy() - Disable and tear-down the FCoE controller. +- * @fip: FCoE controller. ++ * fcoe_ctlr_destroy() - Disable and tear down a FCoE controller ++ * @fip: The FCoE controller to tear down + * + * This is called by FCoE drivers before freeing the &fcoe_ctlr. + * +@@ -148,19 +153,23 @@ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) */ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip) { @@ -825559,7 +888879,161 @@ index f544340..11ae5c9 100644 } EXPORT_SYMBOL(fcoe_ctlr_destroy); -@@ -413,10 +416,18 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, + /** +- * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port. +- * @fip: FCoE controller. ++ * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port ++ * @fip: The FCoE controller to get the maximum FCoE size from + * + * Returns the maximum packet size including the FCoE header and trailer, + * but not including any Ethernet or VLAN headers. +@@ -177,9 +186,9 @@ static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip) + } + + /** +- * fcoe_ctlr_solicit() - Send a solicitation. +- * @fip: FCoE controller. +- * @fcf: Destination FCF. If NULL, a multicast solicitation is sent. ++ * fcoe_ctlr_solicit() - Send a FIP solicitation ++ * @fip: The FCoE controller to send the solicitation on ++ * @fcf: The destination FCF (if NULL, a multicast solicitation is sent) + */ + static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) + { +@@ -238,8 +247,8 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) + } + + /** +- * fcoe_ctlr_link_up() - Start FCoE controller. +- * @fip: FCoE controller. ++ * fcoe_ctlr_link_up() - Start FCoE controller ++ * @fip: The FCoE controller to start + * + * Called from the LLD when the network link is ready. + */ +@@ -265,15 +274,15 @@ void fcoe_ctlr_link_up(struct fcoe_ctlr *fip) + EXPORT_SYMBOL(fcoe_ctlr_link_up); + + /** +- * fcoe_ctlr_reset() - Reset FIP. +- * @fip: FCoE controller. +- * @new_state: FIP state to be entered. ++ * fcoe_ctlr_reset() - Reset a FCoE controller ++ * @fip: The FCoE controller to reset ++ * @new_state: The FIP state to be entered + * + * Returns non-zero if the link was up and now isn't. + */ + static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) + { +- struct fc_lport *lp = fip->lp; ++ struct fc_lport *lport = fip->lp; + int link_dropped; + + spin_lock_bh(&fip->lock); +@@ -291,19 +300,19 @@ static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state) + spin_unlock_bh(&fip->lock); + + if (link_dropped) +- fc_linkdown(lp); ++ fc_linkdown(lport); + + if (new_state == FIP_ST_ENABLED) { + fcoe_ctlr_solicit(fip, NULL); +- fc_linkup(lp); ++ fc_linkup(lport); + link_dropped = 0; + } + return link_dropped; + } + + /** +- * fcoe_ctlr_link_down() - Stop FCoE controller. +- * @fip: FCoE controller. ++ * fcoe_ctlr_link_down() - Stop a FCoE controller ++ * @fip: The FCoE controller to be stopped + * + * Returns non-zero if the link was up and now isn't. + * +@@ -317,10 +326,11 @@ int fcoe_ctlr_link_down(struct fcoe_ctlr *fip) + EXPORT_SYMBOL(fcoe_ctlr_link_down); + + /** +- * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF. +- * @fip: FCoE controller. +- * @ports: 0 for controller keep-alive, 1 for port keep-alive. +- * @sa: source MAC address. ++ * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF ++ * @fip: The FCoE controller to send the FKA on ++ * @lport: libfc fc_lport to send from ++ * @ports: 0 for controller keep-alive, 1 for port keep-alive ++ * @sa: The source MAC address + * + * A controller keep-alive is sent every fka_period (typically 8 seconds). + * The source MAC is the native MAC address. +@@ -329,7 +339,9 @@ EXPORT_SYMBOL(fcoe_ctlr_link_down); + * The source MAC is the assigned mapped source address. + * The destination is the FCF's F-port. + */ +-static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) ++static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, ++ struct fc_lport *lport, ++ int ports, u8 *sa) + { + struct sk_buff *skb; + struct fip_kal { +@@ -363,7 +375,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) + kal->fip.fip_op = htons(FIP_OP_CTRL); + kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE; + kal->fip.fip_dl_len = htons((sizeof(kal->mac) + +- ports * sizeof(*vn)) / FIP_BPW); ++ ports * sizeof(*vn)) / FIP_BPW); + kal->fip.fip_flags = htons(FIP_FL_FPMA); + if (fip->spma) + kal->fip.fip_flags |= htons(FIP_FL_SPMA); +@@ -371,16 +383,14 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) + kal->mac.fd_desc.fip_dtype = FIP_DT_MAC; + kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW; + memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN); +- + if (ports) { + vn = (struct fip_vn_desc *)(kal + 1); + vn->fd_desc.fip_dtype = FIP_DT_VN_ID; + vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW; +- memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN); ++ memcpy(vn->fd_mac, fip->get_src_addr(lport), ETH_ALEN); + hton24(vn->fd_fc_id, fc_host_port_id(lp->host)); + put_unaligned_be64(lp->wwpn, &vn->fd_wwpn); + } +- + skb_put(skb, len); + skb->protocol = htons(ETH_P_FIP); + skb_reset_mac_header(skb); +@@ -389,10 +399,10 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) + } + + /** +- * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it. +- * @fip: FCoE controller. +- * @dtype: FIP descriptor type for the frame. +- * @skb: FCoE ELS frame including FC header but no FCoE headers. ++ * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it ++ * @fip: The FCoE controller for the ELS frame ++ * @dtype: The FIP descriptor type for the frame ++ * @skb: The FCoE ELS frame including FC header but no FCoE headers + * + * Returns non-zero error code on failure. + * +@@ -402,7 +412,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa) + * Headroom includes the FIP encapsulation description, FIP header, and + * Ethernet header. The tailroom is for the FIP MAC descriptor. + */ +-static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, ++static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport, + u8 dtype, struct sk_buff *skb) + { + struct fip_encaps_head { +@@ -413,10 +423,18 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fip_mac_desc *mac; struct fcoe_fcf *fcf; size_t dlen; @@ -825578,7 +889052,7 @@ index f544340..11ae5c9 100644 dlen = sizeof(struct fip_encaps) + skb->len; /* len before push */ cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap)); -@@ -429,9 +440,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, +@@ -429,9 +447,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, cap->fip.fip_op = htons(FIP_OP_LS); cap->fip.fip_subcode = FIP_SC_REQ; cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW); @@ -825589,24 +889063,274 @@ index f544340..11ae5c9 100644 cap->encaps.fd_desc.fip_dtype = dtype; cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW; -@@ -879,7 +888,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) +@@ -440,8 +456,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, + memset(mac, 0, sizeof(mac)); + mac->fd_desc.fip_dtype = FIP_DT_MAC; + mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW; +- if (dtype != FIP_DT_FLOGI) +- memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN); ++ if (dtype != FIP_DT_FLOGI && dtype != FIP_DT_FDISC) ++ memcpy(mac->fd_mac, fip->get_src_addr(lport), ETH_ALEN); + else if (fip->spma) + memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN); + +@@ -454,6 +470,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, + /** + * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate. + * @fip: FCoE controller. ++ * @lport: libfc fc_lport to send from + * @skb: FCoE ELS frame including FC header but no FCoE headers. + * + * Returns a non-zero error code if the frame should not be sent. +@@ -462,11 +479,13 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, + * The caller must check that the length is a multiple of 4. + * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). + */ +-int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) ++int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, ++ struct sk_buff *skb) + { + struct fc_frame_header *fh; + u16 old_xid; + u8 op; ++ u8 mac[ETH_ALEN]; + + fh = (struct fc_frame_header *)skb->data; + op = *(u8 *)(fh + 1); +@@ -521,14 +540,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb) + * FLOGI. + */ + fip->flogi_oxid = FC_XID_UNKNOWN; +- fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id); ++ fc_fcoe_set_mac(mac, fh->fh_d_id); ++ fip->update_mac(lport, mac); + return 0; + default: + if (fip->state != FIP_ST_ENABLED) + goto drop; + return 0; + } +- if (fcoe_ctlr_encaps(fip, op, skb)) ++ if (fcoe_ctlr_encaps(fip, lport, op, skb)) + goto drop; + fip->send(fip, skb); + return -EINPROGRESS; +@@ -538,9 +558,9 @@ drop: + } + EXPORT_SYMBOL(fcoe_ctlr_els_send); + +-/* +- * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller. +- * @fip: FCoE controller. ++/** ++ * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller ++ * @fip: The FCoE controller to free FCFs on + * + * Called with lock held. + * +@@ -581,9 +601,9 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) + } + + /** +- * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry. +- * @skb: received FIP advertisement frame +- * @fcf: resulting FCF entry. ++ * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry ++ * @skb: The received FIP advertisement frame ++ * @fcf: The resulting FCF entry + * + * Returns zero on a valid parsed advertisement, + * otherwise returns non zero value. +@@ -684,9 +704,9 @@ len_err: + } + + /** +- * fcoe_ctlr_recv_adv() - Handle an incoming advertisement. +- * @fip: FCoE controller. +- * @skb: Received FIP packet. ++ * fcoe_ctlr_recv_adv() - Handle an incoming advertisement ++ * @fip: The FCoE controller receiving the advertisement ++ * @skb: The received FIP packet + */ + static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) + { +@@ -769,7 +789,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) + */ + if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) { + fip->sel_time = jiffies + +- msecs_to_jiffies(FCOE_CTLR_START_DELAY); ++ msecs_to_jiffies(FCOE_CTLR_START_DELAY); + if (!timer_pending(&fip->timer) || + time_before(fip->sel_time, fip->timer.expires)) + mod_timer(&fip->timer, fip->sel_time); +@@ -779,15 +799,15 @@ out: + } + + /** +- * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame. +- * @fip: FCoE controller. +- * @skb: Received FIP packet. ++ * fcoe_ctlr_recv_els() - Handle an incoming FIP encapsulated ELS frame ++ * @fip: The FCoE controller which received the packet ++ * @skb: The received FIP packet + */ + static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) + { +- struct fc_lport *lp = fip->lp; ++ struct fc_lport *lport = fip->lp; + struct fip_header *fiph; +- struct fc_frame *fp; ++ struct fc_frame *fp = (struct fc_frame *)skb; + struct fc_frame_header *fh = NULL; + struct fip_desc *desc; + struct fip_encaps *els; +@@ -826,6 +846,7 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) + "in FIP ELS\n"); + goto drop; + } ++ memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); + break; + case FIP_DT_FLOGI: + case FIP_DT_FDISC: +@@ -858,11 +879,8 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) + + if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP && + fip->flogi_oxid == ntohs(fh->fh_ox_id) && +- els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) { ++ els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) + fip->flogi_oxid = FC_XID_UNKNOWN; +- fip->update_mac(fip, fip->data_src_addr, granted_mac); +- memcpy(fip->data_src_addr, granted_mac, ETH_ALEN); +- } + + /* + * Convert skb into an fc_frame containing only the ELS. +@@ -873,13 +891,13 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb) + fc_frame_init(fp); + fr_sof(fp) = FC_SOF_I3; + fr_eof(fp) = FC_EOF_T; +- fr_dev(fp) = lp; ++ fr_dev(fp) = lport; + +- stats = fc_lport_get_stats(lp); ++ stats = fc_lport_get_stats(lport); stats->RxFrames++; stats->RxWords += skb->len / FIP_BPW; - fc_exch_recv(lp, lp->emp, fp); -+ fc_exch_recv(lp, fp); ++ fc_exch_recv(lport, fp); return; len_err: -@@ -1104,7 +1113,6 @@ static void fcoe_ctlr_timeout(unsigned long arg) +@@ -890,15 +908,15 @@ drop: + } + + /** +- * fcoe_ctlr_recv_els() - Handle an incoming link reset frame. +- * @fip: FCoE controller. +- * @fh: Received FIP header. ++ * fcoe_ctlr_recv_els() - Handle an incoming link reset frame ++ * @fip: The FCoE controller that received the frame ++ * @fh: The received FIP header + * + * There may be multiple VN_Port descriptors. + * The overall length has already been checked. + */ + static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, +- struct fip_header *fh) ++ struct fip_header *fh) + { + struct fip_desc *desc; + struct fip_mac_desc *mp; +@@ -907,13 +925,13 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, + size_t rlen; + size_t dlen; + struct fcoe_fcf *fcf = fip->sel_fcf; +- struct fc_lport *lp = fip->lp; ++ struct fc_lport *lport = fip->lp; + u32 desc_mask; + + LIBFCOE_FIP_DBG("Clear Virtual Link received\n"); + if (!fcf) + return; +- if (!fcf || !fc_host_port_id(lp->host)) ++ if (!fcf || !fc_host_port_id(lport->host)) + return; + + /* +@@ -949,9 +967,10 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, + if (dlen < sizeof(*vp)) + return; + if (compare_ether_addr(vp->fd_mac, +- fip->data_src_addr) == 0 && +- get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn && +- ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host)) ++ fip->get_src_addr(lport)) == 0 && ++ get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn && ++ ntoh24(vp->fd_fc_id) == ++ fc_host_port_id(lport->host)) + desc_mask &= ~BIT(FIP_DT_VN_ID); + break; + default: +@@ -976,9 +995,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, + } + + /** +- * fcoe_ctlr_recv() - Receive a FIP frame. +- * @fip: FCoE controller. +- * @skb: Received FIP packet. ++ * fcoe_ctlr_recv() - Receive a FIP packet ++ * @fip: The FCoE controller that received the packet ++ * @skb: The received FIP packet + * + * This is called from NET_RX_SOFTIRQ. + */ +@@ -992,9 +1011,9 @@ void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) + EXPORT_SYMBOL(fcoe_ctlr_recv); + + /** +- * fcoe_ctlr_recv_handler() - Receive a FIP frame. +- * @fip: FCoE controller. +- * @skb: Received FIP packet. ++ * fcoe_ctlr_recv_handler() - Receive a FIP frame ++ * @fip: The FCoE controller that received the frame ++ * @skb: The received FIP frame + * + * Returns non-zero if the frame is dropped. + */ +@@ -1051,8 +1070,8 @@ drop: + } + + /** +- * fcoe_ctlr_select() - Select the best FCF, if possible. +- * @fip: FCoE controller. ++ * fcoe_ctlr_select() - Select the best FCF (if possible) ++ * @fip: The FCoE controller + * + * If there are conflicting advertisements, no FCF can be chosen. + * +@@ -1093,8 +1112,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip) + } + + /** +- * fcoe_ctlr_timeout() - FIP timer function. +- * @arg: &fcoe_ctlr pointer. ++ * fcoe_ctlr_timeout() - FIP timeout handler ++ * @arg: The FCoE controller that timed out + * + * Ages FCFs. Triggers FCF selection if possible. Sends keep-alives. + */ +@@ -1104,9 +1123,6 @@ static void fcoe_ctlr_timeout(unsigned long arg) struct fcoe_fcf *sel; struct fcoe_fcf *fcf; unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); - DECLARE_MAC_BUF(buf); - u8 send_ctlr_ka; - u8 send_port_ka; +- u8 send_ctlr_ka; +- u8 send_port_ka; -@@ -1128,9 +1136,8 @@ static void fcoe_ctlr_timeout(unsigned long arg) + spin_lock_bh(&fip->lock); + if (fip->state == FIP_ST_DISABLED) { +@@ -1128,17 +1144,16 @@ static void fcoe_ctlr_timeout(unsigned long arg) fcf = sel; /* the old FCF may have been freed */ if (sel) { printk(KERN_INFO "libfcoe: host%d: FIP selected " @@ -825617,7 +889341,197 @@ index f544340..11ae5c9 100644 + fip->lp->host->host_no, sel->fcf_mac); memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); fip->port_ka_time = jiffies + - msecs_to_jiffies(FIP_VN_KA_PERIOD); +- msecs_to_jiffies(FIP_VN_KA_PERIOD); ++ msecs_to_jiffies(FIP_VN_KA_PERIOD); + fip->ctlr_ka_time = jiffies + sel->fka_period; + fip->link = 1; + } else { + printk(KERN_NOTICE "libfcoe: host%d: " +- "FIP Fibre-Channel Forwarder timed out. " ++ "FIP Fibre-Channel Forwarder timed out. " + "Starting FCF discovery.\n", + fip->lp->host->host_no); + fip->link = 0; +@@ -1146,40 +1161,35 @@ static void fcoe_ctlr_timeout(unsigned long arg) + schedule_work(&fip->link_work); + } + +- send_ctlr_ka = 0; +- send_port_ka = 0; + if (sel) { + if (time_after_eq(jiffies, fip->ctlr_ka_time)) { + fip->ctlr_ka_time = jiffies + sel->fka_period; +- send_ctlr_ka = 1; ++ fip->send_ctlr_ka = 1; + } + if (time_after(next_timer, fip->ctlr_ka_time)) + next_timer = fip->ctlr_ka_time; + + if (time_after_eq(jiffies, fip->port_ka_time)) { + fip->port_ka_time += jiffies + +- msecs_to_jiffies(FIP_VN_KA_PERIOD); +- send_port_ka = 1; ++ msecs_to_jiffies(FIP_VN_KA_PERIOD); ++ fip->send_port_ka = 1; + } + if (time_after(next_timer, fip->port_ka_time)) + next_timer = fip->port_ka_time; + mod_timer(&fip->timer, next_timer); + } else if (fip->sel_time) { + next_timer = fip->sel_time + +- msecs_to_jiffies(FCOE_CTLR_START_DELAY); ++ msecs_to_jiffies(FCOE_CTLR_START_DELAY); + mod_timer(&fip->timer, next_timer); + } ++ if (fip->send_ctlr_ka || fip->send_port_ka) ++ schedule_work(&fip->link_work); + spin_unlock_bh(&fip->lock); +- +- if (send_ctlr_ka) +- fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr); +- if (send_port_ka) +- fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr); + } + + /** +- * fcoe_ctlr_link_work() - worker thread function for link changes. +- * @work: pointer to link_work member inside &fcoe_ctlr. ++ * fcoe_ctlr_link_work() - Worker thread function for link changes ++ * @work: Handle to a FCoE controller + * + * See if the link status has changed and if so, report it. + * +@@ -1189,6 +1199,8 @@ static void fcoe_ctlr_timeout(unsigned long arg) + static void fcoe_ctlr_link_work(struct work_struct *work) + { + struct fcoe_ctlr *fip; ++ struct fc_lport *vport; ++ u8 *mac; + int link; + int last_link; + +@@ -1205,11 +1217,27 @@ static void fcoe_ctlr_link_work(struct work_struct *work) + else + fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT); + } ++ ++ if (fip->send_ctlr_ka) { ++ fip->send_ctlr_ka = 0; ++ fcoe_ctlr_send_keep_alive(fip, NULL, 0, fip->ctl_src_addr); ++ } ++ if (fip->send_port_ka) { ++ fip->send_port_ka = 0; ++ mutex_lock(&fip->lp->lp_mutex); ++ mac = fip->get_src_addr(fip->lp); ++ fcoe_ctlr_send_keep_alive(fip, fip->lp, 1, mac); ++ list_for_each_entry(vport, &fip->lp->vports, list) { ++ mac = fip->get_src_addr(vport); ++ fcoe_ctlr_send_keep_alive(fip, vport, 1, mac); ++ } ++ mutex_unlock(&fip->lp->lp_mutex); ++ } + } + + /** +- * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames. +- * @recv_work: pointer to recv_work member inside &fcoe_ctlr. ++ * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames ++ * @recv_work: Handle to a FCoE controller + */ + static void fcoe_ctlr_recv_work(struct work_struct *recv_work) + { +@@ -1227,10 +1255,10 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) + } + + /** +- * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request. +- * @fip: FCoE controller. +- * @fp: FC frame. +- * @sa: Ethernet source MAC address from received FCoE frame. ++ * fcoe_ctlr_recv_flogi() - Snoop pre-FIP receipt of FLOGI response or request ++ * @fip: The FCoE controller ++ * @fp: The FC frame to snoop ++ * @sa: Ethernet source MAC address from received FCoE frame + * + * Snoop potential response to FLOGI or even incoming FLOGI. + * +@@ -1241,7 +1269,8 @@ static void fcoe_ctlr_recv_work(struct work_struct *recv_work) + * + * Return non-zero if the frame should not be delivered to libfc. + */ +-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) ++int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_lport *lport, ++ struct fc_frame *fp, u8 *sa) + { + struct fc_frame_header *fh; + u8 op; +@@ -1276,11 +1305,9 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) + fip->map_dest = 0; + } + fip->flogi_oxid = FC_XID_UNKNOWN; +- memcpy(mac, fip->data_src_addr, ETH_ALEN); +- fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id); ++ fc_fcoe_set_mac(mac, fh->fh_d_id); ++ fip->update_mac(lport, mac); + spin_unlock_bh(&fip->lock); +- +- fip->update_mac(fip, mac, fip->data_src_addr); + } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) { + /* + * Save source MAC for point-to-point responses. +@@ -1301,10 +1328,10 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa) + EXPORT_SYMBOL(fcoe_ctlr_recv_flogi); + + /** +- * fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN. +- * @mac: mac address +- * @scheme: check port +- * @port: port indicator for converting ++ * fcoe_wwn_from_mac() - Converts a 48-bit IEEE MAC address to a 64-bit FC WWN ++ * @mac: The MAC address to convert ++ * @scheme: The scheme to use when converting ++ * @port: The port indicator for converting + * + * Returns: u64 fc world wide name + */ +@@ -1342,24 +1369,26 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], + EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); + + /** +- * fcoe_libfc_config() - sets up libfc related properties for lport +- * @lp: ptr to the fc_lport +- * @tt: libfc function template ++ * fcoe_libfc_config() - Sets up libfc related properties for local port ++ * @lp: The local port to configure libfc for ++ * @tt: The libfc function template + * + * Returns : 0 for success + */ +-int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt) ++int fcoe_libfc_config(struct fc_lport *lport, ++ struct libfc_function_template *tt) + { + /* Set the function pointers set by the LLDD */ +- memcpy(&lp->tt, tt, sizeof(*tt)); +- if (fc_fcp_init(lp)) ++ memcpy(&lport->tt, tt, sizeof(*tt)); ++ if (fc_fcp_init(lport)) + return -ENOMEM; +- fc_exch_init(lp); +- fc_elsct_init(lp); +- fc_lport_init(lp); +- fc_rport_init(lp); +- fc_disc_init(lp); ++ fc_exch_init(lport); ++ fc_elsct_init(lport); ++ fc_lport_init(lport); ++ fc_rport_init(lport); ++ fc_disc_init(lport); + + return 0; + } + EXPORT_SYMBOL_GPL(fcoe_libfc_config); ++ diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 07e6eed..50db3e3 100644 --- a/drivers/scsi/fnic/fnic_fcs.c @@ -825632,10 +889546,30 @@ index 07e6eed..50db3e3 100644 } diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c -index 2c266c0..71c7bbe 100644 +index 2c266c0..bfc341c 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c -@@ -671,14 +671,6 @@ static int __devinit fnic_probe(struct pci_dev *pdev, +@@ -424,15 +424,13 @@ static int __devinit fnic_probe(struct pci_dev *pdev, + * Allocate SCSI Host and set up association between host, + * local port, and fnic + */ +- host = scsi_host_alloc(&fnic_host_template, +- sizeof(struct fc_lport) + sizeof(struct fnic)); +- if (!host) { +- printk(KERN_ERR PFX "Unable to alloc SCSI host\n"); ++ lp = libfc_host_alloc(&fnic_host_template, sizeof(struct fnic)); ++ if (!lp) { ++ printk(KERN_ERR PFX "Unable to alloc libfc local port\n"); + err = -ENOMEM; + goto err_out; + } +- lp = shost_priv(host); +- lp->host = host; ++ host = lp->host; + fnic = lport_priv(lp); + fnic->lport = lp; + +@@ -671,14 +669,6 @@ static int __devinit fnic_probe(struct pci_dev *pdev, lp->link_up = 0; lp->tt = fnic_transport_template; @@ -825650,7 +889584,7 @@ index 2c266c0..71c7bbe 100644 lp->max_retry_count = fnic->config.flogi_retries; lp->max_rport_retry_count = fnic->config.plogi_retries; lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | -@@ -693,12 +685,18 @@ static int __devinit fnic_probe(struct pci_dev *pdev, +@@ -693,12 +683,18 @@ static int __devinit fnic_probe(struct pci_dev *pdev, fc_set_wwnn(lp, fnic->config.node_wwn); fc_set_wwpn(lp, fnic->config.port_wwn); @@ -825670,7 +889604,7 @@ index 2c266c0..71c7bbe 100644 fc_lport_config(lp); if (fc_set_mfs(lp, fnic->config.maxdatafieldsize + -@@ -738,7 +736,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev, +@@ -738,7 +734,7 @@ static int __devinit fnic_probe(struct pci_dev *pdev, return 0; err_out_free_exch_mgr: @@ -825679,7 +889613,7 @@ index 2c266c0..71c7bbe 100644 err_out_remove_scsi_host: fc_remove_host(fnic->lport->host); scsi_remove_host(fnic->lport->host); -@@ -827,7 +825,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev) +@@ -827,7 +823,7 @@ static void __devexit fnic_remove(struct pci_dev *pdev) fc_remove_host(fnic->lport->host); scsi_remove_host(fnic->lport->host); @@ -825896,11 +889830,34 @@ index 518dbd9..2b1b834 100644 tcp_conn = conn->dd_data; tcp_sw_conn = tcp_conn->dd_data; +diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile +index 55f982d..4bb23ac 100644 +--- a/drivers/scsi/libfc/Makefile ++++ b/drivers/scsi/libfc/Makefile +@@ -3,10 +3,12 @@ + obj-$(CONFIG_LIBFC) += libfc.o + + libfc-objs := \ ++ fc_libfc.o \ + fc_disc.o \ + fc_exch.o \ + fc_elsct.o \ + fc_frame.o \ + fc_lport.o \ + fc_rport.o \ +- fc_fcp.o ++ fc_fcp.o \ ++ fc_npiv.o diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c -index 6fabf66..c48799e 100644 +index 6fabf66..c42bf90 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c -@@ -43,47 +43,14 @@ +@@ -40,50 +40,19 @@ + + #include + ++#include "fc_libfc.h" ++ #define FC_DISC_RETRY_LIMIT 3 /* max retries */ #define FC_DISC_RETRY_DELAY 500UL /* (msecs) delay */ @@ -825950,7 +889907,7 @@ index 6fabf66..c48799e 100644 * fc_disc_stop_rports() - delete all the remote ports associated with the lport * @disc: The discovery job to stop rports on * -@@ -93,70 +60,17 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, +@@ -93,70 +62,17 @@ struct fc_rport *fc_disc_lookup_rport(const struct fc_lport *lport, void fc_disc_stop_rports(struct fc_disc *disc) { struct fc_lport *lport; @@ -826024,7 +889981,7 @@ index 6fabf66..c48799e 100644 * fc_disc_recv_rscn_req() - Handle Registered State Change Notification (RSCN) * @sp: Current sequence of the RSCN exchange * @fp: RSCN Frame -@@ -169,8 +83,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, +@@ -169,8 +85,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, struct fc_disc *disc) { struct fc_lport *lport; @@ -826033,7 +889990,7 @@ index 6fabf66..c48799e 100644 struct fc_els_rscn *rp; struct fc_els_rscn_page *pp; struct fc_seq_els_data rjt_data; -@@ -224,10 +136,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, +@@ -224,10 +138,7 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, break; } dp->lp = lport; @@ -826045,7 +890002,7 @@ index 6fabf66..c48799e 100644 list_add_tail(&dp->peers, &disc_ports); break; case ELS_ADDR_FMT_AREA: -@@ -240,6 +149,19 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, +@@ -240,6 +151,19 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, } } lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL); @@ -826065,7 +890022,7 @@ index 6fabf66..c48799e 100644 if (redisc) { FC_DISC_DBG(disc, "RSCN received: rediscovering\n"); fc_disc_restart(disc); -@@ -247,16 +169,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, +@@ -247,16 +171,6 @@ static void fc_disc_recv_rscn_req(struct fc_seq *sp, struct fc_frame *fp, FC_DISC_DBG(disc, "RSCN received: not rediscovering. " "redisc %d state %d in_prog %d\n", redisc, lport->state, disc->pending); @@ -826082,7 +890039,7 @@ index 6fabf66..c48799e 100644 } fc_frame_free(fp); return; -@@ -308,35 +220,34 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, +@@ -308,35 +222,34 @@ static void fc_disc_recv_req(struct fc_seq *sp, struct fc_frame *fp, */ static void fc_disc_restart(struct fc_disc *disc) { @@ -826132,7 +890089,7 @@ index 6fabf66..c48799e 100644 struct fc_disc *disc = &lport->disc; /* -@@ -345,145 +256,47 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, +@@ -345,145 +258,47 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, * and send the GPN_FT request. */ mutex_lock(&disc->disc_mutex); @@ -826302,7 +890259,7 @@ index 6fabf66..c48799e 100644 mutex_unlock(&disc->disc_mutex); disc->disc_callback(lport, event); -@@ -522,11 +335,8 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) +@@ -522,11 +337,8 @@ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) } disc->retry_count++; schedule_delayed_work(&disc->disc_work, delay); @@ -826316,7 +890273,7 @@ index 6fabf66..c48799e 100644 } } -@@ -555,7 +365,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc) +@@ -555,7 +367,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc) if (!fp) goto err; @@ -826325,7 +890282,7 @@ index 6fabf66..c48799e 100644 FC_NS_GPN_FT, fc_disc_gpn_ft_resp, disc, lport->e_d_tov)) -@@ -565,10 +375,12 @@ err: +@@ -565,10 +377,12 @@ err: } /** @@ -826339,7 +890296,7 @@ index 6fabf66..c48799e 100644 */ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) { -@@ -578,11 +390,11 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) +@@ -578,11 +392,11 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) size_t plen; size_t tlen; int error = 0; @@ -826354,7 +890311,7 @@ index 6fabf66..c48799e 100644 /* * Handle partial name record left over from previous call. -@@ -591,6 +403,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) +@@ -591,6 +405,7 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) plen = len; np = (struct fc_gpn_ft_resp *)bp; tlen = disc->buf_len; @@ -826362,7 +890319,7 @@ index 6fabf66..c48799e 100644 if (tlen) { WARN_ON(tlen >= sizeof(*np)); plen = sizeof(*np) - tlen; -@@ -621,31 +434,25 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) +@@ -621,31 +436,25 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) * After the first time through the loop, things return to "normal". */ while (plen >= sizeof(*np)) { @@ -826408,7 +890365,7 @@ index 6fabf66..c48799e 100644 len = 0; break; } -@@ -665,8 +472,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) +@@ -665,8 +474,6 @@ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) memcpy(&disc->partial_buf, np, len); } disc->buf_len = (unsigned char) len; @@ -826417,7 +890374,7 @@ index 6fabf66..c48799e 100644 } return error; } -@@ -683,8 +488,7 @@ static void fc_disc_timeout(struct work_struct *work) +@@ -683,8 +490,7 @@ static void fc_disc_timeout(struct work_struct *work) struct fc_disc, disc_work.work); mutex_lock(&disc->disc_mutex); @@ -826427,7 +890384,7 @@ index 6fabf66..c48799e 100644 mutex_unlock(&disc->disc_mutex); } -@@ -703,10 +507,10 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -703,10 +509,10 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, struct fc_disc *disc = disc_arg; struct fc_ct_hdr *cp; struct fc_frame_header *fh; @@ -826440,7 +890397,7 @@ index 6fabf66..c48799e 100644 mutex_lock(&disc->disc_mutex); FC_DISC_DBG(disc, "Received a GPN_FT response\n"); -@@ -721,77 +525,158 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -721,77 +527,158 @@ static void fc_disc_gpn_ft_resp(struct fc_seq *sp, struct fc_frame *fp, fh = fc_frame_header_get(fp); len = fr_len(fp) - sizeof(*fh); seq_cnt = ntohs(fh->fh_seq_cnt); @@ -826635,7 +890592,7 @@ index 6fabf66..c48799e 100644 } /** -@@ -841,18 +726,12 @@ int fc_disc_init(struct fc_lport *lport) +@@ -841,18 +728,12 @@ int fc_disc_init(struct fc_lport *lport) if (!lport->tt.disc_recv_req) lport->tt.disc_recv_req = fc_disc_recv_req; @@ -826655,14 +890612,16 @@ index 6fabf66..c48799e 100644 return 0; } diff --git a/drivers/scsi/libfc/fc_elsct.c b/drivers/scsi/libfc/fc_elsct.c -index 5878b34..5cfa687 100644 +index 5878b34..01ab3d5 100644 --- a/drivers/scsi/libfc/fc_elsct.c +++ b/drivers/scsi/libfc/fc_elsct.c -@@ -32,7 +32,7 @@ +@@ -31,8 +31,8 @@ + /* * fc_elsct_send - sends ELS/CT frame */ - static struct fc_seq *fc_elsct_send(struct fc_lport *lport, +-static struct fc_seq *fc_elsct_send(struct fc_lport *lport, - struct fc_rport *rport, ++struct fc_seq *fc_elsct_send(struct fc_lport *lport, + u32 did, struct fc_frame *fp, unsigned int op, @@ -826689,7 +890648,15 @@ index 5878b34..5cfa687 100644 if (rc) return NULL; -@@ -69,3 +70,41 @@ int fc_elsct_init(struct fc_lport *lport) +@@ -60,6 +61,7 @@ static struct fc_seq *fc_elsct_send(struct fc_lport *lport, + + return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec); + } ++EXPORT_SYMBOL(fc_elsct_send); + + int fc_elsct_init(struct fc_lport *lport) + { +@@ -69,3 +71,41 @@ int fc_elsct_init(struct fc_lport *lport) return 0; } EXPORT_SYMBOL(fc_elsct_init); @@ -826732,20 +890699,22 @@ index 5878b34..5cfa687 100644 + return msg; +} diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c -index 145ab9b..c1c1574 100644 +index 145ab9b..8e815d4 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c -@@ -32,6 +32,9 @@ +@@ -32,6 +32,11 @@ #include #include ++#include "fc_libfc.h" ++ +u16 fc_cpu_mask; /* cpu mask for possible cpus */ +EXPORT_SYMBOL(fc_cpu_mask); +static u16 fc_cpu_order; /* 2's power to represent total possible cpus */ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ /* -@@ -48,6 +51,20 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ +@@ -48,6 +53,20 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ */ /* @@ -826766,7 +890735,7 @@ index 145ab9b..c1c1574 100644 * Exchange manager. * * This structure is the center for creating exchanges and sequences. -@@ -55,17 +72,13 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ +@@ -55,17 +74,13 @@ static struct kmem_cache *fc_em_cachep; /* cache for exchanges */ */ struct fc_exch_mgr { enum fc_class class; /* default class for sequences */ @@ -826787,7 +890756,7 @@ index 145ab9b..c1c1574 100644 /* * currently exchange mgr stats are updated but not used. -@@ -80,10 +93,15 @@ struct fc_exch_mgr { +@@ -80,17 +95,21 @@ struct fc_exch_mgr { atomic_t seq_not_found; atomic_t non_bls_resp; } stats; @@ -826804,7 +890773,14 @@ index 145ab9b..c1c1574 100644 static void fc_exch_rrq(struct fc_exch *); static void fc_seq_ls_acc(struct fc_seq *); static void fc_seq_ls_rjt(struct fc_seq *, enum fc_els_rjt_reason, -@@ -167,8 +185,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp); + enum fc_els_rjt_explan); + static void fc_exch_els_rec(struct fc_seq *, struct fc_frame *); + static void fc_exch_els_rrq(struct fc_seq *, struct fc_frame *); +-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp); + + /* + * Internal implementation notes. +@@ -167,8 +186,8 @@ static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp); * sequence allocation and deallocation must be locked. * - exchange refcnt can be done atomicly without locks. * - sequence allocation must be locked by exch lock. @@ -826815,6 +890791,14 @@ index 145ab9b..c1c1574 100644 */ /* +@@ -255,7 +274,6 @@ static void fc_exch_setup_hdr(struct fc_exch *ep, struct fc_frame *fp, + fh->fh_seq_cnt = htons(ep->seq.cnt); + } + +- + /* + * Release a reference to an exchange. + * If the refcnt goes to zero and the exchange is complete, it is freed. @@ -268,8 +286,6 @@ static void fc_exch_release(struct fc_exch *ep) mp = ep->em; if (ep->destructor) @@ -826873,7 +890857,121 @@ index 145ab9b..c1c1574 100644 if (schedule_delayed_work(&ep->timeout_work, msecs_to_jiffies(timer_msec))) -@@ -408,6 +438,8 @@ static void fc_exch_timeout(struct work_struct *work) +@@ -343,7 +373,104 @@ static void fc_exch_timer_set(struct fc_exch *ep, unsigned int timer_msec) + spin_unlock_bh(&ep->ex_lock); + } + +-int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec) ++/** ++ * send a frame using existing sequence and exchange. ++ */ ++static int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, ++ struct fc_frame *fp) ++{ ++ struct fc_exch *ep; ++ struct fc_frame_header *fh = fc_frame_header_get(fp); ++ int error; ++ u32 f_ctl; ++ ++ ep = fc_seq_exch(sp); ++ WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); ++ ++ f_ctl = ntoh24(fh->fh_f_ctl); ++ fc_exch_setup_hdr(ep, fp, f_ctl); ++ ++ /* ++ * update sequence count if this frame is carrying ++ * multiple FC frames when sequence offload is enabled ++ * by LLD. ++ */ ++ if (fr_max_payload(fp)) ++ sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)), ++ fr_max_payload(fp)); ++ else ++ sp->cnt++; ++ ++ /* ++ * Send the frame. ++ */ ++ error = lp->tt.frame_send(lp, fp); ++ ++ /* ++ * Update the exchange and sequence flags, ++ * assuming all frames for the sequence have been sent. ++ * We can only be called to send once for each sequence. ++ */ ++ spin_lock_bh(&ep->ex_lock); ++ ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ ++ if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT)) ++ ep->esb_stat &= ~ESB_ST_SEQ_INIT; ++ spin_unlock_bh(&ep->ex_lock); ++ return error; ++} ++ ++/** ++ * fc_seq_alloc() - Allocate a sequence. ++ * @ep: Exchange pointer ++ * @seq_id: Sequence ID to allocate a sequence for ++ * ++ * We don't support multiple originated sequences on the same exchange. ++ * By implication, any previously originated sequence on this exchange ++ * is complete, and we reallocate the same sequence. ++ */ ++static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) ++{ ++ struct fc_seq *sp; ++ ++ sp = &ep->seq; ++ sp->ssb_stat = 0; ++ sp->cnt = 0; ++ sp->id = seq_id; ++ return sp; ++} ++ ++static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp) ++{ ++ struct fc_exch *ep = fc_seq_exch(sp); ++ ++ sp = fc_seq_alloc(ep, ep->seq_id++); ++ FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", ++ ep->f_ctl, sp->id); ++ return sp; ++} ++ ++/** ++ * Allocate a new sequence on the same exchange as the supplied sequence. ++ * This will never return NULL. ++ */ ++static struct fc_seq *fc_seq_start_next(struct fc_seq *sp) ++{ ++ struct fc_exch *ep = fc_seq_exch(sp); ++ ++ spin_lock_bh(&ep->ex_lock); ++ sp = fc_seq_start_next_locked(sp); ++ spin_unlock_bh(&ep->ex_lock); ++ ++ return sp; ++} ++ ++/** ++ * This function is for seq_exch_abort function pointer in ++ * struct libfc_function_template, see comment block on ++ * seq_exch_abort for description of this function. ++ */ ++static int fc_seq_exch_abort(const struct fc_seq *req_sp, ++ unsigned int timer_msec) + { + struct fc_seq *sp; + struct fc_exch *ep; +@@ -392,7 +519,6 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec) + error = -ENOBUFS; + return error; + } +-EXPORT_SYMBOL(fc_seq_exch_abort); + + /* + * Exchange timeout - handle exchange timer expiration. +@@ -408,6 +534,8 @@ static void fc_exch_timeout(struct work_struct *work) u32 e_stat; int rc = 1; @@ -826882,7 +890980,7 @@ index 145ab9b..c1c1574 100644 spin_lock_bh(&ep->ex_lock); if (ep->state & (FC_EX_RST_CLEANUP | FC_EX_DONE)) goto unlock; -@@ -427,7 +459,7 @@ static void fc_exch_timeout(struct work_struct *work) +@@ -427,7 +555,7 @@ static void fc_exch_timeout(struct work_struct *work) rc = fc_exch_done_locked(ep); spin_unlock_bh(&ep->ex_lock); if (!rc) @@ -826891,26 +890989,44 @@ index 145ab9b..c1c1574 100644 if (resp) resp(sp, ERR_PTR(-FC_EX_TIMEOUT), arg); fc_seq_exch_abort(sp, 2 * ep->r_a_tov); -@@ -460,65 +492,20 @@ static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) - return sp; +@@ -442,83 +570,20 @@ done: + fc_exch_release(ep); } -/* -- * fc_em_alloc_xid - returns an xid based on request type -- * @lp : ptr to associated lport -- * @fp : ptr to the assocated frame +- * Allocate a sequence. +/** + * fc_exch_em_alloc() - allocate an exchange from a specified EM. + * @lport: ptr to the local port + * @mp: ptr to the exchange manager * +- * We don't support multiple originated sequences on the same exchange. +- * By implication, any previously originated sequence on this exchange +- * is complete, and we reallocate the same sequence. ++ * Returns pointer to allocated fc_exch with exch lock held. + */ +-static struct fc_seq *fc_seq_alloc(struct fc_exch *ep, u8 seq_id) +-{ +- struct fc_seq *sp; +- +- sp = &ep->seq; +- sp->ssb_stat = 0; +- sp->cnt = 0; +- sp->id = seq_id; +- return sp; +-} +- +-/* +- * fc_em_alloc_xid - returns an xid based on request type +- * @lp : ptr to associated lport +- * @fp : ptr to the assocated frame +- * - * check the associated fc_fsp_pkt to get scsi command type and - * command direction to decide from which range this exch id - * will be allocated from. - * - * Returns : 0 or an valid xid -+ * Returns pointer to allocated fc_exch with exch lock held. - */ +- */ -static u16 fc_em_alloc_xid(struct fc_exch_mgr *mp, const struct fc_frame *fp) -{ - u16 xid, min, max; @@ -826967,7 +891083,7 @@ index 145ab9b..c1c1574 100644 /* allocate memory for exchange */ ep = mempool_alloc(mp->ep_pool, GFP_ATOMIC); -@@ -528,16 +515,17 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, +@@ -528,16 +593,17 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, } memset(ep, 0, sizeof(*ep)); @@ -826993,7 +891109,7 @@ index 145ab9b..c1c1574 100644 fc_exch_hold(ep); /* hold for exch in mp */ spin_lock_init(&ep->ex_lock); -@@ -548,18 +536,19 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, +@@ -548,18 +614,19 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, */ spin_lock_bh(&ep->ex_lock); @@ -827019,7 +891135,7 @@ index 145ab9b..c1c1574 100644 ep->f_ctl = FC_FC_FIRST_SEQ; /* next seq is first seq */ ep->rxid = FC_XID_UNKNOWN; ep->class = mp->class; -@@ -567,11 +556,36 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, +@@ -567,33 +634,66 @@ struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, out: return ep; err: @@ -827029,6 +891145,7 @@ index 145ab9b..c1c1574 100644 mempool_free(ep, mp->ep_pool); return NULL; } +-EXPORT_SYMBOL(fc_exch_alloc); + +/** + * fc_exch_alloc() - allocate an exchange. @@ -827040,7 +891157,8 @@ index 145ab9b..c1c1574 100644 + * EM is selected having either a NULL match function pointer + * or call to match function returning true. + */ -+struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp) ++static struct fc_exch *fc_exch_alloc(struct fc_lport *lport, ++ struct fc_frame *fp) +{ + struct fc_exch_mgr_anchor *ema; + struct fc_exch *ep; @@ -827054,10 +891172,9 @@ index 145ab9b..c1c1574 100644 + } + return NULL; +} - EXPORT_SYMBOL(fc_exch_alloc); /* -@@ -579,16 +593,18 @@ EXPORT_SYMBOL(fc_exch_alloc); + * Lookup and hold an exchange. */ static struct fc_exch *fc_exch_find(struct fc_exch_mgr *mp, u16 xid) { @@ -827079,16 +891196,28 @@ index 145ab9b..c1c1574 100644 } return ep; } -@@ -602,7 +618,7 @@ void fc_exch_done(struct fc_seq *sp) + +-void fc_exch_done(struct fc_seq *sp) ++ ++/** ++ * fc_exch_done() - Indicate that an exchange/sequence tuple is complete and ++ * the memory allocated for the related objects may be freed. ++ * @sp: Sequence pointer ++ */ ++static void fc_exch_done(struct fc_seq *sp) + { + struct fc_exch *ep = fc_seq_exch(sp); + int rc; +@@ -602,20 +702,21 @@ void fc_exch_done(struct fc_seq *sp) rc = fc_exch_done_locked(ep); spin_unlock_bh(&ep->ex_lock); if (!rc) - fc_exch_mgr_delete_ep(ep); + fc_exch_delete(ep); } - EXPORT_SYMBOL(fc_exch_done); +-EXPORT_SYMBOL(fc_exch_done); -@@ -610,12 +626,14 @@ EXPORT_SYMBOL(fc_exch_done); + /* * Allocate a new exchange as responder. * Sets the responder ID in the frame header. */ @@ -827105,7 +891234,7 @@ index 145ab9b..c1c1574 100644 if (ep) { ep->class = fc_frame_class(fp); -@@ -641,7 +659,7 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) +@@ -641,7 +742,7 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) ep->esb_stat &= ~ESB_ST_SEQ_INIT; fc_exch_hold(ep); /* hold for caller */ @@ -827114,7 +891243,7 @@ index 145ab9b..c1c1574 100644 } return ep; } -@@ -651,7 +669,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) +@@ -651,7 +752,8 @@ static struct fc_exch *fc_exch_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) * If fc_pf_rjt_reason is FC_RJT_NONE then this function will have a hold * on the ep that should be released by the caller. */ @@ -827124,7 +891253,7 @@ index 145ab9b..c1c1574 100644 struct fc_frame *fp) { struct fc_frame_header *fh = fc_frame_header_get(fp); -@@ -705,7 +724,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, +@@ -705,7 +807,7 @@ static enum fc_pf_rjt_reason fc_seq_lookup_recip(struct fc_exch_mgr *mp, reject = FC_RJT_RX_ID; goto rel; } @@ -827133,15 +891262,101 @@ index 145ab9b..c1c1574 100644 if (!ep) { reject = FC_RJT_EXCH_EST; /* XXX */ goto out; -@@ -822,7 +841,6 @@ struct fc_seq *fc_seq_start_next(struct fc_seq *sp) - struct fc_exch *ep = fc_seq_exch(sp); +@@ -804,77 +906,15 @@ static void fc_exch_set_addr(struct fc_exch *ep, + } + } - spin_lock_bh(&ep->ex_lock); +-static struct fc_seq *fc_seq_start_next_locked(struct fc_seq *sp) +-{ +- struct fc_exch *ep = fc_seq_exch(sp); +- +- sp = fc_seq_alloc(ep, ep->seq_id++); +- FC_EXCH_DBG(ep, "f_ctl %6x seq %2x\n", +- ep->f_ctl, sp->id); +- return sp; +-} +-/* +- * Allocate a new sequence on the same exchange as the supplied sequence. +- * This will never return NULL. ++/** ++ * fc_seq_els_rsp_send() - Send ELS response using mainly infomation ++ * in exchange and sequence in EM layer. ++ * @sp: Sequence pointer ++ * @els_cmd: ELS command ++ * @els_data: ELS data + */ +-struct fc_seq *fc_seq_start_next(struct fc_seq *sp) +-{ +- struct fc_exch *ep = fc_seq_exch(sp); +- +- spin_lock_bh(&ep->ex_lock); - WARN_ON((ep->esb_stat & ESB_ST_COMPLETE) != 0); - sp = fc_seq_start_next_locked(sp); - spin_unlock_bh(&ep->ex_lock); +- sp = fc_seq_start_next_locked(sp); +- spin_unlock_bh(&ep->ex_lock); +- +- return sp; +-} +-EXPORT_SYMBOL(fc_seq_start_next); +- +-int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp) +-{ +- struct fc_exch *ep; +- struct fc_frame_header *fh = fc_frame_header_get(fp); +- int error; +- u32 f_ctl; +- +- ep = fc_seq_exch(sp); +- WARN_ON((ep->esb_stat & ESB_ST_SEQ_INIT) != ESB_ST_SEQ_INIT); +- +- f_ctl = ntoh24(fh->fh_f_ctl); +- fc_exch_setup_hdr(ep, fp, f_ctl); +- +- /* +- * update sequence count if this frame is carrying +- * multiple FC frames when sequence offload is enabled +- * by LLD. +- */ +- if (fr_max_payload(fp)) +- sp->cnt += DIV_ROUND_UP((fr_len(fp) - sizeof(*fh)), +- fr_max_payload(fp)); +- else +- sp->cnt++; +- +- /* +- * Send the frame. +- */ +- error = lp->tt.frame_send(lp, fp); +- +- /* +- * Update the exchange and sequence flags, +- * assuming all frames for the sequence have been sent. +- * We can only be called to send once for each sequence. +- */ +- spin_lock_bh(&ep->ex_lock); +- ep->f_ctl = f_ctl & ~FC_FC_FIRST_SEQ; /* not first seq */ +- if (f_ctl & (FC_FC_END_SEQ | FC_FC_SEQ_INIT)) +- ep->esb_stat &= ~ESB_ST_SEQ_INIT; +- spin_unlock_bh(&ep->ex_lock); +- return error; +-} +-EXPORT_SYMBOL(fc_seq_send); +- +-void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, +- struct fc_seq_els_data *els_data) ++static void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, ++ struct fc_seq_els_data *els_data) + { + switch (els_cmd) { + case ELS_LS_RJT: +@@ -893,7 +933,6 @@ void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, + FC_EXCH_DBG(fc_seq_exch(sp), "Invalid ELS CMD:%x\n", els_cmd); + } + } +-EXPORT_SYMBOL(fc_seq_els_rsp_send); -@@ -999,8 +1017,8 @@ static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp, + /* + * Send a sequence, which is also the last sequence in the exchange. +@@ -999,8 +1038,8 @@ static void fc_exch_send_ba_rjt(struct fc_frame *rx_fp, */ memcpy(fh->fh_s_id, rx_fh->fh_d_id, 3); memcpy(fh->fh_d_id, rx_fh->fh_s_id, 3); @@ -827152,16 +891367,26 @@ index 145ab9b..c1c1574 100644 fh->fh_seq_cnt = rx_fh->fh_seq_cnt; fh->fh_r_ctl = FC_RCTL_BA_RJT; fh->fh_type = FC_TYPE_BLS; -@@ -1097,7 +1115,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, +@@ -1096,8 +1135,17 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, + u32 f_ctl; enum fc_pf_rjt_reason reject; ++ /* We can have the wrong fc_lport at this point with NPIV, which is a ++ * problem now that we know a new exchange needs to be allocated ++ */ ++ lp = fc_vport_id_lookup(lp, ntoh24(fh->fh_d_id)); ++ if (!lp) { ++ fc_frame_free(fp); ++ return; ++ } ++ fr_seq(fp) = NULL; - reject = fc_seq_lookup_recip(mp, fp); + reject = fc_seq_lookup_recip(lp, mp, fp); if (reject == FC_RJT_NONE) { sp = fr_seq(fp); /* sequence will be held */ ep = fc_seq_exch(sp); -@@ -1123,7 +1141,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, +@@ -1123,7 +1171,7 @@ static void fc_exch_recv_req(struct fc_lport *lp, struct fc_exch_mgr *mp, lp->tt.lport_recv(lp, sp, fp); fc_exch_release(ep); /* release from lookup */ } else { @@ -827170,7 +891395,7 @@ index 145ab9b..c1c1574 100644 fc_frame_free(fp); } } -@@ -1193,7 +1211,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) +@@ -1193,7 +1241,7 @@ static void fc_exch_recv_seq_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) WARN_ON(fc_seq_exch(sp) != ep); spin_unlock_bh(&ep->ex_lock); if (!rc) @@ -827179,7 +891404,7 @@ index 145ab9b..c1c1574 100644 } /* -@@ -1229,13 +1247,12 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) +@@ -1229,13 +1277,12 @@ static void fc_exch_recv_resp(struct fc_exch_mgr *mp, struct fc_frame *fp) struct fc_seq *sp; sp = fc_seq_lookup_orig(mp, fp); /* doesn't hold sequence */ @@ -827197,7 +891422,7 @@ index 145ab9b..c1c1574 100644 fc_frame_free(fp); } -@@ -1304,7 +1321,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) +@@ -1304,7 +1351,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) rc = fc_exch_done_locked(ep); spin_unlock_bh(&ep->ex_lock); if (!rc) @@ -827206,7 +891431,7 @@ index 145ab9b..c1c1574 100644 if (resp) resp(sp, fp, ex_resp_arg); -@@ -1447,44 +1464,77 @@ static void fc_exch_reset(struct fc_exch *ep) +@@ -1447,44 +1494,77 @@ static void fc_exch_reset(struct fc_exch *ep) rc = fc_exch_done_locked(ep); spin_unlock_bh(&ep->ex_lock); if (!rc) @@ -827299,7 +891524,76 @@ index 145ab9b..c1c1574 100644 } EXPORT_SYMBOL(fc_exch_mgr_reset); -@@ -1730,85 +1780,129 @@ reject: +@@ -1614,6 +1694,68 @@ cleanup: + fc_exch_release(aborted_ep); + } + ++ ++/** ++ * This function is for exch_seq_send function pointer in ++ * struct libfc_function_template, see comment block on ++ * exch_seq_send for description of this function. ++ */ ++static struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, ++ struct fc_frame *fp, ++ void (*resp)(struct fc_seq *, ++ struct fc_frame *fp, ++ void *arg), ++ void (*destructor)(struct fc_seq *, ++ void *), ++ void *arg, u32 timer_msec) ++{ ++ struct fc_exch *ep; ++ struct fc_seq *sp = NULL; ++ struct fc_frame_header *fh; ++ int rc = 1; ++ ++ ep = fc_exch_alloc(lp, fp); ++ if (!ep) { ++ fc_frame_free(fp); ++ return NULL; ++ } ++ ep->esb_stat |= ESB_ST_SEQ_INIT; ++ fh = fc_frame_header_get(fp); ++ fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); ++ ep->resp = resp; ++ ep->destructor = destructor; ++ ep->arg = arg; ++ ep->r_a_tov = FC_DEF_R_A_TOV; ++ ep->lp = lp; ++ sp = &ep->seq; ++ ++ ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ ++ ep->f_ctl = ntoh24(fh->fh_f_ctl); ++ fc_exch_setup_hdr(ep, fp, ep->f_ctl); ++ sp->cnt++; ++ ++ if (ep->xid <= lp->lro_xid) ++ fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); ++ ++ if (unlikely(lp->tt.frame_send(lp, fp))) ++ goto err; ++ ++ if (timer_msec) ++ fc_exch_timer_set_locked(ep, timer_msec); ++ ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ ++ ++ if (ep->f_ctl & FC_FC_SEQ_INIT) ++ ep->esb_stat &= ~ESB_ST_SEQ_INIT; ++ spin_unlock_bh(&ep->ex_lock); ++ return sp; ++err: ++ rc = fc_exch_done_locked(ep); ++ spin_unlock_bh(&ep->ex_lock); ++ if (!rc) ++ fc_exch_delete(ep); ++ return NULL; ++} ++ + /* + * Send ELS RRQ - Reinstate Recovery Qualifier. + * This tells the remote port to stop blocking the use of +@@ -1730,162 +1872,190 @@ reject: fc_frame_free(fp); } @@ -827339,6 +891633,26 @@ index 145ab9b..c1c1574 100644 + kfree(ema); +} +EXPORT_SYMBOL(fc_exch_mgr_del); ++ ++/** ++ * fc_exch_mgr_list_clone() - share all exchange manager objects ++ * @src: source lport to clone exchange managers from ++ * @dst: new lport that takes references to all the exchange managers ++ */ ++int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst) ++{ ++ struct fc_exch_mgr_anchor *ema, *tmp; ++ ++ list_for_each_entry(ema, &src->ema_list, ema_list) { ++ if (!fc_exch_mgr_add(dst, ema->mp, ema->match)) ++ goto err; ++ } ++ return 0; ++err: ++ list_for_each_entry_safe(ema, tmp, &dst->ema_list, ema_list) ++ fc_exch_mgr_del(ema); ++ return -ENOMEM; ++} + struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, enum fc_class class, @@ -827400,6 +891714,7 @@ index 145ab9b..c1c1574 100644 if (!mp->ep_pool) goto free_mp; +- return mp; + /* + * Setup per cpu exch pool with entire exchange id range equally + * divided across all cpus. The exch pointers array memory is @@ -827407,7 +891722,12 @@ index 145ab9b..c1c1574 100644 + */ + pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1); + mp->pool_max_index = pool_exch_range - 1; -+ + +-free_mp: +- kfree(mp); +- return NULL; +-} +-EXPORT_SYMBOL(fc_exch_mgr_alloc); + /* + * Allocate and initialize per cpu exch pool + */ @@ -827426,81 +891746,99 @@ index 145ab9b..c1c1574 100644 + free_percpu(mp->pool); + goto free_mempool; + } -+ -+ /* + +-void fc_exch_mgr_free(struct fc_exch_mgr *mp) +-{ +- WARN_ON(!mp); + /* +- * The total exch count must be zero +- * before freeing exchange manager. + * Above kref_init() sets mp->kref to 1 and then + * call to fc_exch_mgr_add incremented mp->kref again, + * so adjust that extra increment. -+ */ -+ kref_put(&mp->kref, fc_exch_mgr_destroy); - return mp; - -+free_mempool: -+ mempool_destroy(mp->ep_pool); - free_mp: - kfree(mp); - return NULL; - } - EXPORT_SYMBOL(fc_exch_mgr_alloc); - --void fc_exch_mgr_free(struct fc_exch_mgr *mp) -+void fc_exch_mgr_free(struct fc_lport *lport) - { -- WARN_ON(!mp); -- /* -- * The total exch count must be zero -- * before freeing exchange manager. -- */ + */ - WARN_ON(mp->total_exches != 0); -- mempool_destroy(mp->ep_pool); -- kfree(mp); -+ struct fc_exch_mgr_anchor *ema, *next; ++ kref_put(&mp->kref, fc_exch_mgr_destroy); ++ return mp; + -+ list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list) -+ fc_exch_mgr_del(ema); ++free_mempool: + mempool_destroy(mp->ep_pool); ++free_mp: + kfree(mp); ++ return NULL; } - EXPORT_SYMBOL(fc_exch_mgr_free); - +-EXPORT_SYMBOL(fc_exch_mgr_free); +- -struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp) -{ - if (!lp || !lp->emp) - return NULL; -- ++EXPORT_SYMBOL(fc_exch_mgr_alloc); + - return fc_exch_alloc(lp->emp, fp, 0); -} -EXPORT_SYMBOL(fc_exch_get); - - struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, - struct fc_frame *fp, -@@ -1823,7 +1917,7 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, - struct fc_frame_header *fh; - int rc = 1; - +- +-struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, +- struct fc_frame *fp, +- void (*resp)(struct fc_seq *, +- struct fc_frame *fp, +- void *arg), +- void (*destructor)(struct fc_seq *, void *), +- void *arg, u32 timer_msec) ++void fc_exch_mgr_free(struct fc_lport *lport) + { +- struct fc_exch *ep; +- struct fc_seq *sp = NULL; +- struct fc_frame_header *fh; +- int rc = 1; +- - ep = lp->tt.exch_get(lp, fp); -+ ep = fc_exch_alloc(lp, fp); - if (!ep) { - fc_frame_free(fp); - return NULL; -@@ -1843,7 +1937,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, - fc_exch_setup_hdr(ep, fp, ep->f_ctl); - sp->cnt++; - +- if (!ep) { +- fc_frame_free(fp); +- return NULL; +- } +- ep->esb_stat |= ESB_ST_SEQ_INIT; +- fh = fc_frame_header_get(fp); +- fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); +- ep->resp = resp; +- ep->destructor = destructor; +- ep->arg = arg; +- ep->r_a_tov = FC_DEF_R_A_TOV; +- ep->lp = lp; +- sp = &ep->seq; +- +- ep->fh_type = fh->fh_type; /* save for possbile timeout handling */ +- ep->f_ctl = ntoh24(fh->fh_f_ctl); +- fc_exch_setup_hdr(ep, fp, ep->f_ctl); +- sp->cnt++; +- - fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); -+ if (ep->xid <= lp->lro_xid) -+ fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); +- +- if (unlikely(lp->tt.frame_send(lp, fp))) +- goto err; +- +- if (timer_msec) +- fc_exch_timer_set_locked(ep, timer_msec); +- ep->f_ctl &= ~FC_FC_FIRST_SEQ; /* not first seq */ ++ struct fc_exch_mgr_anchor *ema, *next; - if (unlikely(lp->tt.frame_send(lp, fp))) - goto err; -@@ -1860,7 +1955,7 @@ err: - rc = fc_exch_done_locked(ep); - spin_unlock_bh(&ep->ex_lock); - if (!rc) +- if (ep->f_ctl & FC_FC_SEQ_INIT) +- ep->esb_stat &= ~ESB_ST_SEQ_INIT; +- spin_unlock_bh(&ep->ex_lock); +- return sp; +-err: +- rc = fc_exch_done_locked(ep); +- spin_unlock_bh(&ep->ex_lock); +- if (!rc) - fc_exch_mgr_delete_ep(ep); -+ fc_exch_delete(ep); - return NULL; +- return NULL; ++ list_for_each_entry_safe(ema, next, &lport->ema_list, ema_list) ++ fc_exch_mgr_del(ema); } - EXPORT_SYMBOL(fc_exch_seq_send); -@@ -1868,24 +1963,44 @@ EXPORT_SYMBOL(fc_exch_seq_send); +-EXPORT_SYMBOL(fc_exch_seq_send); ++EXPORT_SYMBOL(fc_exch_mgr_free); + /* * Receive a frame */ @@ -827550,7 +891888,7 @@ index 145ab9b..c1c1574 100644 switch (fr_eof(fp)) { case FC_EOF_T: if (f_ctl & FC_FC_END_SEQ) -@@ -1893,34 +2008,24 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, +@@ -1893,34 +2063,24 @@ void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, /* fall through */ case FC_EOF_N: if (fh->fh_type == FC_TYPE_BLS) @@ -827590,7 +891928,7 @@ index 145ab9b..c1c1574 100644 if (!lp->tt.seq_start_next) lp->tt.seq_start_next = fc_seq_start_next; -@@ -1942,6 +2047,28 @@ int fc_exch_init(struct fc_lport *lp) +@@ -1942,6 +2102,28 @@ int fc_exch_init(struct fc_lport *lp) if (!lp->tt.seq_exch_abort) lp->tt.seq_exch_abort = fc_seq_exch_abort; @@ -827620,10 +891958,140 @@ index 145ab9b..c1c1574 100644 } EXPORT_SYMBOL(fc_exch_init); diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c -index e303e0d..59a4408 100644 +index e303e0d..7edf4d0 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c -@@ -507,33 +507,6 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, +@@ -39,15 +39,9 @@ + #include + #include + +-MODULE_AUTHOR("Open-FCoE.org"); +-MODULE_DESCRIPTION("libfc"); +-MODULE_LICENSE("GPL v2"); ++#include "fc_libfc.h" + +-unsigned int fc_debug_logging; +-module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR); +-MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); +- +-static struct kmem_cache *scsi_pkt_cachep; ++struct kmem_cache *scsi_pkt_cachep; + + /* SRB state definitions */ + #define FC_SRB_FREE 0 /* cmd is free */ +@@ -285,7 +279,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid) + fsp->xfer_ddp = xid; + } + } +-EXPORT_SYMBOL(fc_fcp_ddp_setup); + + /* + * fc_fcp_ddp_done - calls to LLD's ddp_done to release any +@@ -302,10 +295,13 @@ static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp) + if (!fsp) + return; + ++ if (fsp->xfer_ddp == FC_XID_UNKNOWN) ++ return; ++ + lp = fsp->lp; +- if (fsp->xfer_ddp && lp->tt.ddp_done) { ++ if (lp->tt.ddp_done) { + fsp->xfer_len = lp->tt.ddp_done(lp, fsp->xfer_ddp); +- fsp->xfer_ddp = 0; ++ fsp->xfer_ddp = FC_XID_UNKNOWN; + } + } + +@@ -327,7 +323,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + size_t len; + void *buf; + struct scatterlist *sg; +- size_t remaining; ++ u32 nents; + + fh = fc_frame_header_get(fp); + offset = ntohl(fh->fh_parm_offset); +@@ -351,55 +347,19 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + if (offset != fsp->xfer_len) + fsp->state |= FC_SRB_DISCONTIG; + +- crc = 0; +- if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) +- crc = crc32(~0, (u8 *) fh, sizeof(*fh)); +- + sg = scsi_sglist(sc); +- remaining = len; +- +- while (remaining > 0 && sg) { +- size_t off; +- void *page_addr; +- size_t sg_bytes; +- +- if (offset >= sg->length) { +- offset -= sg->length; +- sg = sg_next(sg); +- continue; +- } +- sg_bytes = min(remaining, sg->length - offset); ++ nents = scsi_sg_count(sc); + +- /* +- * The scatterlist item may be bigger than PAGE_SIZE, +- * but we are limited to mapping PAGE_SIZE at a time. +- */ +- off = offset + sg->offset; +- sg_bytes = min(sg_bytes, (size_t) +- (PAGE_SIZE - (off & ~PAGE_MASK))); +- page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT), +- KM_SOFTIRQ0); +- if (!page_addr) +- break; /* XXX panic? */ +- +- if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) +- crc = crc32(crc, buf, sg_bytes); +- memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, +- sg_bytes); +- +- kunmap_atomic(page_addr, KM_SOFTIRQ0); +- buf += sg_bytes; +- offset += sg_bytes; +- remaining -= sg_bytes; +- copy_len += sg_bytes; +- } +- +- if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) { ++ if (!(fr_flags(fp) & FCPHF_CRC_UNCHECKED)) { ++ copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, ++ &offset, KM_SOFTIRQ0, NULL); ++ } else { ++ crc = crc32(~0, (u8 *) fh, sizeof(*fh)); ++ copy_len = fc_copy_buffer_to_sglist(buf, len, sg, &nents, ++ &offset, KM_SOFTIRQ0, &crc); + buf = fc_frame_payload_get(fp, 0); +- if (len % 4) { ++ if (len % 4) + crc = crc32(crc, buf + len, 4 - (len % 4)); +- len += 4 - (len % 4); +- } + + if (~crc != le32_to_cpu(fr_crc(fp))) { + crc_err: +@@ -458,11 +418,13 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, + struct scatterlist *sg; + struct fc_frame *fp = NULL; + struct fc_lport *lp = fsp->lp; ++ struct page *page; + size_t remaining; + size_t t_blen; + size_t tlen; + size_t sg_bytes; + size_t frame_offset, fh_parm_offset; ++ size_t off; + int error; + void *data = NULL; + void *page_addr; +@@ -507,33 +469,6 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, f_ctl = FC_FC_REL_OFF; WARN_ON(!seq); @@ -827657,16 +892125,55 @@ index e303e0d..59a4408 100644 sg = scsi_sglist(sc); while (remaining > 0 && sg) { -@@ -569,8 +542,6 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, +@@ -567,30 +502,26 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, + fh_parm_offset = frame_offset; + fr_max_payload(fp) = fsp->max_payload; } ++ ++ off = offset + sg->offset; sg_bytes = min(tlen, sg->length - offset); ++ sg_bytes = min(sg_bytes, ++ (size_t) (PAGE_SIZE - (off & ~PAGE_MASK))); ++ page = sg_page(sg) + (off >> PAGE_SHIFT); if (using_sg) { - WARN_ON(skb_shinfo(fp_skb(fp))->nr_frags > - FC_FRAME_SG_LEN); - get_page(sg_page(sg)); +- get_page(sg_page(sg)); ++ get_page(page); skb_fill_page_desc(fp_skb(fp), skb_shinfo(fp_skb(fp))->nr_frags, -@@ -1337,7 +1308,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp) +- sg_page(sg), sg->offset + offset, +- sg_bytes); ++ page, off & ~PAGE_MASK, sg_bytes); + fp_skb(fp)->data_len += sg_bytes; + fr_len(fp) += sg_bytes; + fp_skb(fp)->truesize += PAGE_SIZE; + } else { +- size_t off = offset + sg->offset; +- + /* + * The scatterlist item may be bigger than PAGE_SIZE, + * but we must not cross pages inside the kmap. + */ +- sg_bytes = min(sg_bytes, (size_t) (PAGE_SIZE - +- (off & ~PAGE_MASK))); +- page_addr = kmap_atomic(sg_page(sg) + +- (off >> PAGE_SHIFT), +- KM_SOFTIRQ0); ++ page_addr = kmap_atomic(page, KM_SOFTIRQ0); + memcpy(data, (char *)page_addr + (off & ~PAGE_MASK), + sg_bytes); + kunmap_atomic(page_addr, KM_SOFTIRQ0); +@@ -1124,7 +1055,7 @@ unlock: + * Scsi abort handler- calls to send an abort + * and then wait for abort completion + */ +-static int fc_fcp_pkt_abort(struct fc_lport *lp, struct fc_fcp_pkt *fsp) ++static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp) + { + int rc = FAILED; + +@@ -1337,7 +1268,7 @@ static void fc_fcp_rec(struct fc_fcp_pkt *fsp) fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rport->port_id, fc_host_port_id(rp->local_port->host), FC_TYPE_ELS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0); @@ -827675,11 +892182,441 @@ index e303e0d..59a4408 100644 fsp, jiffies_to_msecs(FC_SCSI_REC_TOV))) { fc_fcp_pkt_hold(fsp); /* hold while REC outstanding */ return; +@@ -1737,6 +1668,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *)) + fsp->cmd = sc_cmd; /* save the cmd */ + fsp->lp = lp; /* save the softc ptr */ + fsp->rport = rport; /* set the remote port ptr */ ++ fsp->xfer_ddp = FC_XID_UNKNOWN; + sc_cmd->scsi_done = done; + + /* +@@ -1875,7 +1807,8 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) + * scsi status is good but transport level + * underrun. + */ +- sc_cmd->result = DID_OK << 16; ++ sc_cmd->result = (fsp->state & FC_SRB_RCV_STATUS ? ++ DID_OK : DID_ERROR) << 16; + } else { + /* + * scsi got underrun, this is an error +@@ -1917,23 +1850,6 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp) + } + + /** +- * fc_fcp_complete() - complete processing of a fcp packet +- * @fsp: fcp packet +- * +- * This function may sleep if a fsp timer is pending. +- * The host lock must not be held by caller. +- */ +-void fc_fcp_complete(struct fc_fcp_pkt *fsp) +-{ +- if (fc_fcp_lock_pkt(fsp)) +- return; +- +- fc_fcp_complete_locked(fsp); +- fc_fcp_unlock_pkt(fsp); +-} +-EXPORT_SYMBOL(fc_fcp_complete); +- +-/** + * fc_eh_abort() - Abort a command + * @sc_cmd: scsi command to abort + * +@@ -1971,7 +1887,7 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) + goto release_pkt; + } + +- rc = fc_fcp_pkt_abort(lp, fsp); ++ rc = fc_fcp_pkt_abort(fsp); + fc_fcp_unlock_pkt(fsp); + + release_pkt: +@@ -2127,6 +2043,28 @@ void fc_fcp_destroy(struct fc_lport *lp) + } + EXPORT_SYMBOL(fc_fcp_destroy); + ++int fc_setup_fcp() ++{ ++ int rc = 0; ++ ++ scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt", ++ sizeof(struct fc_fcp_pkt), ++ 0, SLAB_HWCACHE_ALIGN, NULL); ++ if (!scsi_pkt_cachep) { ++ printk(KERN_ERR "libfc: Unable to allocate SRB cache, " ++ "module load failed!"); ++ rc = -ENOMEM; ++ } ++ ++ return rc; ++} ++ ++void fc_destroy_fcp() ++{ ++ if (scsi_pkt_cachep) ++ kmem_cache_destroy(scsi_pkt_cachep); ++} ++ + int fc_fcp_init(struct fc_lport *lp) + { + int rc; +@@ -2159,42 +2097,3 @@ free_internal: + return rc; + } + EXPORT_SYMBOL(fc_fcp_init); +- +-static int __init libfc_init(void) +-{ +- int rc; +- +- scsi_pkt_cachep = kmem_cache_create("libfc_fcp_pkt", +- sizeof(struct fc_fcp_pkt), +- 0, SLAB_HWCACHE_ALIGN, NULL); +- if (scsi_pkt_cachep == NULL) { +- printk(KERN_ERR "libfc: Unable to allocate SRB cache, " +- "module load failed!"); +- return -ENOMEM; +- } +- +- rc = fc_setup_exch_mgr(); +- if (rc) +- goto destroy_pkt_cache; +- +- rc = fc_setup_rport(); +- if (rc) +- goto destroy_em; +- +- return rc; +-destroy_em: +- fc_destroy_exch_mgr(); +-destroy_pkt_cache: +- kmem_cache_destroy(scsi_pkt_cachep); +- return rc; +-} +- +-static void __exit libfc_exit(void) +-{ +- kmem_cache_destroy(scsi_pkt_cachep); +- fc_destroy_exch_mgr(); +- fc_destroy_rport(); +-} +- +-module_init(libfc_init); +-module_exit(libfc_exit); +diff --git a/drivers/scsi/libfc/fc_frame.c b/drivers/scsi/libfc/fc_frame.c +index 63fe00c..8ddb685 100644 +--- a/drivers/scsi/libfc/fc_frame.c ++++ b/drivers/scsi/libfc/fc_frame.c +@@ -58,18 +58,18 @@ struct fc_frame *__fc_frame_alloc(size_t len) + + WARN_ON((len % sizeof(u32)) != 0); + len += sizeof(struct fc_frame_header); +- skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM); ++ skb = alloc_skb_fclone(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM + ++ NET_SKB_PAD, GFP_ATOMIC); + if (!skb) + return NULL; ++ skb_reserve(skb, NET_SKB_PAD + FC_FRAME_HEADROOM); + fp = (struct fc_frame *) skb; + fc_frame_init(fp); +- skb_reserve(skb, FC_FRAME_HEADROOM); + skb_put(skb, len); + return fp; + } + EXPORT_SYMBOL(__fc_frame_alloc); + +- + struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len) + { + struct fc_frame *fp; +@@ -87,3 +87,4 @@ struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len) + } + return fp; + } ++EXPORT_SYMBOL(fc_frame_alloc_fill); +diff --git a/drivers/scsi/libfc/fc_libfc.c b/drivers/scsi/libfc/fc_libfc.c +new file mode 100644 +index 0000000..295eafb +--- /dev/null ++++ b/drivers/scsi/libfc/fc_libfc.c +@@ -0,0 +1,134 @@ ++/* ++ * Copyright(c) 2009 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Maintained at www.Open-FCoE.org ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "fc_libfc.h" ++ ++MODULE_AUTHOR("Open-FCoE.org"); ++MODULE_DESCRIPTION("libfc"); ++MODULE_LICENSE("GPL v2"); ++ ++unsigned int fc_debug_logging; ++module_param_named(debug_logging, fc_debug_logging, int, S_IRUGO|S_IWUSR); ++MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels"); ++ ++/** ++ * libfc_init() - Initialize libfc.ko ++ */ ++static int __init libfc_init(void) ++{ ++ int rc = 0; ++ ++ rc = fc_setup_fcp(); ++ if (rc) ++ return rc; ++ ++ rc = fc_setup_exch_mgr(); ++ if (rc) ++ goto destroy_pkt_cache; ++ ++ rc = fc_setup_rport(); ++ if (rc) ++ goto destroy_em; ++ ++ return rc; ++destroy_em: ++ fc_destroy_exch_mgr(); ++destroy_pkt_cache: ++ fc_destroy_fcp(); ++ return rc; ++} ++module_init(libfc_init); ++ ++/** ++ * libfc_exit() - Tear down libfc.ko ++ */ ++static void __exit libfc_exit(void) ++{ ++ fc_destroy_fcp(); ++ fc_destroy_exch_mgr(); ++ fc_destroy_rport(); ++} ++module_exit(libfc_exit); ++ ++/** ++ * fc_copy_buffer_to_sglist() - This routine copies the data of a buffer ++ * into a scatter-gather list (SG list). ++ * ++ * @buf: pointer to the data buffer. ++ * @len: the byte-length of the data buffer. ++ * @sg: pointer to the pointer of the SG list. ++ * @nents: pointer to the remaining number of entries in the SG list. ++ * @offset: pointer to the current offset in the SG list. ++ * @km_type: dedicated page table slot type for kmap_atomic. ++ * @crc: pointer to the 32-bit crc value. ++ * If crc is NULL, CRC is not calculated. ++ */ ++u32 fc_copy_buffer_to_sglist(void *buf, size_t len, ++ struct scatterlist *sg, ++ u32 *nents, size_t *offset, ++ enum km_type km_type, u32 *crc) ++{ ++ size_t remaining = len; ++ u32 copy_len = 0; ++ ++ while (remaining > 0 && sg) { ++ size_t off, sg_bytes; ++ void *page_addr; ++ ++ if (*offset >= sg->length) { ++ /* ++ * Check for end and drop resources ++ * from the last iteration. ++ */ ++ if (!(*nents)) ++ break; ++ --(*nents); ++ *offset -= sg->length; ++ sg = sg_next(sg); ++ continue; ++ } ++ sg_bytes = min(remaining, sg->length - *offset); ++ ++ /* ++ * The scatterlist item may be bigger than PAGE_SIZE, ++ * but we are limited to mapping PAGE_SIZE at a time. ++ */ ++ off = *offset + sg->offset; ++ sg_bytes = min(sg_bytes, ++ (size_t)(PAGE_SIZE - (off & ~PAGE_MASK))); ++ page_addr = kmap_atomic(sg_page(sg) + (off >> PAGE_SHIFT), ++ km_type); ++ if (crc) ++ *crc = crc32(*crc, buf, sg_bytes); ++ memcpy((char *)page_addr + (off & ~PAGE_MASK), buf, sg_bytes); ++ kunmap_atomic(page_addr, km_type); ++ buf += sg_bytes; ++ *offset += sg_bytes; ++ remaining -= sg_bytes; ++ copy_len += sg_bytes; ++ } ++ return copy_len; ++} +diff --git a/drivers/scsi/libfc/fc_libfc.h b/drivers/scsi/libfc/fc_libfc.h +new file mode 100644 +index 0000000..e4b5e92 +--- /dev/null ++++ b/drivers/scsi/libfc/fc_libfc.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright(c) 2009 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Maintained at www.Open-FCoE.org ++ */ ++ ++#ifndef _FC_LIBFC_H_ ++#define _FC_LIBFC_H_ ++ ++#define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */ ++#define FC_LPORT_LOGGING 0x02 /* lport layer logging */ ++#define FC_DISC_LOGGING 0x04 /* discovery layer logging */ ++#define FC_RPORT_LOGGING 0x08 /* rport layer logging */ ++#define FC_FCP_LOGGING 0x10 /* I/O path logging */ ++#define FC_EM_LOGGING 0x20 /* Exchange Manager logging */ ++#define FC_EXCH_LOGGING 0x40 /* Exchange/Sequence logging */ ++#define FC_SCSI_LOGGING 0x80 /* SCSI logging (mostly error handling) */ ++ ++extern unsigned int fc_debug_logging; ++ ++#define FC_CHECK_LOGGING(LEVEL, CMD) \ ++do { \ ++ if (unlikely(fc_debug_logging & LEVEL)) \ ++ do { \ ++ CMD; \ ++ } while (0); \ ++} while (0) ++ ++#define FC_LIBFC_DBG(fmt, args...) \ ++ FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ ++ printk(KERN_INFO "libfc: " fmt, ##args)) ++ ++#define FC_LPORT_DBG(lport, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ ++ printk(KERN_INFO "host%u: lport %6x: " fmt, \ ++ (lport)->host->host_no, \ ++ fc_host_port_id((lport)->host), ##args)) ++ ++#define FC_DISC_DBG(disc, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_DISC_LOGGING, \ ++ printk(KERN_INFO "host%u: disc: " fmt, \ ++ (disc)->lport->host->host_no, \ ++ ##args)) ++ ++#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ ++ printk(KERN_INFO "host%u: rport %6x: " fmt, \ ++ (lport)->host->host_no, \ ++ (port_id), ##args)) ++ ++#define FC_RPORT_DBG(rdata, fmt, args...) \ ++ FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args) ++ ++#define FC_FCP_DBG(pkt, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_FCP_LOGGING, \ ++ printk(KERN_INFO "host%u: fcp: %6x: " fmt, \ ++ (pkt)->lp->host->host_no, \ ++ pkt->rport->port_id, ##args)) ++ ++#define FC_EXCH_DBG(exch, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ ++ printk(KERN_INFO "host%u: xid %4x: " fmt, \ ++ (exch)->lp->host->host_no, \ ++ exch->xid, ##args)) ++ ++#define FC_SCSI_DBG(lport, fmt, args...) \ ++ FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ ++ printk(KERN_INFO "host%u: scsi: " fmt, \ ++ (lport)->host->host_no, ##args)) ++ ++/* ++ * Set up direct-data placement for this I/O request ++ */ ++void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid); ++ ++/* ++ * Module setup functions ++ */ ++int fc_setup_exch_mgr(void); ++void fc_destroy_exch_mgr(void); ++int fc_setup_rport(void); ++void fc_destroy_rport(void); ++int fc_setup_fcp(void); ++void fc_destroy_fcp(void); ++ ++/* ++ * Internal libfc functions ++ */ ++const char *fc_els_resp_type(struct fc_frame *); ++ ++/* ++ * Copies a buffer into an sg list ++ */ ++u32 fc_copy_buffer_to_sglist(void *buf, size_t len, ++ struct scatterlist *sg, ++ u32 *nents, size_t *offset, ++ enum km_type km_type, u32 *crc); ++ ++#endif /* _FC_LIBFC_H_ */ diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c -index 745fa55..bd2f771 100644 +index 745fa55..33f4c2f 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c -@@ -113,7 +113,7 @@ static void fc_lport_enter_ready(struct fc_lport *); +@@ -94,6 +94,9 @@ + + #include + #include ++#include ++ ++#include "fc_libfc.h" + + /* Fabric IDs to use for point-to-point mode, chosen on whims. */ + #define FC_LOCAL_PTP_FID_LO 0x010101 +@@ -106,17 +109,18 @@ static void fc_lport_error(struct fc_lport *, struct fc_frame *); + static void fc_lport_enter_reset(struct fc_lport *); + static void fc_lport_enter_flogi(struct fc_lport *); + static void fc_lport_enter_dns(struct fc_lport *); +-static void fc_lport_enter_rpn_id(struct fc_lport *); +-static void fc_lport_enter_rft_id(struct fc_lport *); ++static void fc_lport_enter_ns(struct fc_lport *, enum fc_lport_state); + static void fc_lport_enter_scr(struct fc_lport *); + static void fc_lport_enter_ready(struct fc_lport *); static void fc_lport_enter_logo(struct fc_lport *); static const char *fc_lport_state_names[] = { @@ -827687,8 +892624,39 @@ index 745fa55..bd2f771 100644 + [LPORT_ST_DISABLED] = "disabled", [LPORT_ST_FLOGI] = "FLOGI", [LPORT_ST_DNS] = "dNS", - [LPORT_ST_RPN_ID] = "RPN_ID", -@@ -133,57 +133,44 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) +- [LPORT_ST_RPN_ID] = "RPN_ID", ++ [LPORT_ST_RNN_ID] = "RNN_ID", ++ [LPORT_ST_RSNN_NN] = "RSNN_NN", ++ [LPORT_ST_RSPN_ID] = "RSPN_ID", + [LPORT_ST_RFT_ID] = "RFT_ID", + [LPORT_ST_SCR] = "SCR", + [LPORT_ST_READY] = "Ready", +@@ -124,6 +128,24 @@ static const char *fc_lport_state_names[] = { + [LPORT_ST_RESET] = "reset", + }; + ++/** ++ * struct fc_bsg_info - FC Passthrough managemet structure ++ * @job: The passthrough job ++ * @lport: The local port to pass through a command ++ * @rsp_code: The expected response code ++ * @sg: job->reply_payload.sg_list ++ * @nents: job->reply_payload.sg_cnt ++ * @offset: The offset into the response data ++ */ ++struct fc_bsg_info { ++ struct fc_bsg_job *job; ++ struct fc_lport *lport; ++ u16 rsp_code; ++ struct scatterlist *sg; ++ u32 nents; ++ size_t offset; ++}; ++ + static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) + { + fc_frame_free(fp); +@@ -133,57 +155,44 @@ static int fc_frame_drop(struct fc_lport *lport, struct fc_frame *fp) /** * fc_lport_rport_callback() - Event handler for rport events * @lport: The lport which is receiving the event @@ -827733,7 +892701,7 @@ index 745fa55..bd2f771 100644 + case RPORT_EV_READY: + if (lport->state == LPORT_ST_DNS) { + lport->dns_rp = rdata; -+ fc_lport_enter_rpn_id(lport); ++ fc_lport_enter_ns(lport, LPORT_ST_RNN_ID); + } else { + FC_LPORT_DBG(lport, "Received an READY event " + "on port (%6x) for the directory " @@ -827765,7 +892733,7 @@ index 745fa55..bd2f771 100644 } /** -@@ -211,20 +198,13 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, +@@ -211,20 +220,13 @@ static void fc_lport_ptp_setup(struct fc_lport *lport, u32 remote_fid, u64 remote_wwpn, u64 remote_wwnn) { @@ -827792,7 +892760,29 @@ index 745fa55..bd2f771 100644 lport->tt.rport_login(lport->ptp_rp); -@@ -472,56 +452,6 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, +@@ -242,10 +244,18 @@ void fc_get_host_port_state(struct Scsi_Host *shost) + { + struct fc_lport *lp = shost_priv(shost); + +- if (lp->link_up) +- fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; ++ mutex_lock(&lp->lp_mutex); ++ if (!lp->link_up) ++ fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; + else +- fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; ++ switch (lp->state) { ++ case LPORT_ST_READY: ++ fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; ++ break; ++ default: ++ fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; ++ } ++ mutex_unlock(&lp->lp_mutex); + } + EXPORT_SYMBOL(fc_get_host_port_state); + +@@ -472,56 +482,6 @@ static void fc_lport_recv_rnid_req(struct fc_seq *sp, struct fc_frame *in_fp, } /** @@ -827849,7 +892839,7 @@ index 745fa55..bd2f771 100644 * fc_lport_recv_logo_req() - Handle received fabric LOGO request * @lport: Fibre Channel local port recieving the LOGO * @sp: current sequence in the LOGO exchange -@@ -550,7 +480,7 @@ int fc_fabric_login(struct fc_lport *lport) +@@ -550,7 +510,7 @@ int fc_fabric_login(struct fc_lport *lport) int rc = -1; mutex_lock(&lport->lp_mutex); @@ -827858,7 +892848,82 @@ index 745fa55..bd2f771 100644 fc_lport_enter_reset(lport); rc = 0; } -@@ -637,12 +567,13 @@ EXPORT_SYMBOL(fc_fabric_logoff); +@@ -561,40 +521,62 @@ int fc_fabric_login(struct fc_lport *lport) + EXPORT_SYMBOL(fc_fabric_login); + + /** +- * fc_linkup() - Handler for transport linkup events ++ * __fc_linkup() - Handler for transport linkup events + * @lport: The lport whose link is up ++ * ++ * Locking: must be called with the lp_mutex held + */ +-void fc_linkup(struct fc_lport *lport) ++void __fc_linkup(struct fc_lport *lport) + { +- printk(KERN_INFO "libfc: Link up on port (%6x)\n", +- fc_host_port_id(lport->host)); +- +- mutex_lock(&lport->lp_mutex); + if (!lport->link_up) { + lport->link_up = 1; + + if (lport->state == LPORT_ST_RESET) + fc_lport_enter_flogi(lport); + } ++} ++ ++/** ++ * fc_linkup() - Handler for transport linkup events ++ * @lport: The lport whose link is up ++ */ ++void fc_linkup(struct fc_lport *lport) ++{ ++ printk(KERN_INFO "libfc: Link up on port (%6x)\n", ++ fc_host_port_id(lport->host)); ++ ++ mutex_lock(&lport->lp_mutex); ++ __fc_linkup(lport); + mutex_unlock(&lport->lp_mutex); + } + EXPORT_SYMBOL(fc_linkup); + + /** +- * fc_linkdown() - Handler for transport linkdown events ++ * __fc_linkdown() - Handler for transport linkdown events + * @lport: The lport whose link is down ++ * ++ * Locking: must be called with the lp_mutex held + */ +-void fc_linkdown(struct fc_lport *lport) ++void __fc_linkdown(struct fc_lport *lport) + { +- mutex_lock(&lport->lp_mutex); +- printk(KERN_INFO "libfc: Link down on port (%6x)\n", +- fc_host_port_id(lport->host)); +- + if (lport->link_up) { + lport->link_up = 0; + fc_lport_enter_reset(lport); + lport->tt.fcp_cleanup(lport); + } ++} ++ ++/** ++ * fc_linkdown() - Handler for transport linkdown events ++ * @lport: The lport whose link is down ++ */ ++void fc_linkdown(struct fc_lport *lport) ++{ ++ printk(KERN_INFO "libfc: Link down on port (%6x)\n", ++ fc_host_port_id(lport->host)); ++ ++ mutex_lock(&lport->lp_mutex); ++ __fc_linkdown(lport); + mutex_unlock(&lport->lp_mutex); + } + EXPORT_SYMBOL(fc_linkdown); +@@ -637,12 +619,13 @@ EXPORT_SYMBOL(fc_fabric_logoff); int fc_lport_destroy(struct fc_lport *lport) { mutex_lock(&lport->lp_mutex); @@ -827873,9 +892938,13 @@ index 745fa55..bd2f771 100644 lport->tt.exch_mgr_reset(lport, 0, 0); return 0; } -@@ -722,7 +653,8 @@ static void fc_lport_enter_ready(struct fc_lport *lport) +@@ -721,8 +704,12 @@ static void fc_lport_enter_ready(struct fc_lport *lport) + fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_READY); ++ if (lport->vport) ++ fc_vport_set_state(lport->vport, FC_VPORT_ACTIVE); ++ fc_vports_linkchange(lport); - lport->tt.disc_start(fc_lport_disc_callback, lport); + if (!lport->ptp_rp) @@ -827883,7 +892952,7 @@ index 745fa55..bd2f771 100644 } /** -@@ -808,8 +740,6 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, +@@ -808,8 +795,6 @@ static void fc_lport_recv_flogi_req(struct fc_seq *sp_in, fc_lport_ptp_setup(lport, remote_fid, remote_wwpn, get_unaligned_be64(&flp->fl_wwnn)); @@ -827892,7 +892961,7 @@ index 745fa55..bd2f771 100644 out: sp = fr_seq(rx_fp); fc_frame_free(rx_fp); -@@ -832,10 +762,6 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, +@@ -832,10 +817,6 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, { struct fc_frame_header *fh = fc_frame_header_get(fp); void (*recv) (struct fc_seq *, struct fc_frame *, struct fc_lport *); @@ -827903,7 +892972,7 @@ index 745fa55..bd2f771 100644 mutex_lock(&lport->lp_mutex); -@@ -844,11 +770,14 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, +@@ -844,11 +825,14 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, * RSCN here. These don't require a session. * Even if we had a session, it might not be ready. */ @@ -827920,7 +892989,7 @@ index 745fa55..bd2f771 100644 switch (fc_frame_payload_op(fp)) { case ELS_FLOGI: recv = fc_lport_recv_flogi_req; -@@ -870,34 +799,9 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, +@@ -870,34 +854,9 @@ static void fc_lport_recv_req(struct fc_lport *lport, struct fc_seq *sp, case ELS_RNID: recv = fc_lport_recv_rnid_req; break; @@ -827956,7 +893025,7 @@ index 745fa55..bd2f771 100644 } else { FC_LPORT_DBG(lport, "dropping invalid frame (eof %x)\n", fr_eof(fp)); -@@ -930,38 +834,61 @@ int fc_lport_reset(struct fc_lport *lport) +@@ -930,38 +889,69 @@ int fc_lport_reset(struct fc_lport *lport) EXPORT_SYMBOL(fc_lport_reset); /** @@ -828003,7 +893072,14 @@ index 745fa55..bd2f771 100644 + FC_LPORT_DBG(lport, "Entered RESET state from %s state\n", + fc_lport_state(lport)); + ++ if (lport->vport) { ++ if (lport->link_up) ++ fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING); ++ else ++ fc_vport_set_state(lport->vport, FC_VPORT_LINKDOWN); ++ } + fc_lport_state_enter(lport, LPORT_ST_RESET); ++ fc_vports_linkchange(lport); + fc_lport_reset_locked(lport); if (lport->link_up) fc_lport_enter_flogi(lport); @@ -828022,6 +893098,7 @@ index 745fa55..bd2f771 100644 + fc_lport_state(lport)); + + fc_lport_state_enter(lport, LPORT_ST_DISABLED); ++ fc_vports_linkchange(lport); + fc_lport_reset_locked(lport); +} + @@ -828029,7 +893106,7 @@ index 745fa55..bd2f771 100644 * fc_lport_error() - Handler for any errors * @lport: The fc_lport object * @fp: The frame pointer -@@ -992,7 +919,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) +@@ -992,10 +982,12 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) schedule_delayed_work(&lport->retry_work, delay); } else { switch (lport->state) { @@ -828037,29 +893114,94 @@ index 745fa55..bd2f771 100644 + case LPORT_ST_DISABLED: case LPORT_ST_READY: case LPORT_ST_RESET: - case LPORT_ST_RPN_ID: -@@ -1026,13 +953,13 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, +- case LPORT_ST_RPN_ID: ++ case LPORT_ST_RNN_ID: ++ case LPORT_ST_RSNN_NN: ++ case LPORT_ST_RSPN_ID: + case LPORT_ST_RFT_ID: + case LPORT_ST_SCR: + case LPORT_ST_DNS: +@@ -1009,9 +1001,9 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) + } + + /** +- * fc_lport_rft_id_resp() - Handle response to Register Fibre +- * Channel Types by ID (RPN_ID) request +- * @sp: current sequence in RPN_ID exchange ++ * fc_lport_ns_resp() - Handle response to a name server ++ * registration exchange ++ * @sp: current sequence in exchange + * @fp: response frame + * @lp_arg: Fibre Channel host port instance + * +@@ -1019,77 +1011,23 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp) + * held, but it will lock, call an _enter_* function or fc_lport_error + * and then unlock the lport. + */ +-static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp, +- void *lp_arg) ++static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp, ++ void *lp_arg) + { + struct fc_lport *lport = lp_arg; struct fc_frame_header *fh; struct fc_ct_hdr *ct; -+ FC_LPORT_DBG(lport, "Received a RFT_ID %s\n", fc_els_resp_type(fp)); -+ - if (fp == ERR_PTR(-FC_EX_CLOSED)) - return; - - mutex_lock(&lport->lp_mutex); - +- if (fp == ERR_PTR(-FC_EX_CLOSED)) +- return; +- +- mutex_lock(&lport->lp_mutex); +- - FC_LPORT_DBG(lport, "Received a RFT_ID response\n"); - - if (lport->state != LPORT_ST_RFT_ID) { - FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state " - "%s\n", fc_lport_state(lport)); -@@ -1080,13 +1007,13 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, - struct fc_frame_header *fh; - struct fc_ct_hdr *ct; +- if (lport->state != LPORT_ST_RFT_ID) { +- FC_LPORT_DBG(lport, "Received a RFT_ID response, but in state " +- "%s\n", fc_lport_state(lport)); +- if (IS_ERR(fp)) +- goto err; +- goto out; +- } +- +- if (IS_ERR(fp)) { +- fc_lport_error(lport, fp); +- goto err; +- } +- +- fh = fc_frame_header_get(fp); +- ct = fc_frame_payload_get(fp, sizeof(*ct)); +- +- if (fh && ct && fh->fh_type == FC_TYPE_CT && +- ct->ct_fs_type == FC_FST_DIR && +- ct->ct_fs_subtype == FC_NS_SUBTYPE && +- ntohs(ct->ct_cmd) == FC_FS_ACC) +- fc_lport_enter_scr(lport); +- else +- fc_lport_error(lport, fp); +-out: +- fc_frame_free(fp); +-err: +- mutex_unlock(&lport->lp_mutex); +-} +- +-/** +- * fc_lport_rpn_id_resp() - Handle response to Register Port +- * Name by ID (RPN_ID) request +- * @sp: current sequence in RPN_ID exchange +- * @fp: response frame +- * @lp_arg: Fibre Channel host port instance +- * +- * Locking Note: This function will be called without the lport lock +- * held, but it will lock, call an _enter_* function or fc_lport_error +- * and then unlock the lport. +- */ +-static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, +- void *lp_arg) +-{ +- struct fc_lport *lport = lp_arg; +- struct fc_frame_header *fh; +- struct fc_ct_hdr *ct; ++ FC_LPORT_DBG(lport, "Received a ns %s\n", fc_els_resp_type(fp)); -+ FC_LPORT_DBG(lport, "Received a RPN_ID %s\n", fc_els_resp_type(fp)); -+ if (fp == ERR_PTR(-FC_EX_CLOSED)) return; @@ -828067,10 +893209,49 @@ index 745fa55..bd2f771 100644 - FC_LPORT_DBG(lport, "Received a RPN_ID response\n"); - - if (lport->state != LPORT_ST_RPN_ID) { - FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state " - "%s\n", fc_lport_state(lport)); -@@ -1132,13 +1059,13 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, +- if (lport->state != LPORT_ST_RPN_ID) { +- FC_LPORT_DBG(lport, "Received a RPN_ID response, but in state " +- "%s\n", fc_lport_state(lport)); ++ if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFT_ID) { ++ FC_LPORT_DBG(lport, "Received a name server response, " ++ "but in state %s\n", fc_lport_state(lport)); + if (IS_ERR(fp)) + goto err; + goto out; +@@ -1102,14 +1040,30 @@ static void fc_lport_rpn_id_resp(struct fc_seq *sp, struct fc_frame *fp, + + fh = fc_frame_header_get(fp); + ct = fc_frame_payload_get(fp, sizeof(*ct)); ++ + if (fh && ct && fh->fh_type == FC_TYPE_CT && + ct->ct_fs_type == FC_FST_DIR && + ct->ct_fs_subtype == FC_NS_SUBTYPE && + ntohs(ct->ct_cmd) == FC_FS_ACC) +- fc_lport_enter_rft_id(lport); ++ switch (lport->state) { ++ case LPORT_ST_RNN_ID: ++ fc_lport_enter_ns(lport, LPORT_ST_RSNN_NN); ++ break; ++ case LPORT_ST_RSNN_NN: ++ fc_lport_enter_ns(lport, LPORT_ST_RSPN_ID); ++ break; ++ case LPORT_ST_RSPN_ID: ++ fc_lport_enter_ns(lport, LPORT_ST_RFT_ID); ++ break; ++ case LPORT_ST_RFT_ID: ++ fc_lport_enter_scr(lport); ++ break; ++ default: ++ /* should have already been caught by state checks */ ++ break; ++ } + else + fc_lport_error(lport, fp); +- + out: + fc_frame_free(fp); + err: +@@ -1132,13 +1086,13 @@ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, struct fc_lport *lport = lp_arg; u8 op; @@ -828086,7 +893267,7 @@ index 745fa55..bd2f771 100644 if (lport->state != LPORT_ST_SCR) { FC_LPORT_DBG(lport, "Received a SCR response, but in state " "%s\n", fc_lport_state(lport)); -@@ -1186,7 +1113,7 @@ static void fc_lport_enter_scr(struct fc_lport *lport) +@@ -1186,78 +1140,69 @@ static void fc_lport_enter_scr(struct fc_lport *lport) return; } @@ -828095,25 +893276,116 @@ index 745fa55..bd2f771 100644 fc_lport_scr_resp, lport, lport->e_d_tov)) fc_lport_error(lport, fp); } -@@ -1227,7 +1154,7 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport) + + /** +- * fc_lport_enter_rft_id() - Register FC4-types with the name server ++ * fc_lport_enter_ns() - register some object with the name server + * @lport: Fibre Channel local port to register + * + * Locking Note: The lport lock is expected to be held before calling + * this routine. + */ +-static void fc_lport_enter_rft_id(struct fc_lport *lport) ++static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state) + { + struct fc_frame *fp; +- struct fc_ns_fts *lps; +- int i; ++ enum fc_ns_req cmd; ++ int size = sizeof(struct fc_ct_hdr); ++ size_t len; + +- FC_LPORT_DBG(lport, "Entered RFT_ID state from %s state\n", ++ FC_LPORT_DBG(lport, "Entered %s state from %s state\n", ++ fc_lport_state_names[state], + fc_lport_state(lport)); + +- fc_lport_state_enter(lport, LPORT_ST_RFT_ID); ++ fc_lport_state_enter(lport, state); + +- lps = &lport->fcts; +- i = sizeof(lps->ff_type_map) / sizeof(lps->ff_type_map[0]); +- while (--i >= 0) +- if (ntohl(lps->ff_type_map[i]) != 0) +- break; +- if (i < 0) { +- /* nothing to register, move on to SCR */ +- fc_lport_enter_scr(lport); ++ switch (state) { ++ case LPORT_ST_RNN_ID: ++ cmd = FC_NS_RNN_ID; ++ size += sizeof(struct fc_ns_rn_id); ++ break; ++ case LPORT_ST_RSNN_NN: ++ len = strnlen(fc_host_symbolic_name(lport->host), 255); ++ /* if there is no symbolic name, skip to RFT_ID */ ++ if (!len) ++ return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID); ++ cmd = FC_NS_RSNN_NN; ++ size += sizeof(struct fc_ns_rsnn) + len; ++ break; ++ case LPORT_ST_RSPN_ID: ++ len = strnlen(fc_host_symbolic_name(lport->host), 255); ++ /* if there is no symbolic name, skip to RFT_ID */ ++ if (!len) ++ return fc_lport_enter_ns(lport, LPORT_ST_RFT_ID); ++ cmd = FC_NS_RSPN_ID; ++ size += sizeof(struct fc_ns_rspn) + len; ++ break; ++ case LPORT_ST_RFT_ID: ++ cmd = FC_NS_RFT_ID; ++ size += sizeof(struct fc_ns_rft); ++ break; ++ default: ++ fc_lport_error(lport, NULL); + return; + } + +- fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + +- sizeof(struct fc_ns_rft)); ++ fp = fc_frame_alloc(lport, size); + if (!fp) { + fc_lport_error(lport, fp); return; } - if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RFT_ID, -+ if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RFT_ID, - fc_lport_rft_id_resp, - lport, lport->e_d_tov)) - fc_lport_error(lport, fp); -@@ -1256,7 +1183,7 @@ static void fc_lport_enter_rpn_id(struct fc_lport *lport) - return; - } - +- fc_lport_rft_id_resp, +- lport, lport->e_d_tov)) +- fc_lport_error(lport, fp); +-} +- +-/** +- * fc_rport_enter_rft_id() - Register port name with the name server +- * @lport: Fibre Channel local port to register +- * +- * Locking Note: The lport lock is expected to be held before calling +- * this routine. +- */ +-static void fc_lport_enter_rpn_id(struct fc_lport *lport) +-{ +- struct fc_frame *fp; +- +- FC_LPORT_DBG(lport, "Entered RPN_ID state from %s state\n", +- fc_lport_state(lport)); +- +- fc_lport_state_enter(lport, LPORT_ST_RPN_ID); +- +- fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + +- sizeof(struct fc_ns_rn_id)); +- if (!fp) { +- fc_lport_error(lport, fp); +- return; +- } +- - if (!lport->tt.elsct_send(lport, NULL, fp, FC_NS_RPN_ID, -+ if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RPN_ID, - fc_lport_rpn_id_resp, +- fc_lport_rpn_id_resp, ++ if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, cmd, ++ fc_lport_ns_resp, lport, lport->e_d_tov)) fc_lport_error(lport, fp); -@@ -1275,28 +1202,21 @@ static struct fc_rport_operations fc_lport_rport_ops = { + } +@@ -1275,28 +1220,21 @@ static struct fc_rport_operations fc_lport_rport_ops = { */ static void fc_lport_enter_dns(struct fc_lport *lport) { @@ -828148,7 +893420,7 @@ index 745fa55..bd2f771 100644 return; err: -@@ -1316,7 +1236,7 @@ static void fc_lport_timeout(struct work_struct *work) +@@ -1316,7 +1254,7 @@ static void fc_lport_timeout(struct work_struct *work) mutex_lock(&lport->lp_mutex); switch (lport->state) { @@ -828157,7 +893429,30 @@ index 745fa55..bd2f771 100644 case LPORT_ST_READY: case LPORT_ST_RESET: WARN_ON(1); -@@ -1360,13 +1280,13 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -1327,11 +1265,11 @@ static void fc_lport_timeout(struct work_struct *work) + case LPORT_ST_DNS: + fc_lport_enter_dns(lport); + break; +- case LPORT_ST_RPN_ID: +- fc_lport_enter_rpn_id(lport); +- break; ++ case LPORT_ST_RNN_ID: ++ case LPORT_ST_RSNN_NN: ++ case LPORT_ST_RSPN_ID: + case LPORT_ST_RFT_ID: +- fc_lport_enter_rft_id(lport); ++ fc_lport_enter_ns(lport, lport->state); + break; + case LPORT_ST_SCR: + fc_lport_enter_scr(lport); +@@ -1354,19 +1292,19 @@ static void fc_lport_timeout(struct work_struct *work) + * held, but it will lock, call an _enter_* function or fc_lport_error + * and then unlock the lport. + */ +-static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, ++void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, + void *lp_arg) + { struct fc_lport *lport = lp_arg; u8 op; @@ -828173,7 +893468,7 @@ index 745fa55..bd2f771 100644 if (lport->state != LPORT_ST_LOGO) { FC_LPORT_DBG(lport, "Received a LOGO response, but in state " "%s\n", fc_lport_state(lport)); -@@ -1382,7 +1302,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -1382,7 +1320,7 @@ static void fc_lport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) @@ -828182,7 +893477,23 @@ index 745fa55..bd2f771 100644 else fc_lport_error(lport, fp); -@@ -1415,8 +1335,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport) +@@ -1391,6 +1329,7 @@ out: + err: + mutex_unlock(&lport->lp_mutex); + } ++EXPORT_SYMBOL(fc_lport_logo_resp); + + /** + * fc_rport_enter_logo() - Logout of the fabric +@@ -1408,6 +1347,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport) + fc_lport_state(lport)); + + fc_lport_state_enter(lport, LPORT_ST_LOGO); ++ fc_vports_linkchange(lport); + + fp = fc_frame_alloc(lport, sizeof(*logo)); + if (!fp) { +@@ -1415,8 +1355,8 @@ static void fc_lport_enter_logo(struct fc_lport *lport) return; } @@ -828193,7 +893504,16 @@ index 745fa55..bd2f771 100644 fc_lport_error(lport, fp); } -@@ -1442,13 +1362,13 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -1430,7 +1370,7 @@ static void fc_lport_enter_logo(struct fc_lport *lport) + * held, but it will lock, call an _enter_* function or fc_lport_error + * and then unlock the lport. + */ +-static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, ++void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, + void *lp_arg) + { + struct fc_lport *lport = lp_arg; +@@ -1442,13 +1382,13 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, unsigned int e_d_tov; u16 mfs; @@ -828209,7 +893529,17 @@ index 745fa55..bd2f771 100644 if (lport->state != LPORT_ST_FLOGI) { FC_LPORT_DBG(lport, "Received a FLOGI response, but in state " "%s\n", fc_lport_state(lport)); -@@ -1501,14 +1421,6 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -1482,6 +1422,9 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, + e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); + if (csp_flags & FC_SP_FT_EDTR) + e_d_tov /= 1000000; ++ ++ lport->npiv_enabled = !!(csp_flags & FC_SP_FT_NPIV_ACC); ++ + if ((csp_flags & FC_SP_FT_FPORT) == 0) { + if (e_d_tov > lport->e_d_tov) + lport->e_d_tov = e_d_tov; +@@ -1501,14 +1444,6 @@ static void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, fc_lport_enter_dns(lport); } } @@ -828224,16 +893554,25 @@ index 745fa55..bd2f771 100644 } else { FC_LPORT_DBG(lport, "Bad FLOGI response\n"); } -@@ -1539,7 +1451,7 @@ void fc_lport_enter_flogi(struct fc_lport *lport) +@@ -1518,6 +1453,7 @@ out: + err: + mutex_unlock(&lport->lp_mutex); + } ++EXPORT_SYMBOL(fc_lport_flogi_resp); + + /** + * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager +@@ -1539,7 +1475,8 @@ void fc_lport_enter_flogi(struct fc_lport *lport) if (!fp) return fc_lport_error(lport, fp); - if (!lport->tt.elsct_send(lport, NULL, fp, ELS_FLOGI, -+ if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ELS_FLOGI, ++ if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, ++ lport->vport ? ELS_FDISC : ELS_FLOGI, fc_lport_flogi_resp, lport, lport->e_d_tov)) fc_lport_error(lport, fp); } -@@ -1550,7 +1462,7 @@ int fc_lport_config(struct fc_lport *lport) +@@ -1550,7 +1487,7 @@ int fc_lport_config(struct fc_lport *lport) INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout); mutex_init(&lport->lp_mutex); @@ -828242,20 +893581,435 @@ index 745fa55..bd2f771 100644 fc_lport_add_fc4_type(lport, FC_TYPE_FCP); fc_lport_add_fc4_type(lport, FC_TYPE_CT); -@@ -1588,6 +1500,7 @@ int fc_lport_init(struct fc_lport *lport) - if (lport->link_supported_speeds & FC_PORTSPEED_10GBIT) - fc_host_supported_speeds(lport->host) |= FC_PORTSPEED_10GBIT; - -+ INIT_LIST_HEAD(&lport->ema_list); +@@ -1591,3 +1528,251 @@ int fc_lport_init(struct fc_lport *lport) return 0; } EXPORT_SYMBOL(fc_lport_init); ++ ++/** ++ * fc_lport_bsg_resp() - The common response handler for fc pass-thru requests ++ * @sp: current sequence in the fc pass-thru request exchange ++ * @fp: received response frame ++ * @info_arg: pointer to struct fc_bsg_info ++ */ ++static void fc_lport_bsg_resp(struct fc_seq *sp, struct fc_frame *fp, ++ void *info_arg) ++{ ++ struct fc_bsg_info *info = info_arg; ++ struct fc_bsg_job *job = info->job; ++ struct fc_lport *lport = info->lport; ++ struct fc_frame_header *fh; ++ size_t len; ++ void *buf; ++ ++ if (IS_ERR(fp)) { ++ job->reply->result = (PTR_ERR(fp) == -FC_EX_CLOSED) ? ++ -ECONNABORTED : -ETIMEDOUT; ++ job->reply_len = sizeof(uint32_t); ++ job->state_flags |= FC_RQST_STATE_DONE; ++ job->job_done(job); ++ kfree(info); ++ return; ++ } ++ ++ mutex_lock(&lport->lp_mutex); ++ fh = fc_frame_header_get(fp); ++ len = fr_len(fp) - sizeof(*fh); ++ buf = fc_frame_payload_get(fp, 0); ++ ++ if (fr_sof(fp) == FC_SOF_I3 && !ntohs(fh->fh_seq_cnt)) { ++ /* Get the response code from the first frame payload */ ++ unsigned short cmd = (info->rsp_code == FC_FS_ACC) ? ++ ntohs(((struct fc_ct_hdr *)buf)->ct_cmd) : ++ (unsigned short)fc_frame_payload_op(fp); ++ ++ /* Save the reply status of the job */ ++ job->reply->reply_data.ctels_reply.status = ++ (cmd == info->rsp_code) ? ++ FC_CTELS_STATUS_OK : FC_CTELS_STATUS_REJECT; ++ } ++ ++ job->reply->reply_payload_rcv_len += ++ fc_copy_buffer_to_sglist(buf, len, info->sg, &info->nents, ++ &info->offset, KM_BIO_SRC_IRQ, NULL); ++ ++ if (fr_eof(fp) == FC_EOF_T && ++ (ntoh24(fh->fh_f_ctl) & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) == ++ (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) { ++ if (job->reply->reply_payload_rcv_len > ++ job->reply_payload.payload_len) ++ job->reply->reply_payload_rcv_len = ++ job->reply_payload.payload_len; ++ job->reply->result = 0; ++ job->state_flags |= FC_RQST_STATE_DONE; ++ job->job_done(job); ++ kfree(info); ++ } ++ fc_frame_free(fp); ++ mutex_unlock(&lport->lp_mutex); ++} ++ ++/** ++ * fc_lport_els_request() - Send ELS pass-thru request ++ * @job: The bsg fc pass-thru job structure ++ * @lport: The local port sending the request ++ * @did: The destination port id. ++ * ++ * Locking Note: The lport lock is expected to be held before calling ++ * this routine. ++ */ ++static int fc_lport_els_request(struct fc_bsg_job *job, ++ struct fc_lport *lport, ++ u32 did, u32 tov) ++{ ++ struct fc_bsg_info *info; ++ struct fc_frame *fp; ++ struct fc_frame_header *fh; ++ char *pp; ++ int len; ++ ++ fp = fc_frame_alloc(lport, sizeof(struct fc_frame_header) + ++ job->request_payload.payload_len); ++ if (!fp) ++ return -ENOMEM; ++ ++ len = job->request_payload.payload_len; ++ pp = fc_frame_payload_get(fp, len); ++ ++ sg_copy_to_buffer(job->request_payload.sg_list, ++ job->request_payload.sg_cnt, ++ pp, len); ++ ++ fh = fc_frame_header_get(fp); ++ fh->fh_r_ctl = FC_RCTL_ELS_REQ; ++ hton24(fh->fh_d_id, did); ++ hton24(fh->fh_s_id, fc_host_port_id(lport->host)); ++ fh->fh_type = FC_TYPE_ELS; ++ hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | ++ FC_FC_END_SEQ | FC_FC_SEQ_INIT); ++ fh->fh_cs_ctl = 0; ++ fh->fh_df_ctl = 0; ++ fh->fh_parm_offset = 0; ++ ++ info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); ++ if (!info) { ++ fc_frame_free(fp); ++ return -ENOMEM; ++ } ++ ++ info->job = job; ++ info->lport = lport; ++ info->rsp_code = ELS_LS_ACC; ++ info->nents = job->reply_payload.sg_cnt; ++ info->sg = job->reply_payload.sg_list; ++ ++ if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp, ++ NULL, info, tov)) ++ return -ECOMM; ++ return 0; ++} ++ ++/** ++ * fc_lport_ct_request() - Send CT pass-thru request ++ * @job: The bsg fc pass-thru job structure ++ * @lport: The local port sending the request ++ * @did: The destination FC-ID ++ * @tov: The time to wait for a response ++ * ++ * Locking Note: The lport lock is expected to be held before calling ++ * this routine. ++ */ ++static int fc_lport_ct_request(struct fc_bsg_job *job, ++ struct fc_lport *lport, u32 did, u32 tov) ++{ ++ struct fc_bsg_info *info; ++ struct fc_frame *fp; ++ struct fc_frame_header *fh; ++ struct fc_ct_req *ct; ++ size_t len; ++ ++ fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) + ++ job->request_payload.payload_len); ++ if (!fp) ++ return -ENOMEM; ++ ++ len = job->request_payload.payload_len; ++ ct = fc_frame_payload_get(fp, len); ++ ++ sg_copy_to_buffer(job->request_payload.sg_list, ++ job->request_payload.sg_cnt, ++ ct, len); ++ ++ fh = fc_frame_header_get(fp); ++ fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL; ++ hton24(fh->fh_d_id, did); ++ hton24(fh->fh_s_id, fc_host_port_id(lport->host)); ++ fh->fh_type = FC_TYPE_CT; ++ hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ | ++ FC_FC_END_SEQ | FC_FC_SEQ_INIT); ++ fh->fh_cs_ctl = 0; ++ fh->fh_df_ctl = 0; ++ fh->fh_parm_offset = 0; ++ ++ info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); ++ if (!info) { ++ fc_frame_free(fp); ++ return -ENOMEM; ++ } ++ ++ info->job = job; ++ info->lport = lport; ++ info->rsp_code = FC_FS_ACC; ++ info->nents = job->reply_payload.sg_cnt; ++ info->sg = job->reply_payload.sg_list; ++ ++ if (!lport->tt.exch_seq_send(lport, fp, fc_lport_bsg_resp, ++ NULL, info, tov)) ++ return -ECOMM; ++ return 0; ++} ++ ++/** ++ * fc_lport_bsg_request() - The common entry point for sending ++ * fc pass-thru requests ++ * @job: The fc pass-thru job structure ++ */ ++int fc_lport_bsg_request(struct fc_bsg_job *job) ++{ ++ struct request *rsp = job->req->next_rq; ++ struct Scsi_Host *shost = job->shost; ++ struct fc_lport *lport = shost_priv(shost); ++ struct fc_rport *rport; ++ struct fc_rport_priv *rdata; ++ int rc = -EINVAL; ++ u32 did; ++ ++ job->reply->reply_payload_rcv_len = 0; ++ rsp->resid_len = job->reply_payload.payload_len; ++ ++ mutex_lock(&lport->lp_mutex); ++ ++ switch (job->request->msgcode) { ++ case FC_BSG_RPT_ELS: ++ rport = job->rport; ++ if (!rport) ++ break; ++ ++ rdata = rport->dd_data; ++ rc = fc_lport_els_request(job, lport, rport->port_id, ++ rdata->e_d_tov); ++ break; ++ ++ case FC_BSG_RPT_CT: ++ rport = job->rport; ++ if (!rport) ++ break; ++ ++ rdata = rport->dd_data; ++ rc = fc_lport_ct_request(job, lport, rport->port_id, ++ rdata->e_d_tov); ++ break; ++ ++ case FC_BSG_HST_CT: ++ did = ntoh24(job->request->rqst_data.h_ct.port_id); ++ if (did == FC_FID_DIR_SERV) ++ rdata = lport->dns_rp; ++ else ++ rdata = lport->tt.rport_lookup(lport, did); ++ ++ if (!rdata) ++ break; ++ ++ rc = fc_lport_ct_request(job, lport, did, rdata->e_d_tov); ++ break; ++ ++ case FC_BSG_HST_ELS_NOLOGIN: ++ did = ntoh24(job->request->rqst_data.h_els.port_id); ++ rc = fc_lport_els_request(job, lport, did, lport->e_d_tov); ++ break; ++ } ++ ++ mutex_unlock(&lport->lp_mutex); ++ return rc; ++} ++EXPORT_SYMBOL(fc_lport_bsg_request); +diff --git a/drivers/scsi/libfc/fc_npiv.c b/drivers/scsi/libfc/fc_npiv.c +new file mode 100644 +index 0000000..c68f6c7 +--- /dev/null ++++ b/drivers/scsi/libfc/fc_npiv.c +@@ -0,0 +1,161 @@ ++/* ++ * Copyright(c) 2009 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., ++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Maintained at www.Open-FCoE.org ++ */ ++ ++/* ++ * NPIV VN_Port helper functions for libfc ++ */ ++ ++#include ++ ++/** ++ * fc_vport_create() - Create a new NPIV vport instance ++ * @vport: fc_vport structure from scsi_transport_fc ++ * @privsize: driver private data size to allocate along with the Scsi_Host ++ */ ++ ++struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize) ++{ ++ struct Scsi_Host *shost = vport_to_shost(vport); ++ struct fc_lport *n_port = shost_priv(shost); ++ struct fc_lport *vn_port; ++ ++ vn_port = libfc_host_alloc(shost->hostt, privsize); ++ if (!vn_port) ++ goto err_out; ++ if (fc_exch_mgr_list_clone(n_port, vn_port)) ++ goto err_put; ++ ++ vn_port->vport = vport; ++ vport->dd_data = vn_port; ++ ++ mutex_lock(&n_port->lp_mutex); ++ list_add_tail(&vn_port->list, &n_port->vports); ++ mutex_unlock(&n_port->lp_mutex); ++ ++ return vn_port; ++ ++err_put: ++ scsi_host_put(vn_port->host); ++err_out: ++ return NULL; ++} ++EXPORT_SYMBOL(libfc_vport_create); ++ ++/** ++ * fc_vport_id_lookup() - find NPIV lport that matches a given fabric ID ++ * @n_port: Top level N_Port which may have multiple NPIV VN_Ports ++ * @port_id: Fabric ID to find a match for ++ * ++ * Returns: matching lport pointer or NULL if there is no match ++ */ ++struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id) ++{ ++ struct fc_lport *lport = NULL; ++ struct fc_lport *vn_port; ++ ++ if (fc_host_port_id(n_port->host) == port_id) ++ return n_port; ++ ++ mutex_lock(&n_port->lp_mutex); ++ list_for_each_entry(vn_port, &n_port->vports, list) { ++ if (fc_host_port_id(vn_port->host) == port_id) { ++ lport = vn_port; ++ break; ++ } ++ } ++ mutex_unlock(&n_port->lp_mutex); ++ ++ return lport; ++} ++ ++/* ++ * When setting the link state of vports during an lport state change, it's ++ * necessary to hold the lp_mutex of both the N_Port and the VN_Port. ++ * This tells the lockdep engine to treat the nested locking of the VN_Port ++ * as a different lock class. ++ */ ++enum libfc_lport_mutex_class { ++ LPORT_MUTEX_NORMAL = 0, ++ LPORT_MUTEX_VN_PORT = 1, ++}; ++ ++/** ++ * __fc_vport_setlink() - update link and status on a VN_Port ++ * @n_port: parent N_Port ++ * @vn_port: VN_Port to update ++ * ++ * Locking: must be called with both the N_Port and VN_Port lp_mutex held ++ */ ++static void __fc_vport_setlink(struct fc_lport *n_port, ++ struct fc_lport *vn_port) ++{ ++ struct fc_vport *vport = vn_port->vport; ++ ++ if (vn_port->state == LPORT_ST_DISABLED) ++ return; ++ ++ if (n_port->state == LPORT_ST_READY) { ++ if (n_port->npiv_enabled) { ++ fc_vport_set_state(vport, FC_VPORT_INITIALIZING); ++ __fc_linkup(vn_port); ++ } else { ++ fc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP); ++ __fc_linkdown(vn_port); ++ } ++ } else { ++ fc_vport_set_state(vport, FC_VPORT_LINKDOWN); ++ __fc_linkdown(vn_port); ++ } ++} ++ ++/** ++ * fc_vport_setlink() - update link and status on a VN_Port ++ * @vn_port: virtual port to update ++ */ ++void fc_vport_setlink(struct fc_lport *vn_port) ++{ ++ struct fc_vport *vport = vn_port->vport; ++ struct Scsi_Host *shost = vport_to_shost(vport); ++ struct fc_lport *n_port = shost_priv(shost); ++ ++ mutex_lock(&n_port->lp_mutex); ++ mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT); ++ __fc_vport_setlink(n_port, vn_port); ++ mutex_unlock(&vn_port->lp_mutex); ++ mutex_unlock(&n_port->lp_mutex); ++} ++EXPORT_SYMBOL(fc_vport_setlink); ++ ++/** ++ * fc_vports_linkchange() - change the link state of all vports ++ * @n_port: Parent N_Port that has changed state ++ * ++ * Locking: called with the n_port lp_mutex held ++ */ ++void fc_vports_linkchange(struct fc_lport *n_port) ++{ ++ struct fc_lport *vn_port; ++ ++ list_for_each_entry(vn_port, &n_port->vports, list) { ++ mutex_lock_nested(&vn_port->lp_mutex, LPORT_MUTEX_VN_PORT); ++ __fc_vport_setlink(n_port, vn_port); ++ mutex_unlock(&vn_port->lp_mutex); ++ } ++} ++ diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c -index 7162385..03ea674 100644 +index 7162385..239fe54 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c -@@ -57,94 +57,114 @@ +@@ -55,96 +55,118 @@ + #include + #include ++#include "fc_libfc.h" ++ struct workqueue_struct *rport_event_queue; -static void fc_rport_enter_plogi(struct fc_rport *); @@ -828263,15 +894017,14 @@ index 7162385..03ea674 100644 -static void fc_rport_enter_rtv(struct fc_rport *); -static void fc_rport_enter_ready(struct fc_rport *); -static void fc_rport_enter_logo(struct fc_rport *); -- --static void fc_rport_recv_plogi_req(struct fc_rport *, +static void fc_rport_enter_plogi(struct fc_rport_priv *); +static void fc_rport_enter_prli(struct fc_rport_priv *); +static void fc_rport_enter_rtv(struct fc_rport_priv *); +static void fc_rport_enter_ready(struct fc_rport_priv *); +static void fc_rport_enter_logo(struct fc_rport_priv *); +static void fc_rport_enter_adisc(struct fc_rport_priv *); -+ + +-static void fc_rport_recv_plogi_req(struct fc_rport *, +static void fc_rport_recv_plogi_req(struct fc_lport *, struct fc_seq *, struct fc_frame *); -static void fc_rport_recv_prli_req(struct fc_rport *, @@ -828419,7 +894172,7 @@ index 7162385..03ea674 100644 cp = fc_rport_state_names[rdata->rp_state]; if (!cp) -@@ -191,15 +211,14 @@ static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, +@@ -191,15 +213,14 @@ static unsigned int fc_plogi_get_maxframe(struct fc_els_flogi *flp, /** * fc_rport_state_enter() - Change the rport's state @@ -828437,7 +894190,7 @@ index 7162385..03ea674 100644 if (rdata->rp_state != new) rdata->retries = 0; rdata->rp_state = new; -@@ -208,147 +227,187 @@ static void fc_rport_state_enter(struct fc_rport *rport, +@@ -208,147 +229,187 @@ static void fc_rport_state_enter(struct fc_rport *rport, static void fc_rport_work(struct work_struct *work) { u32 port_id; @@ -828713,7 +894466,7 @@ index 7162385..03ea674 100644 mutex_unlock(&rdata->rp_mutex); out: -@@ -357,26 +416,25 @@ out: +@@ -357,26 +418,25 @@ out: /** * fc_rport_enter_ready() - The rport is ready @@ -828748,7 +894501,7 @@ index 7162385..03ea674 100644 * * Locking Note: Called without the rport lock held. This * function will hold the rport lock, call an _enter_* -@@ -384,63 +442,63 @@ static void fc_rport_enter_ready(struct fc_rport *rport) +@@ -384,63 +444,63 @@ static void fc_rport_enter_ready(struct fc_rport *rport) */ static void fc_rport_timeout(struct work_struct *work) { @@ -828834,7 +894587,7 @@ index 7162385..03ea674 100644 case RPORT_ST_READY: case RPORT_ST_INIT: break; -@@ -449,7 +507,7 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) +@@ -449,7 +509,7 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) /** * fc_rport_error_retry() - Error handler when retries are desired @@ -828843,7 +894596,7 @@ index 7162385..03ea674 100644 * @fp: The frame pointer * * If the error was an exchange timeout retry immediately, -@@ -458,45 +516,43 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) +@@ -458,45 +518,43 @@ static void fc_rport_error(struct fc_rport *rport, struct fc_frame *fp) * Locking Note: The rport lock is expected to be held before * calling this routine */ @@ -828898,7 +894651,7 @@ index 7162385..03ea674 100644 struct fc_lport *lport = rdata->local_port; struct fc_els_flogi *plp = NULL; unsigned int tov; -@@ -506,26 +562,26 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -506,26 +564,26 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); @@ -828931,7 +894684,7 @@ index 7162385..03ea674 100644 tov = ntohl(plp->fl_csp.sp_e_d_tov); if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) -@@ -537,75 +593,64 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -537,75 +595,64 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, if (cssp_seq < csp_seq) csp_seq = cssp_seq; rdata->max_seq = csp_seq; @@ -829025,7 +894778,7 @@ index 7162385..03ea674 100644 struct { struct fc_els_prli prli; struct fc_els_spp spp; -@@ -616,21 +661,24 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -616,21 +663,24 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, mutex_lock(&rdata->rp_mutex); @@ -829054,7 +894807,7 @@ index 7162385..03ea674 100644 op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) { pp = fc_frame_payload_get(fp, sizeof(*pp)); -@@ -640,90 +688,82 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -640,90 +690,82 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, rdata->flags |= FC_RP_FLAGS_RETRY; } @@ -829165,7 +894918,7 @@ index 7162385..03ea674 100644 struct fc_lport *lport = rdata->local_port; struct { struct fc_els_prli prli; -@@ -731,29 +771,38 @@ static void fc_rport_enter_prli(struct fc_rport *rport) +@@ -731,29 +773,38 @@ static void fc_rport_enter_prli(struct fc_rport *rport) } *pp; struct fc_frame *fp; @@ -829213,7 +894966,7 @@ index 7162385..03ea674 100644 * * Many targets don't seem to support this. * -@@ -762,26 +811,25 @@ static void fc_rport_enter_prli(struct fc_rport *rport) +@@ -762,26 +813,25 @@ static void fc_rport_enter_prli(struct fc_rport *rport) * and then unlock the rport. */ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, @@ -829246,7 +894999,7 @@ index 7162385..03ea674 100644 goto err; } -@@ -807,184 +855,376 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, +@@ -807,184 +857,376 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, } } @@ -829713,7 +895466,7 @@ index 7162385..03ea674 100644 * set the state appropriately and accept the PLOGI. * * If we had also sent a PLOGI, and if the received PLOGI is from a -@@ -996,86 +1236,76 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, +@@ -996,86 +1238,76 @@ static void fc_rport_recv_plogi_req(struct fc_rport *rport, */ switch (rdata->rp_state) { case RPORT_ST_INIT: @@ -829847,7 +895600,7 @@ index 7162385..03ea674 100644 struct fc_lport *lport = rdata->local_port; struct fc_exch *ep; struct fc_frame *fp; -@@ -1099,12 +1329,14 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, +@@ -1099,12 +1331,14 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, fh = fc_frame_header_get(rx_fp); @@ -829864,7 +895617,7 @@ index 7162385..03ea674 100644 reason = ELS_RJT_NONE; break; default: -@@ -1149,6 +1381,9 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, +@@ -1149,6 +1383,9 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, pp->prli.prli_len = htons(len); len -= sizeof(struct fc_els_prli); @@ -829874,9 +895627,12 @@ index 7162385..03ea674 100644 /* * Go through all the service parameter pages and build * response. If plen indicates longer SPP than standard, -@@ -1169,12 +1404,12 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, +@@ -1167,14 +1404,14 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, + break; + case FC_TYPE_FCP: fcp_parm = ntohl(rspp->spp_params); - if (fcp_parm * FCP_SPPF_RETRY) +- if (fcp_parm * FCP_SPPF_RETRY) ++ if (fcp_parm & FCP_SPPF_RETRY) rdata->flags |= FC_RP_FLAGS_RETRY; - rport->supported_classes = FC_COS_CLASS3; + rdata->supported_classes = FC_COS_CLASS3; @@ -829889,7 +895645,7 @@ index 7162385..03ea674 100644 spp->spp_params = htonl(lport->service_params); -@@ -1204,9 +1439,10 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, +@@ -1204,9 +1441,10 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, */ switch (rdata->rp_state) { case RPORT_ST_PRLI: @@ -829901,7 +895657,7 @@ index 7162385..03ea674 100644 break; default: break; -@@ -1217,17 +1453,17 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, +@@ -1217,17 +1455,17 @@ static void fc_rport_recv_prli_req(struct fc_rport *rport, /** * fc_rport_recv_prlo_req() - Handle incoming Process Logout (PRLO) request @@ -829922,7 +895678,7 @@ index 7162385..03ea674 100644 struct fc_lport *lport = rdata->local_port; struct fc_frame_header *fh; -@@ -1235,13 +1471,8 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, +@@ -1235,13 +1473,8 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, fh = fc_frame_header_get(fp); @@ -829938,7 +895694,7 @@ index 7162385..03ea674 100644 rjt_data.fp = NULL; rjt_data.reason = ELS_RJT_UNAB; -@@ -1252,35 +1483,46 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, +@@ -1252,35 +1485,46 @@ static void fc_rport_recv_prlo_req(struct fc_rport *rport, struct fc_seq *sp, /** * fc_rport_recv_logo_req() - Handle incoming Logout (LOGO) request @@ -830001,7 +895757,7 @@ index 7162385..03ea674 100644 fc_frame_free(fp); } -@@ -1291,8 +1533,11 @@ static void fc_rport_flush_queue(void) +@@ -1291,8 +1535,11 @@ static void fc_rport_flush_queue(void) int fc_rport_init(struct fc_lport *lport) { @@ -830014,7 +895770,7 @@ index 7162385..03ea674 100644 if (!lport->tt.rport_login) lport->tt.rport_login = fc_rport_login; -@@ -1306,6 +1551,9 @@ int fc_rport_init(struct fc_lport *lport) +@@ -1306,6 +1553,9 @@ int fc_rport_init(struct fc_lport *lport) if (!lport->tt.rport_flush_queue) lport->tt.rport_flush_queue = fc_rport_flush_queue; @@ -830024,7 +895780,17 @@ index 7162385..03ea674 100644 return 0; } EXPORT_SYMBOL(fc_rport_init); -@@ -1327,8 +1575,8 @@ EXPORT_SYMBOL(fc_destroy_rport); +@@ -1317,18 +1567,16 @@ int fc_setup_rport(void) + return -ENOMEM; + return 0; + } +-EXPORT_SYMBOL(fc_setup_rport); + + void fc_destroy_rport(void) + { + destroy_workqueue(rport_event_queue); + } +-EXPORT_SYMBOL(fc_destroy_rport); void fc_rport_terminate_io(struct fc_rport *rport) { @@ -832595,10 +898361,63 @@ index 27d1a88..d655ed3 100644 + uint32_t type; +}; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index da59c4f..61d0897 100644 +index da59c4f..c88f59f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -2142,7 +2142,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, +@@ -56,8 +56,6 @@ static char *dif_op_str[] = { + "SCSI_PROT_WRITE_INSERT", + "SCSI_PROT_READ_PASS", + "SCSI_PROT_WRITE_PASS", +- "SCSI_PROT_READ_CONVERT", +- "SCSI_PROT_WRITE_CONVERT" + }; + static void + lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); +@@ -1131,13 +1129,11 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc) + ret_prof = LPFC_PROF_A1; + break; + +- case SCSI_PROT_READ_CONVERT: +- case SCSI_PROT_WRITE_CONVERT: ++ case SCSI_PROT_READ_PASS: ++ case SCSI_PROT_WRITE_PASS: + ret_prof = LPFC_PROF_AST1; + break; + +- case SCSI_PROT_READ_PASS: +- case SCSI_PROT_WRITE_PASS: + case SCSI_PROT_NORMAL: + default: + printk(KERN_ERR "Bad op/guard:%d/%d combination\n", +@@ -1157,8 +1153,6 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc) + ret_prof = LPFC_PROF_C1; + break; + +- case SCSI_PROT_READ_CONVERT: +- case SCSI_PROT_WRITE_CONVERT: + case SCSI_PROT_READ_INSERT: + case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_NORMAL: +@@ -1209,8 +1203,7 @@ lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask, + static int cnt; + + if (protcnt && (op == SCSI_PROT_WRITE_STRIP || +- op == SCSI_PROT_WRITE_PASS || +- op == SCSI_PROT_WRITE_CONVERT)) { ++ op == SCSI_PROT_WRITE_PASS)) { + + cnt++; + spt = page_address(sg_page(scsi_prot_sglist(sc))) + +@@ -1501,8 +1494,6 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) + case SCSI_PROT_WRITE_STRIP: + case SCSI_PROT_READ_PASS: + case SCSI_PROT_WRITE_PASS: +- case SCSI_PROT_WRITE_CONVERT: +- case SCSI_PROT_READ_CONVERT: + ret = LPFC_PG_TYPE_DIF_BUF; + break; + default: +@@ -2142,7 +2133,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, } else if (resp_info & RESID_OVER) { lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, "9028 FCP command x%x residual overrun error. " @@ -832607,7 +898426,7 @@ index da59c4f..61d0897 100644 scsi_bufflen(cmnd), scsi_get_resid(cmnd)); host_status = DID_ERROR; -@@ -2843,7 +2843,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) +@@ -2843,7 +2834,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) dif_op_str[scsi_get_prot_op(cmnd)]); lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, "9034 BLKGRD: CDB: %02x %02x %02x %02x %02x " @@ -832616,7 +898435,7 @@ index da59c4f..61d0897 100644 cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], -@@ -2871,7 +2871,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) +@@ -2871,7 +2862,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) dif_op_str[scsi_get_prot_op(cmnd)]); lpfc_printf_vlog(vport, KERN_WARNING, LOG_BG, "9039 BLKGRD: CDB: %02x %02x %02x %02x %02x " @@ -832625,7 +898444,7 @@ index da59c4f..61d0897 100644 cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], -@@ -3584,6 +3584,7 @@ struct scsi_host_template lpfc_template = { +@@ -3584,6 +3575,7 @@ struct scsi_host_template lpfc_template = { .use_clustering = ENABLE_CLUSTERING, .shost_attrs = lpfc_hba_attrs, .max_sectors = 0xFFFF, @@ -844468,10 +910287,38 @@ index 40e3caf..83c8b5e 100644 * @l: lun id * diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c -index 2de5f3a..b6e0307 100644 +index 2de5f3a..dd098ca 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c -@@ -994,7 +994,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, +@@ -241,10 +241,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) + */ + struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) + { +- struct scsi_cmnd *cmd; +- unsigned char *buf; +- +- cmd = scsi_host_alloc_command(shost, gfp_mask); ++ struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask); + + if (unlikely(!cmd)) { + unsigned long flags; +@@ -258,9 +255,15 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) + spin_unlock_irqrestore(&shost->free_list_lock, flags); + + if (cmd) { ++ void *buf, *prot; ++ + buf = cmd->sense_buffer; ++ prot = cmd->prot_sdb; ++ + memset(cmd, 0, sizeof(*cmd)); ++ + cmd->sense_buffer = buf; ++ cmd->prot_sdb = prot; + } + } + +@@ -994,7 +997,7 @@ static int scsi_vpd_inquiry(struct scsi_device *sdev, unsigned char *buffer, * all the existing users tried this hard. */ result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, @@ -844480,7 +910327,7 @@ index 2de5f3a..b6e0307 100644 if (result) return result; -@@ -1021,13 +1021,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) +@@ -1021,13 +1024,14 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) { int i, result; unsigned int len; @@ -844497,7 +910344,7 @@ index 2de5f3a..b6e0307 100644 if (result) goto fail; -@@ -1050,12 +1051,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) +@@ -1050,12 +1054,12 @@ unsigned char *scsi_get_vpd_page(struct scsi_device *sdev, u8 page) * Some pages are longer than 255 bytes. The actual length of * the page is returned in the header. */ @@ -844513,8 +910360,321 @@ index 2de5f3a..b6e0307 100644 result = scsi_vpd_inquiry(sdev, buf, page, len); if (result) goto fail; +diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c +index fb9af20..c4103be 100644 +--- a/drivers/scsi/scsi_debug.c ++++ b/drivers/scsi/scsi_debug.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + #include "sd.h" + #include "scsi_logging.h" +@@ -64,6 +65,7 @@ static const char * scsi_debug_version_date = "20070104"; + #define PARAMETER_LIST_LENGTH_ERR 0x1a + #define INVALID_OPCODE 0x20 + #define ADDR_OUT_OF_RANGE 0x21 ++#define INVALID_COMMAND_OPCODE 0x20 + #define INVALID_FIELD_IN_CDB 0x24 + #define INVALID_FIELD_IN_PARAM_LIST 0x26 + #define POWERON_RESET 0x29 +@@ -180,7 +182,7 @@ static int sdebug_sectors_per; /* sectors per cylinder */ + #define SDEBUG_SENSE_LEN 32 + + #define SCSI_DEBUG_CANQUEUE 255 +-#define SCSI_DEBUG_MAX_CMD_LEN 16 ++#define SCSI_DEBUG_MAX_CMD_LEN 32 + + struct sdebug_dev_info { + struct list_head dev_list; +@@ -296,9 +298,25 @@ static void mk_sense_buffer(struct sdebug_dev_info *devip, int key, + } + + static void get_data_transfer_info(unsigned char *cmd, +- unsigned long long *lba, unsigned int *num) ++ unsigned long long *lba, unsigned int *num, ++ u32 *ei_lba) + { ++ *ei_lba = 0; ++ + switch (*cmd) { ++ case VARIABLE_LENGTH_CMD: ++ *lba = (u64)cmd[19] | (u64)cmd[18] << 8 | ++ (u64)cmd[17] << 16 | (u64)cmd[16] << 24 | ++ (u64)cmd[15] << 32 | (u64)cmd[14] << 40 | ++ (u64)cmd[13] << 48 | (u64)cmd[12] << 56; ++ ++ *ei_lba = (u32)cmd[23] | (u32)cmd[22] << 8 | ++ (u32)cmd[21] << 16 | (u32)cmd[20] << 24; ++ ++ *num = (u32)cmd[31] | (u32)cmd[30] << 8 | (u32)cmd[29] << 16 | ++ (u32)cmd[28] << 24; ++ break; ++ + case WRITE_16: + case READ_16: + *lba = (u64)cmd[9] | (u64)cmd[8] << 8 | +@@ -1589,7 +1607,7 @@ static int do_device_access(struct scsi_cmnd *scmd, + } + + static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, +- unsigned int sectors) ++ unsigned int sectors, u32 ei_lba) + { + unsigned int i, resid; + struct scatterlist *psgl; +@@ -1636,13 +1654,23 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, + return 0x01; + } + +- if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION && ++ if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && + be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) { + printk(KERN_ERR "%s: REF check failed on sector %lu\n", + __func__, (unsigned long)sector); + dif_errors++; + return 0x03; + } ++ ++ if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && ++ be32_to_cpu(sdt[i].ref_tag) != ei_lba) { ++ printk(KERN_ERR "%s: REF check failed on sector %lu\n", ++ __func__, (unsigned long)sector); ++ dif_errors++; ++ return 0x03; ++ } ++ ++ ei_lba++; + } + + resid = sectors * 8; /* Bytes of protection data to copy into sgl */ +@@ -1670,7 +1698,8 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, + } + + static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, +- unsigned int num, struct sdebug_dev_info *devip) ++ unsigned int num, struct sdebug_dev_info *devip, ++ u32 ei_lba) + { + unsigned long iflags; + int ret; +@@ -1699,7 +1728,7 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, + + /* DIX + T10 DIF */ + if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { +- int prot_ret = prot_verify_read(SCpnt, lba, num); ++ int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba); + + if (prot_ret) { + mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret); +@@ -1735,7 +1764,7 @@ void dump_sector(unsigned char *buf, int len) + } + + static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, +- unsigned int sectors) ++ unsigned int sectors, u32 ei_lba) + { + int i, j, ret; + struct sd_dif_tuple *sdt; +@@ -1749,11 +1778,6 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, + + sector = do_div(tmp_sec, sdebug_store_sectors); + +- if (((SCpnt->cmnd[1] >> 5) & 7) != 1) { +- printk(KERN_WARNING "scsi_debug: WRPROTECT != 1\n"); +- return 0; +- } +- + BUG_ON(scsi_sg_count(SCpnt) == 0); + BUG_ON(scsi_prot_sg_count(SCpnt) == 0); + +@@ -1808,7 +1832,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, + goto out; + } + +- if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION && ++ if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && + be32_to_cpu(sdt->ref_tag) + != (start_sec & 0xffffffff)) { + printk(KERN_ERR +@@ -1819,6 +1843,16 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, + goto out; + } + ++ if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && ++ be32_to_cpu(sdt->ref_tag) != ei_lba) { ++ printk(KERN_ERR ++ "%s: REF check failed on sector %lu\n", ++ __func__, (unsigned long)sector); ++ ret = 0x03; ++ dump_sector(daddr, scsi_debug_sector_size); ++ goto out; ++ } ++ + /* Would be great to copy this in bigger + * chunks. However, for the sake of + * correctness we need to verify each sector +@@ -1832,6 +1866,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, + sector = 0; /* Force wrap */ + + start_sec++; ++ ei_lba++; + daddr += scsi_debug_sector_size; + ppage_offset += sizeof(struct sd_dif_tuple); + } +@@ -1853,7 +1888,8 @@ out: + } + + static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, +- unsigned int num, struct sdebug_dev_info *devip) ++ unsigned int num, struct sdebug_dev_info *devip, ++ u32 ei_lba) + { + unsigned long iflags; + int ret; +@@ -1864,7 +1900,7 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, + + /* DIX + T10 DIF */ + if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { +- int prot_ret = prot_verify_write(SCpnt, lba, num); ++ int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba); + + if (prot_ret) { + mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret); +@@ -2872,11 +2908,12 @@ static int __init scsi_debug_init(void) + + case SD_DIF_TYPE0_PROTECTION: + case SD_DIF_TYPE1_PROTECTION: ++ case SD_DIF_TYPE2_PROTECTION: + case SD_DIF_TYPE3_PROTECTION: + break; + + default: +- printk(KERN_ERR "scsi_debug_init: dif must be 0, 1 or 3\n"); ++ printk(KERN_ERR "scsi_debug_init: dif must be 0, 1, 2 or 3\n"); + return -EINVAL; + } + +@@ -3121,6 +3158,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) + int len, k; + unsigned int num; + unsigned long long lba; ++ u32 ei_lba; + int errsts = 0; + int target = SCpnt->device->id; + struct sdebug_dev_info *devip = NULL; +@@ -3254,14 +3292,30 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) + case READ_16: + case READ_12: + case READ_10: ++ /* READ{10,12,16} and DIF Type 2 are natural enemies */ ++ if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && ++ cmd[1] & 0xe0) { ++ mk_sense_buffer(devip, ILLEGAL_REQUEST, ++ INVALID_COMMAND_OPCODE, 0); ++ errsts = check_condition_result; ++ break; ++ } ++ ++ if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || ++ scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && ++ (cmd[1] & 0xe0) == 0) ++ printk(KERN_ERR "Unprotected RD/WR to DIF device\n"); ++ ++ /* fall through */ + case READ_6: ++read: + errsts = check_readiness(SCpnt, 0, devip); + if (errsts) + break; + if (scsi_debug_fake_rw) + break; +- get_data_transfer_info(cmd, &lba, &num); +- errsts = resp_read(SCpnt, lba, num, devip); ++ get_data_transfer_info(cmd, &lba, &num, &ei_lba); ++ errsts = resp_read(SCpnt, lba, num, devip, ei_lba); + if (inj_recovered && (0 == errsts)) { + mk_sense_buffer(devip, RECOVERED_ERROR, + THRESHOLD_EXCEEDED, 0); +@@ -3288,14 +3342,30 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) + case WRITE_16: + case WRITE_12: + case WRITE_10: ++ /* WRITE{10,12,16} and DIF Type 2 are natural enemies */ ++ if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && ++ cmd[1] & 0xe0) { ++ mk_sense_buffer(devip, ILLEGAL_REQUEST, ++ INVALID_COMMAND_OPCODE, 0); ++ errsts = check_condition_result; ++ break; ++ } ++ ++ if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION || ++ scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) && ++ (cmd[1] & 0xe0) == 0) ++ printk(KERN_ERR "Unprotected RD/WR to DIF device\n"); ++ ++ /* fall through */ + case WRITE_6: ++write: + errsts = check_readiness(SCpnt, 0, devip); + if (errsts) + break; + if (scsi_debug_fake_rw) + break; +- get_data_transfer_info(cmd, &lba, &num); +- errsts = resp_write(SCpnt, lba, num, devip); ++ get_data_transfer_info(cmd, &lba, &num, &ei_lba); ++ errsts = resp_write(SCpnt, lba, num, devip, ei_lba); + if (inj_recovered && (0 == errsts)) { + mk_sense_buffer(devip, RECOVERED_ERROR, + THRESHOLD_EXCEEDED, 0); +@@ -3341,15 +3411,38 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) + break; + if (scsi_debug_fake_rw) + break; +- get_data_transfer_info(cmd, &lba, &num); +- errsts = resp_read(SCpnt, lba, num, devip); ++ get_data_transfer_info(cmd, &lba, &num, &ei_lba); ++ errsts = resp_read(SCpnt, lba, num, devip, ei_lba); + if (errsts) + break; +- errsts = resp_write(SCpnt, lba, num, devip); ++ errsts = resp_write(SCpnt, lba, num, devip, ei_lba); + if (errsts) + break; + errsts = resp_xdwriteread(SCpnt, lba, num, devip); + break; ++ case VARIABLE_LENGTH_CMD: ++ if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION) { ++ ++ if ((cmd[10] & 0xe0) == 0) ++ printk(KERN_ERR ++ "Unprotected RD/WR to DIF device\n"); ++ ++ if (cmd[9] == READ_32) { ++ BUG_ON(SCpnt->cmd_len < 32); ++ goto read; ++ } ++ ++ if (cmd[9] == WRITE_32) { ++ BUG_ON(SCpnt->cmd_len < 32); ++ goto write; ++ } ++ } ++ ++ mk_sense_buffer(devip, ILLEGAL_REQUEST, ++ INVALID_FIELD_IN_CDB, 0); ++ errsts = check_condition_result; ++ break; ++ + default: + if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) + printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c -index a168935..877204d 100644 +index a168935..1b0060b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -382,9 +382,13 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) @@ -844532,6 +910692,16 @@ index a168935..877204d 100644 default: return FAILED; } +@@ -721,6 +725,9 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, + case NEEDS_RETRY: + case FAILED: + break; ++ case ADD_TO_MLQUEUE: ++ rtn = NEEDS_RETRY; ++ break; + default: + rtn = FAILED; + break; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f3c4089..5987da8 100644 --- a/drivers/scsi/scsi_lib.c @@ -844587,7 +910757,7 @@ index 91482f2..fde5453 100644 NULL }; diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c -index 292c02f..b98885d 100644 +index 292c02f..a67fed1 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -291,7 +291,7 @@ static void fc_scsi_scan_rport(struct work_struct *work); @@ -844608,6 +910778,22 @@ index 292c02f..b98885d 100644 */ static void fc_bsg_softirq_done(struct request *rq) { +@@ -3586,6 +3586,7 @@ enum fc_dispatch_result { + + /** + * fc_bsg_host_dispatch - process fc host bsg requests and dispatch to LLDD ++ * @q: fc host request queue + * @shost: scsi host rport attached to + * @job: bsg job to be processed + */ +@@ -3693,6 +3694,7 @@ fc_bsg_goose_queue(struct fc_rport *rport) + + /** + * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD ++ * @q: rport request queue + * @shost: scsi host rport attached to + * @rport: rport request destined to + * @job: bsg job to be processed diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index b47240c..ad897df 100644 --- a/drivers/scsi/scsi_transport_iscsi.c @@ -844876,10 +911062,133 @@ index 0895d3c..fd47cb1 100644 SETUP_PHY_ATTRIBUTE(target_port_protocols); SETUP_PHY_ATTRIBUTE(device_type); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c -index b7b9fec..8dd96dc 100644 +index b7b9fec..9093c72 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c -@@ -956,7 +956,7 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, +@@ -116,6 +116,9 @@ static DEFINE_IDA(sd_index_ida); + * object after last put) */ + static DEFINE_MUTEX(sd_ref_mutex); + ++struct kmem_cache *sd_cdb_cache; ++mempool_t *sd_cdb_pool; ++ + static const char *sd_cache_types[] = { + "write through", "none", "write back", + "write back, no read (daft)" +@@ -370,6 +373,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) + mutex_unlock(&sd_ref_mutex); + } + ++static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif) ++{ ++ unsigned int prot_op = SCSI_PROT_NORMAL; ++ unsigned int dix = scsi_prot_sg_count(scmd); ++ ++ if (scmd->sc_data_direction == DMA_FROM_DEVICE) { ++ if (dif && dix) ++ prot_op = SCSI_PROT_READ_PASS; ++ else if (dif && !dix) ++ prot_op = SCSI_PROT_READ_STRIP; ++ else if (!dif && dix) ++ prot_op = SCSI_PROT_READ_INSERT; ++ } else { ++ if (dif && dix) ++ prot_op = SCSI_PROT_WRITE_PASS; ++ else if (dif && !dix) ++ prot_op = SCSI_PROT_WRITE_INSERT; ++ else if (!dif && dix) ++ prot_op = SCSI_PROT_WRITE_STRIP; ++ } ++ ++ scsi_set_prot_op(scmd, prot_op); ++ scsi_set_prot_type(scmd, dif); ++} ++ + /** + * sd_init_command - build a scsi (read or write) command from + * information in the request structure. +@@ -388,6 +416,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) + sector_t threshold; + unsigned int this_count = blk_rq_sectors(rq); + int ret, host_dif; ++ unsigned char protect; + + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { + ret = scsi_setup_blk_pc_cmnd(sdp, rq); +@@ -520,13 +549,49 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) + /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ + host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); + if (host_dif) +- SCpnt->cmnd[1] = 1 << 5; ++ protect = 1 << 5; + else +- SCpnt->cmnd[1] = 0; ++ protect = 0; ++ ++ if (host_dif == SD_DIF_TYPE2_PROTECTION) { ++ SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC); ++ ++ if (unlikely(SCpnt->cmnd == NULL)) { ++ ret = BLKPREP_DEFER; ++ goto out; ++ } + +- if (block > 0xffffffff) { ++ SCpnt->cmd_len = SD_EXT_CDB_SIZE; ++ memset(SCpnt->cmnd, 0, SCpnt->cmd_len); ++ SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD; ++ SCpnt->cmnd[7] = 0x18; ++ SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32; ++ SCpnt->cmnd[10] = protect | (blk_fua_rq(rq) ? 0x8 : 0); ++ ++ /* LBA */ ++ SCpnt->cmnd[12] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; ++ SCpnt->cmnd[13] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; ++ SCpnt->cmnd[14] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; ++ SCpnt->cmnd[15] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0; ++ SCpnt->cmnd[16] = (unsigned char) (block >> 24) & 0xff; ++ SCpnt->cmnd[17] = (unsigned char) (block >> 16) & 0xff; ++ SCpnt->cmnd[18] = (unsigned char) (block >> 8) & 0xff; ++ SCpnt->cmnd[19] = (unsigned char) block & 0xff; ++ ++ /* Expected Indirect LBA */ ++ SCpnt->cmnd[20] = (unsigned char) (block >> 24) & 0xff; ++ SCpnt->cmnd[21] = (unsigned char) (block >> 16) & 0xff; ++ SCpnt->cmnd[22] = (unsigned char) (block >> 8) & 0xff; ++ SCpnt->cmnd[23] = (unsigned char) block & 0xff; ++ ++ /* Transfer length */ ++ SCpnt->cmnd[28] = (unsigned char) (this_count >> 24) & 0xff; ++ SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff; ++ SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff; ++ SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; ++ } else if (block > 0xffffffff) { + SCpnt->cmnd[0] += READ_16 - READ_6; +- SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; ++ SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0); + SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; + SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; + SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; +@@ -547,7 +612,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) + this_count = 0xffff; + + SCpnt->cmnd[0] += READ_10 - READ_6; +- SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; ++ SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0); + SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; + SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; + SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; +@@ -578,8 +643,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) + + /* If DIF or DIX is enabled, tell HBA how to handle request */ + if (host_dif || scsi_prot_sg_count(SCpnt)) +- sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt), +- sdkp->protection_type); ++ sd_prot_op(SCpnt, host_dif); + + /* + * We shouldn't disconnect in the middle of a sector, so with a dumb +@@ -956,7 +1020,7 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, } #endif @@ -844888,7 +911197,77 @@ index b7b9fec..8dd96dc 100644 .owner = THIS_MODULE, .open = sd_open, .release = sd_release, -@@ -2021,6 +2021,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) +@@ -1023,6 +1087,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) + int result = SCpnt->result; + unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); + struct scsi_sense_hdr sshdr; ++ struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); + int sense_valid = 0; + int sense_deferred = 0; + +@@ -1084,6 +1149,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) + if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) + sd_dif_complete(SCpnt, good_bytes); + ++ if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) ++ == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) ++ mempool_free(SCpnt->cmnd, sd_cdb_pool); ++ + return good_bytes; + } + +@@ -1238,34 +1307,28 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) + u8 type; + + if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) +- type = 0; +- else +- type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ ++ return; + +- sdkp->protection_type = type; ++ type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ + +- switch (type) { +- case SD_DIF_TYPE0_PROTECTION: +- case SD_DIF_TYPE1_PROTECTION: +- case SD_DIF_TYPE3_PROTECTION: +- break; ++ if (type == sdkp->protection_type || !sdkp->first_scan) ++ return; + +- case SD_DIF_TYPE2_PROTECTION: +- sd_printk(KERN_ERR, sdkp, "formatted with DIF Type 2 " \ +- "protection which is currently unsupported. " \ +- "Disabling disk!\n"); +- goto disable; ++ sdkp->protection_type = type; + +- default: +- sd_printk(KERN_ERR, sdkp, "formatted with unknown " \ +- "protection type %d. Disabling disk!\n", type); +- goto disable; ++ if (type > SD_DIF_TYPE3_PROTECTION) { ++ sd_printk(KERN_ERR, sdkp, "formatted with unsupported " \ ++ "protection type %u. Disabling disk!\n", type); ++ sdkp->capacity = 0; ++ return; + } + +- return; +- +-disable: +- sdkp->capacity = 0; ++ if (scsi_host_dif_capable(sdp->host, type)) ++ sd_printk(KERN_NOTICE, sdkp, ++ "Enabling DIF Type %u protection\n", type); ++ else ++ sd_printk(KERN_NOTICE, sdkp, ++ "Disabling DIF Type %u protection\n", type); + } + + static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, +@@ -2021,6 +2084,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sdp->removable ? "removable " : ""); @@ -844896,7 +911275,7 @@ index b7b9fec..8dd96dc 100644 } /** -@@ -2106,6 +2107,7 @@ static int sd_probe(struct device *dev) +@@ -2106,6 +2170,7 @@ static int sd_probe(struct device *dev) get_device(&sdp->sdev_gendev); @@ -844904,6 +911283,157 @@ index b7b9fec..8dd96dc 100644 async_schedule(sd_probe_async, sdkp); return 0; +@@ -2298,8 +2363,24 @@ static int __init init_sd(void) + if (err) + goto err_out_class; + ++ sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE, ++ 0, 0, NULL); ++ if (!sd_cdb_cache) { ++ printk(KERN_ERR "sd: can't init extended cdb cache\n"); ++ goto err_out_class; ++ } ++ ++ sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache); ++ if (!sd_cdb_pool) { ++ printk(KERN_ERR "sd: can't init extended cdb pool\n"); ++ goto err_out_cache; ++ } ++ + return 0; + ++err_out_cache: ++ kmem_cache_destroy(sd_cdb_cache); ++ + err_out_class: + class_unregister(&sd_disk_class); + err_out: +@@ -2319,6 +2400,9 @@ static void __exit exit_sd(void) + + SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); + ++ mempool_destroy(sd_cdb_pool); ++ kmem_cache_destroy(sd_cdb_cache); ++ + scsi_unregister_driver(&sd_template.gendrv); + class_unregister(&sd_disk_class); + +diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h +index 8474b5b..e374804 100644 +--- a/drivers/scsi/sd.h ++++ b/drivers/scsi/sd.h +@@ -37,6 +37,11 @@ + */ + #define SD_LAST_BUGGY_SECTORS 8 + ++enum { ++ SD_EXT_CDB_SIZE = 32, /* Extended CDB size */ ++ SD_MEMPOOL_SIZE = 2, /* CDB pool size */ ++}; ++ + struct scsi_disk { + struct scsi_driver *driver; /* always &sd_template */ + struct scsi_device *device; +@@ -101,16 +106,12 @@ struct sd_dif_tuple { + + #ifdef CONFIG_BLK_DEV_INTEGRITY + +-extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int, unsigned int); + extern void sd_dif_config_host(struct scsi_disk *); + extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); + extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); + + #else /* CONFIG_BLK_DEV_INTEGRITY */ + +-static inline void sd_dif_op(struct scsi_cmnd *cmd, unsigned int a, unsigned int b, unsigned int c) +-{ +-} + static inline void sd_dif_config_host(struct scsi_disk *disk) + { + } +diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c +index 82f14a9..88da977 100644 +--- a/drivers/scsi/sd_dif.c ++++ b/drivers/scsi/sd_dif.c +@@ -320,15 +320,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp) + dif = 0; dix = 1; + } + +- if (type) { +- if (dif) +- sd_printk(KERN_NOTICE, sdkp, +- "Enabling DIF Type %d protection\n", type); +- else +- sd_printk(KERN_NOTICE, sdkp, +- "Disabling DIF Type %d protection\n", type); +- } +- + if (!dix) + return; + +@@ -360,62 +351,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp) + } + + /* +- * DIF DMA operation magic decoder ring. +- */ +-void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type) +-{ +- int csum_convert, prot_op; +- +- prot_op = 0; +- +- /* Convert checksum? */ +- if (scsi_host_get_guard(scmd->device->host) != SHOST_DIX_GUARD_CRC) +- csum_convert = 1; +- else +- csum_convert = 0; +- +- BUG_ON(dif && (scmd->cmnd[0] == READ_6 || scmd->cmnd[0] == WRITE_6)); +- +- switch (scmd->cmnd[0]) { +- case READ_6: +- case READ_10: +- case READ_12: +- case READ_16: +- if (dif && dix) +- if (csum_convert) +- prot_op = SCSI_PROT_READ_CONVERT; +- else +- prot_op = SCSI_PROT_READ_PASS; +- else if (dif && !dix) +- prot_op = SCSI_PROT_READ_STRIP; +- else if (!dif && dix) +- prot_op = SCSI_PROT_READ_INSERT; +- +- break; +- +- case WRITE_6: +- case WRITE_10: +- case WRITE_12: +- case WRITE_16: +- if (dif && dix) +- if (csum_convert) +- prot_op = SCSI_PROT_WRITE_CONVERT; +- else +- prot_op = SCSI_PROT_WRITE_PASS; +- else if (dif && !dix) +- prot_op = SCSI_PROT_WRITE_INSERT; +- else if (!dif && dix) +- prot_op = SCSI_PROT_WRITE_STRIP; +- +- break; +- } +- +- scsi_set_prot_op(scmd, prot_op); +- if (dif) +- scsi_set_prot_type(scmd, type); +-} +- +-/* + * The virtual start sector is the one that was originally submitted + * by the block layer. Due to partitioning, MD/DM cloning, etc. the + * actual physical start sector is likely to be different. Remap diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 4f618f4..55b034b 100644 --- a/drivers/scsi/ses.c @@ -845185,9 +911715,33 @@ index 4f618f4..55b034b 100644 .add_dev = ses_intf_add, .remove_dev = ses_intf_remove, diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c -index 9230402..848b594 100644 +index 9230402..f4ccd73 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c +@@ -1708,11 +1708,6 @@ static int sg_finish_rem_req(Sg_request * srp) + Sg_scatter_hold *req_schp = &srp->data; + + SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used)); +- if (srp->res_used) +- sg_unlink_reserve(sfp, srp); +- else +- sg_remove_scat(req_schp); +- + if (srp->rq) { + if (srp->bio) + ret = blk_rq_unmap_user(srp->bio); +@@ -1720,6 +1715,11 @@ static int sg_finish_rem_req(Sg_request * srp) + blk_put_request(srp->rq); + } + ++ if (srp->res_used) ++ sg_unlink_reserve(sfp, srp); ++ else ++ sg_remove_scat(req_schp); ++ + sg_remove_request(sfp, srp); + + return ret; @@ -1811,7 +1811,7 @@ retry: return 0; out: @@ -845225,7 +911779,7 @@ index 9230402..848b594 100644 .next = dev_seq_next, .stop = dev_seq_stop, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c -index cce0fe4..eb61f7a 100644 +index cce0fe4..d6f340f 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -525,7 +525,7 @@ static int sr_block_media_changed(struct gendisk *disk) @@ -845237,6 +911791,35 @@ index cce0fe4..eb61f7a 100644 { .owner = THIS_MODULE, .open = sr_block_open, +@@ -684,14 +684,20 @@ static void get_sectorsize(struct scsi_cd *cd) + cd->capacity = 0x1fffff; + sector_size = 2048; /* A guess, just in case */ + } else { +-#if 0 +- if (cdrom_get_last_written(&cd->cdi, +- &cd->capacity)) +-#endif +- cd->capacity = 1 + ((buffer[0] << 24) | +- (buffer[1] << 16) | +- (buffer[2] << 8) | +- buffer[3]); ++ long last_written; ++ ++ cd->capacity = 1 + ((buffer[0] << 24) | (buffer[1] << 16) | ++ (buffer[2] << 8) | buffer[3]); ++ /* ++ * READ_CAPACITY doesn't return the correct size on ++ * certain UDF media. If last_written is larger, use ++ * it instead. ++ * ++ * http://bugzilla.kernel.org/show_bug.cgi?id=9668 ++ */ ++ if (!cdrom_get_last_written(&cd->cdi, &last_written)) ++ cd->capacity = max_t(long, cd->capacity, last_written); ++ + sector_size = (buffer[4] << 24) | + (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; + switch (sector_size) { diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 8d2a95c..09fa886 100644 --- a/drivers/scsi/stex.c @@ -845861,7 +912444,7 @@ index 80e7642..b6acd19 100644 if (port->x_char) { diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c -index f8df068..8d349b2 100644 +index f8df068..300cea7 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -244,7 +244,7 @@ static void cpm_uart_int_rx(struct uart_port *port) @@ -845873,6 +912456,15 @@ index f8df068..8d349b2 100644 struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; cbd_t __iomem *bdp; u16 status; +@@ -649,7 +649,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) + u8 *p; + int count; + struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; +- struct circ_buf *xmit = &port->info->xmit; ++ struct circ_buf *xmit = &port->state->xmit; + + /* Handle xon/xoff */ + if (port->x_char) { diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 7be52fe..31f1723 100644 --- a/drivers/serial/crisv10.c @@ -1052771,10 +1119363,10 @@ index ca6ade6..e47f683 100644 + module will be called wis-tw2804 diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile -index e514b4a..d14ea84 100644 +index e514b4a..1301caa 100644 --- a/drivers/staging/go7007/Makefile +++ b/drivers/staging/go7007/Makefile -@@ -6,22 +6,34 @@ +@@ -6,22 +6,29 @@ obj-$(CONFIG_VIDEO_GO7007) += go7007.o obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o @@ -1052808,11 +1119400,6 @@ index e514b4a..d14ea84 100644 -EXTRA_CFLAGS += -Idrivers/staging/saa7134 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -+ -+# Ubuntu 8.04 has CONFIG_SND undefined, so include lum sound/config.h too -+ifeq ($(CONFIG_SND),) -+EXTRA_CFLAGS += -include sound/config.h -+endif diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index 77b1e76..472f4bb 100644 --- a/drivers/staging/go7007/go7007-driver.c @@ -1473522,6 +1540109,30 @@ index 0000000..0a577d5 + return status; +} + +diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c +index eb6ddfc..6cb29d3 100644 +--- a/drivers/usb/gadget/f_loopback.c ++++ b/drivers/usb/gadget/f_loopback.c +@@ -22,7 +22,6 @@ + /* #define VERBOSE_DEBUG */ + + #include +-#include + #include + + #include "g_zero.h" +diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c +index 46d6266..b4a3ba6 100644 +--- a/drivers/usb/gadget/f_obex.c ++++ b/drivers/usb/gadget/f_obex.c +@@ -24,7 +24,6 @@ + /* #define VERBOSE_DEBUG */ + + #include +-#include + #include + + #include "u_serial.h" diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 96fb118..d2de10b 100644 --- a/drivers/usb/gadget/f_phonet.c @@ -1473734,6 +1540345,18 @@ index 424a37c..c9966cc 100644 } static void rndis_response_available(void *_rndis) +diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c +index bffe91d..09cba27 100644 +--- a/drivers/usb/gadget/f_sourcesink.c ++++ b/drivers/usb/gadget/f_sourcesink.c +@@ -22,7 +22,6 @@ + /* #define VERBOSE_DEBUG */ + + #include +-#include + #include + + #include "g_zero.h" diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index d701bf4..7881f12 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c @@ -1476623,10 +1543246,18 @@ index a9b452f..d5f4c1d 100644 device_del(&udc->gadget.dev); udc->driver = NULL; diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c -index 0f3d22f..b5200d5 100644 +index 0f3d22f..8252595 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c -@@ -253,11 +253,13 @@ static int gaudio_open_snd_dev(struct gaudio *card) +@@ -10,7 +10,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -253,11 +252,13 @@ static int gaudio_open_snd_dev(struct gaudio *card) snd->filp = filp_open(fn_cap, O_RDONLY, 0); if (IS_ERR(snd->filp)) { ERROR(card, "No such PCM capture device: %s\n", fn_cap); @@ -1476645,10 +1543276,18 @@ index 0f3d22f..b5200d5 100644 return 0; } diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c -index 016f63b..f8751ff 100644 +index 016f63b..2fc02bd 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c -@@ -37,8 +37,9 @@ +@@ -23,7 +23,6 @@ + /* #define VERBOSE_DEBUG */ + + #include +-#include + #include + #include + #include +@@ -37,8 +36,9 @@ * one (!) network link through the USB gadget stack, normally "usb0". * * The control and data models are handled by the function driver which @@ -1476660,7 +1543299,7 @@ index 016f63b..f8751ff 100644 * * Link level addressing is handled by this component using module * parameters; if no such parameters are provided, random link level -@@ -68,9 +69,13 @@ struct eth_dev { +@@ -68,9 +68,13 @@ struct eth_dev { struct list_head tx_reqs, rx_reqs; atomic_t tx_qlen; @@ -1476676,7 +1543315,7 @@ index 016f63b..f8751ff 100644 struct work_struct work; -@@ -181,7 +186,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) +@@ -181,7 +185,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) * - ... probably more ethtool ops */ @@ -1476685,7 +1543324,7 @@ index 016f63b..f8751ff 100644 .get_drvinfo = eth_get_drvinfo, .get_link = ethtool_op_get_link, }; -@@ -269,7 +274,7 @@ enomem: +@@ -269,7 +273,7 @@ enomem: static void rx_complete(struct usb_ep *ep, struct usb_request *req) { @@ -1476694,7 +1543333,7 @@ index 016f63b..f8751ff 100644 struct eth_dev *dev = ep->driver_data; int status = req->status; -@@ -278,26 +283,47 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) +@@ -278,26 +282,47 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) /* normal completion */ case 0: skb_put(skb, req->actual); @@ -1476759,7 +1543398,7 @@ index 016f63b..f8751ff 100644 break; /* software-driven interface shutdown */ -@@ -465,7 +491,8 @@ static inline int is_promisc(u16 cdc_filter) +@@ -465,7 +490,8 @@ static inline int is_promisc(u16 cdc_filter) return cdc_filter & USB_CDC_PACKET_TYPE_PROMISCUOUS; } @@ -1476769,7 +1543408,7 @@ index 016f63b..f8751ff 100644 { struct eth_dev *dev = netdev_priv(net); int length = skb->len; -@@ -487,7 +514,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) +@@ -487,7 +513,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) if (!in) { dev_kfree_skb_any(skb); @@ -1476778,7 +1543417,7 @@ index 016f63b..f8751ff 100644 } /* apply outgoing CDC or RNDIS filters */ -@@ -506,7 +533,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) +@@ -506,7 +532,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) type = USB_CDC_PACKET_TYPE_ALL_MULTICAST; if (!(cdc_filter & type)) { dev_kfree_skb_any(skb); @@ -1476787,7 +1543426,7 @@ index 016f63b..f8751ff 100644 } } /* ignores USB_CDC_PACKET_TYPE_DIRECTED */ -@@ -536,14 +563,15 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) +@@ -536,14 +562,15 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) * or there's not enough space for extra headers we need */ if (dev->wrap) { @@ -1476808,7 +1543447,7 @@ index 016f63b..f8751ff 100644 length = skb->len; } req->buf = skb->data; -@@ -577,16 +605,16 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) +@@ -577,16 +604,16 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net) } if (retval) { @@ -1476827,7 +1543466,7 @@ index 016f63b..f8751ff 100644 } /*-------------------------------------------------------------------------*/ -@@ -752,6 +780,8 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) +@@ -752,6 +779,8 @@ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); @@ -1489574,7 +1556213,7 @@ index ee9505e..d640dc9 100644 +#define SANWA_VENDOR_ID 0x11ad +#define SANWA_PRODUCT_ID 0x0001 diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c -index f48d05e..68fa0e4 100644 +index f48d05e..8c075b2 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -51,6 +51,12 @@ struct sierra_iface_info { @@ -1489818,10 +1556457,11 @@ index f48d05e..68fa0e4 100644 /* Set the port private data pointer */ usb_set_serial_port_data(port, portdata); } -@@ -845,6 +912,83 @@ static void sierra_release(struct usb_serial *serial) +@@ -845,6 +912,88 @@ static void sierra_release(struct usb_serial *serial) } } ++#ifdef CONFIG_PM +static void stop_read_write_urbs(struct usb_serial *serial) +{ + int i, j; @@ -1489898,11 +1556538,15 @@ index f48d05e..68fa0e4 100644 + + return ec ? -EIO : 0; +} ++#else ++#define sierra_suspend NULL ++#define sierra_resume NULL ++#endif + static struct usb_serial_driver sierra_device = { .driver = { .owner = THIS_MODULE, -@@ -865,6 +1009,8 @@ static struct usb_serial_driver sierra_device = { +@@ -865,6 +1014,8 @@ static struct usb_serial_driver sierra_device = { .tiocmset = sierra_tiocmset, .attach = sierra_startup, .release = sierra_release, @@ -1493311,7 +1559955,7 @@ index 378f277..a699aab 100644 /* Unsupported option */ else { diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig -index f9d19be..d570e92 100644 +index f9d19be..09bfa96 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -31,6 +31,13 @@ config LCD_CORGI @@ -1493337,7 +1559981,7 @@ index f9d19be..d570e92 100644 help This provides a backlight control internal to the Atmel LCDC driver. If the LCD "contrast control" on your board is wired -@@ -229,3 +236,18 @@ config BACKLIGHT_SAHARA +@@ -229,3 +236,29 @@ config BACKLIGHT_SAHARA help If you have a Tabletkiosk Sahara Touch-iT, say y to enable the backlight driver. @@ -1493356,8 +1560000,19 @@ index f9d19be..d570e92 100644 + help + Say Y to enable the backlight driver on Avionic Design Xanthos-based + boards. ++ ++config BACKLIGHT_ADP5520 ++ tristate "Backlight Driver for ADP5520/ADP5501 using WLED" ++ depends on BACKLIGHT_CLASS_DEVICE && PMIC_ADP5520 ++ help ++ If you have a LCD backlight connected to the BST/BL_SNK output of ++ ADP5520 or ADP5501, say Y here to enable this driver. ++ ++ To compile this driver as a module, choose M here: the module will ++ be called adp5520_bl. ++ diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile -index 4eb178c..a483709 100644 +index 4eb178c..9a40554 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -3,6 +3,7 @@ @@ -1493368,13 +1560023,397 @@ index 4eb178c..a483709 100644 obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o obj-$(CONFIG_LCD_ILI9320) += ili9320.o obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o -@@ -24,4 +25,5 @@ obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o +@@ -24,4 +25,7 @@ obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o -- +obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o +obj-$(CONFIG_BACKLIGHT_ADX) += adx_bl.o ++obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o + +diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c +new file mode 100644 +index 0000000..fc32d59 +--- /dev/null ++++ b/drivers/video/backlight/adp5520_bl.c +@@ -0,0 +1,377 @@ ++/* ++ * Backlight driver for Analog Devices ADP5520/ADP5501 MFD PMICs ++ * ++ * Copyright 2009 Analog Devices Inc. ++ * ++ * Licensed under the GPL-2 or later. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct adp5520_bl { ++ struct device *master; ++ struct adp5520_backlight_platfrom_data *pdata; ++ struct mutex lock; ++ unsigned long cached_daylight_max; ++ int id; ++ int current_brightness; ++}; ++ ++static int adp5520_bl_set(struct backlight_device *bl, int brightness) ++{ ++ struct adp5520_bl *data = bl_get_data(bl); ++ struct device *master = data->master; ++ int ret = 0; ++ ++ if (data->pdata->en_ambl_sens) { ++ if ((brightness > 0) && (brightness < ADP5020_MAX_BRIGHTNESS)) { ++ /* Disable Ambient Light auto adjust */ ++ ret |= adp5520_clr_bits(master, BL_CONTROL, ++ BL_AUTO_ADJ); ++ ret |= adp5520_write(master, DAYLIGHT_MAX, brightness); ++ } else { ++ /* ++ * MAX_BRIGHTNESS -> Enable Ambient Light auto adjust ++ * restore daylight l3 sysfs brightness ++ */ ++ ret |= adp5520_write(master, DAYLIGHT_MAX, ++ data->cached_daylight_max); ++ ret |= adp5520_set_bits(master, BL_CONTROL, ++ BL_AUTO_ADJ); ++ } ++ } else { ++ ret |= adp5520_write(master, DAYLIGHT_MAX, brightness); ++ } ++ ++ if (data->current_brightness && brightness == 0) ++ ret |= adp5520_set_bits(master, ++ MODE_STATUS, DIM_EN); ++ else if (data->current_brightness == 0 && brightness) ++ ret |= adp5520_clr_bits(master, ++ MODE_STATUS, DIM_EN); ++ ++ if (!ret) ++ data->current_brightness = brightness; ++ ++ return ret; ++} ++ ++static int adp5520_bl_update_status(struct backlight_device *bl) ++{ ++ int brightness = bl->props.brightness; ++ if (bl->props.power != FB_BLANK_UNBLANK) ++ brightness = 0; ++ ++ if (bl->props.fb_blank != FB_BLANK_UNBLANK) ++ brightness = 0; ++ ++ return adp5520_bl_set(bl, brightness); ++} ++ ++static int adp5520_bl_get_brightness(struct backlight_device *bl) ++{ ++ struct adp5520_bl *data = bl_get_data(bl); ++ int error; ++ uint8_t reg_val; ++ ++ error = adp5520_read(data->master, BL_VALUE, ®_val); ++ ++ return error ? data->current_brightness : reg_val; ++} ++ ++static struct backlight_ops adp5520_bl_ops = { ++ .update_status = adp5520_bl_update_status, ++ .get_brightness = adp5520_bl_get_brightness, ++}; ++ ++static int adp5520_bl_setup(struct backlight_device *bl) ++{ ++ struct adp5520_bl *data = bl_get_data(bl); ++ struct device *master = data->master; ++ struct adp5520_backlight_platfrom_data *pdata = data->pdata; ++ int ret = 0; ++ ++ ret |= adp5520_write(master, DAYLIGHT_MAX, pdata->l1_daylight_max); ++ ret |= adp5520_write(master, DAYLIGHT_DIM, pdata->l1_daylight_dim); ++ ++ if (pdata->en_ambl_sens) { ++ data->cached_daylight_max = pdata->l1_daylight_max; ++ ret |= adp5520_write(master, OFFICE_MAX, pdata->l2_office_max); ++ ret |= adp5520_write(master, OFFICE_DIM, pdata->l2_office_dim); ++ ret |= adp5520_write(master, DARK_MAX, pdata->l3_dark_max); ++ ret |= adp5520_write(master, DARK_DIM, pdata->l3_dark_dim); ++ ret |= adp5520_write(master, L2_TRIP, pdata->l2_trip); ++ ret |= adp5520_write(master, L2_HYS, pdata->l2_hyst); ++ ret |= adp5520_write(master, L3_TRIP, pdata->l3_trip); ++ ret |= adp5520_write(master, L3_HYS, pdata->l3_hyst); ++ ret |= adp5520_write(master, ALS_CMPR_CFG, ++ ALS_CMPR_CFG_VAL(pdata->abml_filt, L3_EN)); ++ } ++ ++ ret |= adp5520_write(master, BL_CONTROL, ++ BL_CTRL_VAL(pdata->fade_led_law, pdata->en_ambl_sens); ++ ++ ret |= adp5520_write(master, BL_FADE, FADE_VAL(pdata->fade_in, ++ pdata->fade_out)); ++ ++ ret |= adp5520_set_bits(master, MODE_STATUS, BL_EN | DIM_EN); ++ ++ return ret; ++} ++ ++static ssize_t adp5520_show(struct device *dev, char *buf, int reg) ++{ ++ struct adp5520_bl *data = dev_get_drvdata(dev); ++ int error; ++ uint8_t reg_val; ++ ++ mutex_lock(&data->lock); ++ error = adp5520_read(data->master, reg, ®_val); ++ mutex_unlock(&data->lock); ++ ++ return sprintf(buf, "%u\n", reg_val); ++} ++ ++static ssize_t adp5520_store(struct device *dev, const char *buf, ++ size_t count, int reg) ++{ ++ struct adp5520_bl *data = dev_get_drvdata(dev); ++ unsigned long val; ++ int ret; ++ ++ ret = strict_strtoul(buf, 10, &val); ++ if (ret) ++ return ret; ++ ++ mutex_lock(&data->lock); ++ adp5520_write(data->master, reg, val); ++ mutex_unlock(&data->lock); ++ ++ return count; ++} ++ ++static ssize_t adp5520_bl_dark_max_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, DARK_MAX); ++} ++ ++static ssize_t adp5520_bl_dark_max_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ return adp5520_store(dev, buf, count, DARK_MAX); ++} ++static DEVICE_ATTR(dark_max, 0664, adp5520_bl_dark_max_show, ++ adp5520_bl_dark_max_store); ++ ++static ssize_t adp5520_bl_office_max_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, OFFICE_MAX); ++} ++ ++static ssize_t adp5520_bl_office_max_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ return adp5520_store(dev, buf, count, OFFICE_MAX); ++} ++static DEVICE_ATTR(office_max, 0664, adp5520_bl_office_max_show, ++ adp5520_bl_office_max_store); ++ ++static ssize_t adp5520_bl_daylight_max_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, DAYLIGHT_MAX); ++} ++ ++static ssize_t adp5520_bl_daylight_max_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t count) ++{ ++ struct adp5520_bl *data = dev_get_drvdata(dev); ++ ++ strict_strtoul(buf, 10, &data->cached_daylight_max); ++ return adp5520_store(dev, buf, count, DAYLIGHT_MAX); ++} ++static DEVICE_ATTR(daylight_max, 0664, adp5520_bl_daylight_max_show, ++ adp5520_bl_daylight_max_store); ++ ++static ssize_t adp5520_bl_dark_dim_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, DARK_DIM); ++} ++ ++static ssize_t adp5520_bl_dark_dim_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ return adp5520_store(dev, buf, count, DARK_DIM); ++} ++static DEVICE_ATTR(dark_dim, 0664, adp5520_bl_dark_dim_show, ++ adp5520_bl_dark_dim_store); ++ ++static ssize_t adp5520_bl_office_dim_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, OFFICE_DIM); ++} ++ ++static ssize_t adp5520_bl_office_dim_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ return adp5520_store(dev, buf, count, OFFICE_DIM); ++} ++static DEVICE_ATTR(office_dim, 0664, adp5520_bl_office_dim_show, ++ adp5520_bl_office_dim_store); ++ ++static ssize_t adp5520_bl_daylight_dim_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return adp5520_show(dev, buf, DAYLIGHT_DIM); ++} ++ ++static ssize_t adp5520_bl_daylight_dim_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ return adp5520_store(dev, buf, count, DAYLIGHT_DIM); ++} ++static DEVICE_ATTR(daylight_dim, 0664, adp5520_bl_daylight_dim_show, ++ adp5520_bl_daylight_dim_store); ++ ++static struct attribute *adp5520_bl_attributes[] = { ++ &dev_attr_dark_max.attr, ++ &dev_attr_dark_dim.attr, ++ &dev_attr_office_max.attr, ++ &dev_attr_office_dim.attr, ++ &dev_attr_daylight_max.attr, ++ &dev_attr_daylight_dim.attr, ++ NULL ++}; ++ ++static const struct attribute_group adp5520_bl_attr_group = { ++ .attrs = adp5520_bl_attributes, ++}; ++ ++static int __devinit adp5520_bl_probe(struct platform_device *pdev) ++{ ++ struct backlight_device *bl; ++ struct adp5520_bl *data; ++ int ret = 0; ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (data == NULL) ++ return -ENOMEM; ++ ++ data->master = pdev->dev.parent; ++ data->pdata = pdev->dev.platform_data; ++ ++ if (data->pdata == NULL) { ++ dev_err(&pdev->dev, "missing platform data\n"); ++ kfree(data); ++ return -ENODEV; ++ } ++ ++ data->id = pdev->id; ++ data->current_brightness = 0; ++ ++ mutex_init(&data->lock); ++ ++ bl = backlight_device_register(pdev->name, data->master, ++ data, &adp5520_bl_ops); ++ if (IS_ERR(bl)) { ++ dev_err(&pdev->dev, "failed to register backlight\n"); ++ kfree(data); ++ return PTR_ERR(bl); ++ } ++ ++ bl->props.max_brightness = ++ bl->props.brightness = ADP5020_MAX_BRIGHTNESS; ++ ++ if (data->pdata->en_ambl_sens) ++ ret = sysfs_create_group(&bl->dev.kobj, ++ &adp5520_bl_attr_group); ++ ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register sysfs\n"); ++ backlight_device_unregister(bl); ++ kfree(data); ++ } ++ ++ platform_set_drvdata(pdev, bl); ++ ret |= adp5520_bl_setup(bl); ++ backlight_update_status(bl); ++ ++ return ret; ++} ++ ++static int __devexit adp5520_bl_remove(struct platform_device *pdev) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ struct adp5520_bl *data = bl_get_data(bl); ++ ++ adp5520_clr_bits(data->master, MODE_STATUS, BL_EN); ++ ++ if (data->pdata->en_ambl_sens) ++ sysfs_remove_group(&bl->dev.kobj, ++ &adp5520_bl_attr_group); ++ ++ backlight_device_unregister(bl); ++ kfree(data); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int adp5520_bl_suspend(struct platform_device *pdev, ++ pm_message_t state) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ return adp5520_bl_set(bl, 0); ++} ++ ++static int adp5520_bl_resume(struct platform_device *pdev) ++{ ++ struct backlight_device *bl = platform_get_drvdata(pdev); ++ ++ backlight_update_status(bl); ++ return 0; ++} ++#else ++#define adp5520_bl_suspend NULL ++#define adp5520_bl_resume NULL ++#endif ++ ++static struct platform_driver adp5520_bl_driver = { ++ .driver = { ++ .name = "adp5520-backlight", ++ .owner = THIS_MODULE, ++ }, ++ .probe = adp5520_bl_probe, ++ .remove = __devexit_p(adp5520_bl_remove), ++ .suspend = adp5520_bl_suspend, ++ .resume = adp5520_bl_resume, ++}; ++ ++static int __init adp5520_bl_init(void) ++{ ++ return platform_driver_register(&adp5520_bl_driver); ++} ++module_init(adp5520_bl_init); ++ ++static void __exit adp5520_bl_exit(void) ++{ ++ platform_driver_unregister(&adp5520_bl_driver); ++} ++module_exit(adp5520_bl_exit); ++ ++MODULE_AUTHOR("Michael Hennerich "); ++MODULE_DESCRIPTION("ADP5520(01) Backlight Driver"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:adp5520-backlight"); diff --git a/drivers/video/backlight/adx_bl.c b/drivers/video/backlight/adx_bl.c new file mode 100644 index 0000000..2c3bdfc @@ -1493559,6 +1560598,73 @@ index 0000000..2c3bdfc +MODULE_AUTHOR("Thierry Reding "); +MODULE_DESCRIPTION("Avionic Design Xanthos Backlight Driver"); +MODULE_LICENSE("GPL v2"); +diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c +index 157057c..6615ac7 100644 +--- a/drivers/video/backlight/backlight.c ++++ b/drivers/video/backlight/backlight.c +@@ -73,6 +73,27 @@ static inline void backlight_unregister_fb(struct backlight_device *bd) + } + #endif /* CONFIG_FB */ + ++static void backlight_generate_event(struct backlight_device *bd, ++ enum backlight_update_reason reason) ++{ ++ char *envp[2]; ++ ++ switch (reason) { ++ case BACKLIGHT_UPDATE_SYSFS: ++ envp[0] = "SOURCE=sysfs"; ++ break; ++ case BACKLIGHT_UPDATE_HOTKEY: ++ envp[0] = "SOURCE=hotkey"; ++ break; ++ default: ++ envp[0] = "SOURCE=unknown"; ++ break; ++ } ++ envp[1] = NULL; ++ kobject_uevent_env(&bd->dev.kobj, KOBJ_CHANGE, envp); ++ sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); ++} ++ + static ssize_t backlight_show_power(struct device *dev, + struct device_attribute *attr,char *buf) + { +@@ -142,6 +163,8 @@ static ssize_t backlight_store_brightness(struct device *dev, + } + mutex_unlock(&bd->ops_lock); + ++ backlight_generate_event(bd, BACKLIGHT_UPDATE_SYSFS); ++ + return rc; + } + +@@ -214,6 +237,25 @@ static struct device_attribute bl_device_attributes[] = { + }; + + /** ++ * backlight_force_update - tell the backlight subsystem that hardware state ++ * has changed ++ * @bd: the backlight device to update ++ * ++ * Updates the internal state of the backlight in response to a hardware event, ++ * and generate a uevent to notify userspace ++ */ ++void backlight_force_update(struct backlight_device *bd, ++ enum backlight_update_reason reason) ++{ ++ mutex_lock(&bd->ops_lock); ++ if (bd->ops && bd->ops->get_brightness) ++ bd->props.brightness = bd->ops->get_brightness(bd); ++ mutex_unlock(&bd->ops_lock); ++ backlight_generate_event(bd, reason); ++} ++EXPORT_SYMBOL(backlight_force_update); ++ ++/** + * backlight_device_register - create and register a new object of + * backlight_device class. + * @name: the name of the new object(must be the same as the name of the diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index f8a4bb2..2211a85 100644 --- a/drivers/video/backlight/corgi_lcd.c @@ -1516479,7 +1583585,7 @@ index a882f26..f536005 100644 static void vring_kick(struct virtqueue *_vq) diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c -index f05d2a3..ba3d71f 100644 +index f05d2a3..9554ad5 100644 --- a/drivers/vlynq/vlynq.c +++ b/drivers/vlynq/vlynq.c @@ -28,7 +28,6 @@ @@ -1516490,6 +1583596,15 @@ index f05d2a3..ba3d71f 100644 #include #include +@@ -703,7 +702,7 @@ static int vlynq_probe(struct platform_device *pdev) + dev->mem_start = mem_res->start; + dev->mem_end = mem_res->end; + +- len = regs_res->end - regs_res->start; ++ len = resource_size(regs_res); + if (!request_mem_region(regs_res->start, len, dev_name(&dev->dev))) { + printk(KERN_ERR "%s: Can't request vlynq registers\n", + dev_name(&dev->dev)); diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index df52cb3..406caa6 100644 --- a/drivers/w1/masters/ds2482.c @@ -1516580,7 +1583695,7 @@ index fdf7285..52ccb3d 100644 struct w1_netlink_cmd *cmd; struct w1_slave *sl; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig -index b1ccc04..ff3eb8f 100644 +index b1ccc04..3711b88 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -55,6 +55,13 @@ config SOFT_WATCHDOG @@ -1516597,7 +1583712,7 @@ index b1ccc04..ff3eb8f 100644 config WM8350_WATCHDOG tristate "WM8350 watchdog" depends on MFD_WM8350 -@@ -266,6 +273,15 @@ config STMP3XXX_WATCHDOG +@@ -266,6 +273,22 @@ config STMP3XXX_WATCHDOG To compile this driver as a module, choose M here: the module will be called stmp3xxx_wdt. @@ -1516609,11 +1583724,18 @@ index b1ccc04..ff3eb8f 100644 + for the Nuvoton NUC900 series SoCs. + To compile this driver as a module, choose M here: the + module will be called nuc900_wdt. ++ ++config ADX_WATCHDOG ++ tristate "Avionic Design Xanthos watchdog" ++ depends on ARCH_PXA_ADX ++ help ++ Say Y here if you want support for the watchdog timer on Avionic ++ Design Xanthos boards. + # AVR32 Architecture config AT32AP700X_WDT -@@ -369,6 +385,28 @@ config SC520_WDT +@@ -369,6 +392,28 @@ config SC520_WDT You can compile this driver directly into the kernel, or use it as a module. The module will be called sc520_wdt. @@ -1516643,18 +1583765,19 @@ index b1ccc04..ff3eb8f 100644 tristate "Eurotech CPU-1220/1410 Watchdog Timer" depends on X86 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile -index 3d77429..348b3b8 100644 +index 3d77429..699199b 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile -@@ -44,6 +44,7 @@ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o +@@ -44,6 +44,8 @@ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o +obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o ++obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o # AVR32 Architecture obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o -@@ -64,6 +65,7 @@ obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o +@@ -64,6 +66,7 @@ obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o obj-$(CONFIG_GEODE_WDT) += geodewdt.o obj-$(CONFIG_SC520_WDT) += sc520_wdt.o @@ -1516662,13 +1583785,373 @@ index 3d77429..348b3b8 100644 obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o obj-$(CONFIG_IB700_WDT) += ib700wdt.o obj-$(CONFIG_IBMASR) += ibmasr.o -@@ -139,5 +141,6 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o +@@ -139,5 +142,6 @@ obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwd.o # XTENSA Architecture # Architecture Independant +obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o +diff --git a/drivers/watchdog/adx_wdt.c b/drivers/watchdog/adx_wdt.c +new file mode 100644 +index 0000000..77afb0a +--- /dev/null ++++ b/drivers/watchdog/adx_wdt.c +@@ -0,0 +1,354 @@ ++/* ++ * Copyright (C) 2008-2009 Avionic Design GmbH ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define WATCHDOG_NAME "adx-wdt" ++ ++/* register offsets */ ++#define ADX_WDT_CONTROL 0x00 ++#define ADX_WDT_CONTROL_ENABLE (1 << 0) ++#define ADX_WDT_CONTROL_nRESET (1 << 1) ++#define ADX_WDT_TIMEOUT 0x08 ++ ++static struct platform_device *adx_wdt_dev; ++static unsigned long driver_open; ++ ++#define WDT_STATE_STOP 0 ++#define WDT_STATE_START 1 ++ ++struct adx_wdt { ++ void __iomem *base; ++ unsigned long timeout; ++ unsigned int state; ++ unsigned int wake; ++ spinlock_t lock; ++}; ++ ++static struct watchdog_info adx_wdt_info = { ++ .identity = "Avionic Design Xanthos Watchdog", ++ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, ++}; ++ ++static void adx_wdt_start_locked(struct adx_wdt *wdt) ++{ ++ u32 ctrl; ++ ++ ctrl = readl(wdt->base + ADX_WDT_CONTROL); ++ ctrl |= ADX_WDT_CONTROL_ENABLE; ++ writel(ctrl, wdt->base + ADX_WDT_CONTROL); ++ wdt->state = WDT_STATE_START; ++} ++ ++static void adx_wdt_start(struct adx_wdt *wdt) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&wdt->lock, flags); ++ adx_wdt_start_locked(wdt); ++ spin_unlock_irqrestore(&wdt->lock, flags); ++} ++ ++static void adx_wdt_stop_locked(struct adx_wdt *wdt) ++{ ++ u32 ctrl; ++ ++ ctrl = readl(wdt->base + ADX_WDT_CONTROL); ++ ctrl &= ~ADX_WDT_CONTROL_ENABLE; ++ writel(ctrl, wdt->base + ADX_WDT_CONTROL); ++ wdt->state = WDT_STATE_STOP; ++} ++ ++static void adx_wdt_stop(struct adx_wdt *wdt) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&wdt->lock, flags); ++ adx_wdt_stop_locked(wdt); ++ spin_unlock_irqrestore(&wdt->lock, flags); ++} ++ ++static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds) ++{ ++ unsigned long timeout = seconds * 1000; ++ unsigned long flags; ++ unsigned int state; ++ ++ spin_lock_irqsave(&wdt->lock, flags); ++ state = wdt->state; ++ adx_wdt_stop_locked(wdt); ++ writel(timeout, wdt->base + ADX_WDT_TIMEOUT); ++ ++ if (state == WDT_STATE_START) ++ adx_wdt_start_locked(wdt); ++ ++ wdt->timeout = timeout; ++ spin_unlock_irqrestore(&wdt->lock, flags); ++} ++ ++static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds) ++{ ++ *seconds = wdt->timeout / 1000; ++} ++ ++static void adx_wdt_keepalive(struct adx_wdt *wdt) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&wdt->lock, flags); ++ writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT); ++ spin_unlock_irqrestore(&wdt->lock, flags); ++} ++ ++static int adx_wdt_open(struct inode *inode, struct file *file) ++{ ++ struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev); ++ ++ if (test_and_set_bit(0, &driver_open)) ++ return -EBUSY; ++ ++ file->private_data = wdt; ++ adx_wdt_set_timeout(wdt, 30); ++ adx_wdt_start(wdt); ++ ++ return nonseekable_open(inode, file); ++} ++ ++static int adx_wdt_release(struct inode *inode, struct file *file) ++{ ++ struct adx_wdt *wdt = file->private_data; ++ ++ adx_wdt_stop(wdt); ++ clear_bit(0, &driver_open); ++ ++ return 0; ++} ++ ++static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct adx_wdt *wdt = file->private_data; ++ void __user *argp = (void __user *)arg; ++ unsigned long __user *p = argp; ++ unsigned long seconds = 0; ++ unsigned int options; ++ long ret = -EINVAL; ++ ++ switch (cmd) { ++ case WDIOC_GETSUPPORT: ++ if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info))) ++ return -EFAULT; ++ else ++ return 0; ++ ++ case WDIOC_GETSTATUS: ++ case WDIOC_GETBOOTSTATUS: ++ return put_user(0, p); ++ ++ case WDIOC_KEEPALIVE: ++ adx_wdt_keepalive(wdt); ++ return 0; ++ ++ case WDIOC_SETTIMEOUT: ++ if (get_user(seconds, p)) ++ return -EFAULT; ++ ++ adx_wdt_set_timeout(wdt, seconds); ++ ++ /* fallthrough */ ++ case WDIOC_GETTIMEOUT: ++ adx_wdt_get_timeout(wdt, &seconds); ++ return put_user(seconds, p); ++ ++ case WDIOC_SETOPTIONS: ++ if (copy_from_user(&options, argp, sizeof(options))) ++ return -EFAULT; ++ ++ if (options & WDIOS_DISABLECARD) { ++ adx_wdt_stop(wdt); ++ ret = 0; ++ } ++ ++ if (options & WDIOS_ENABLECARD) { ++ adx_wdt_start(wdt); ++ ret = 0; ++ } ++ ++ return ret; ++ ++ default: ++ break; ++ } ++ ++ return -ENOTTY; ++} ++ ++static ssize_t adx_wdt_write(struct file *file, const char __user *data, ++ size_t len, loff_t *ppos) ++{ ++ struct adx_wdt *wdt = file->private_data; ++ ++ if (len) ++ adx_wdt_keepalive(wdt); ++ ++ return len; ++} ++ ++static const struct file_operations adx_wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .open = adx_wdt_open, ++ .release = adx_wdt_release, ++ .unlocked_ioctl = adx_wdt_ioctl, ++ .write = adx_wdt_write, ++}; ++ ++static struct miscdevice adx_wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &adx_wdt_fops, ++}; ++ ++static int __devinit adx_wdt_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ struct adx_wdt *wdt; ++ int ret = 0; ++ u32 ctrl; ++ ++ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); ++ if (!wdt) { ++ dev_err(&pdev->dev, "cannot allocate WDT structure\n"); ++ return -ENOMEM; ++ } ++ ++ spin_lock_init(&wdt->lock); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ dev_err(&pdev->dev, "cannot obtain I/O memory region\n"); ++ return -ENXIO; ++ } ++ ++ res = devm_request_mem_region(&pdev->dev, res->start, ++ res->end - res->start + 1, res->name); ++ if (!res) { ++ dev_err(&pdev->dev, "cannot request I/O memory region\n"); ++ return -ENXIO; ++ } ++ ++ wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, ++ res->end - res->start + 1); ++ if (!wdt->base) { ++ dev_err(&pdev->dev, "cannot remap I/O memory region\n"); ++ return -ENXIO; ++ } ++ ++ /* disable watchdog and reboot on timeout */ ++ ctrl = readl(wdt->base + ADX_WDT_CONTROL); ++ ctrl &= ~ADX_WDT_CONTROL_ENABLE; ++ ctrl &= ~ADX_WDT_CONTROL_nRESET; ++ writel(ctrl, wdt->base + ADX_WDT_CONTROL); ++ ++ platform_set_drvdata(pdev, wdt); ++ adx_wdt_dev = pdev; ++ ++ ret = misc_register(&adx_wdt_miscdev); ++ if (ret) { ++ dev_err(&pdev->dev, "cannot register miscdev on minor %d " ++ "(err=%d)\n", WATCHDOG_MINOR, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int __devexit adx_wdt_remove(struct platform_device *pdev) ++{ ++ struct adx_wdt *wdt = platform_get_drvdata(pdev); ++ ++ misc_deregister(&adx_wdt_miscdev); ++ adx_wdt_stop(wdt); ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++static void adx_wdt_shutdown(struct platform_device *pdev) ++{ ++ struct adx_wdt *wdt = platform_get_drvdata(pdev); ++ adx_wdt_stop(wdt); ++} ++ ++#ifdef CONFIG_PM ++static int adx_wdt_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct adx_wdt *wdt = platform_get_drvdata(pdev); ++ ++ wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0; ++ adx_wdt_stop(wdt); ++ ++ return 0; ++} ++ ++static int adx_wdt_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct adx_wdt *wdt = platform_get_drvdata(pdev); ++ ++ if (wdt->wake) ++ adx_wdt_start(wdt); ++ ++ return 0; ++} ++ ++static struct dev_pm_ops adx_wdt_pm_ops = { ++ .suspend = adx_wdt_suspend, ++ .resume = adx_wdt_resume, ++}; ++ ++# define ADX_WDT_PM_OPS (&adx_wdt_pm_ops) ++#else ++# define ADX_WDT_PM_OPS NULL ++#endif ++ ++static struct platform_driver adx_wdt_driver = { ++ .probe = adx_wdt_probe, ++ .remove = __devexit_p(adx_wdt_remove), ++ .shutdown = adx_wdt_shutdown, ++ .driver = { ++ .name = WATCHDOG_NAME, ++ .owner = THIS_MODULE, ++ .pm = ADX_WDT_PM_OPS, ++ }, ++}; ++ ++static int __init adx_wdt_init(void) ++{ ++ return platform_driver_register(&adx_wdt_driver); ++} ++ ++static void __exit adx_wdt_exit(void) ++{ ++ platform_driver_unregister(&adx_wdt_driver); ++} ++ ++module_init(adx_wdt_init); ++module_exit(adx_wdt_exit); ++ ++MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver"); ++MODULE_LICENSE("GPL v2"); ++MODULE_AUTHOR("Thierry Reding "); ++MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 2f8643e..2e94b71 100644 --- a/drivers/watchdog/ar7_wdt.c @@ -1517408,6 +1584891,28 @@ index 2e44426..bb66958 100644 return NULL; return platform_get_resource_byname(pdv, type, buf); } +diff --git a/drivers/watchdog/sb_wdog.c b/drivers/watchdog/sb_wdog.c +index 9748eed..c8eadd4 100644 +--- a/drivers/watchdog/sb_wdog.c ++++ b/drivers/watchdog/sb_wdog.c +@@ -1,7 +1,7 @@ + /* + * Watchdog driver for SiByte SB1 SoCs + * +- * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp ++ * Copyright (C) 2007 OnStor, Inc. * Andrew Sharp + * + * This driver is intended to make the second of two hardware watchdogs + * on the Sibyte 12XX and 11XX SoCs available to the user. There are two +@@ -326,7 +326,7 @@ static void __exit sbwdog_exit(void) + module_init(sbwdog_init); + module_exit(sbwdog_exit); + +-MODULE_AUTHOR("Andrew Sharp "); ++MODULE_AUTHOR("Andrew Sharp "); + MODULE_DESCRIPTION("SiByte Watchdog"); + + module_param(timeout, ulong, 0); diff --git a/drivers/watchdog/sbc_fitpc2_wdt.c b/drivers/watchdog/sbc_fitpc2_wdt.c new file mode 100644 index 0000000..852ca19 @@ -1605057,6 +1672562,31 @@ index 0e7da7b..d4bf8ca 100644 endif # MISC_FILESYSTEMS +diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c +index 798cb07..3f57ce4 100644 +--- a/fs/adfs/inode.c ++++ b/fs/adfs/inode.c +@@ -19,9 +19,6 @@ static int + adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, + int create) + { +- if (block < 0) +- goto abort_negative; +- + if (!create) { + if (block >= inode->i_blocks) + goto abort_toobig; +@@ -34,10 +31,6 @@ adfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh, + /* don't support allocation of blocks yet */ + return -EIO; + +-abort_negative: +- adfs_error(inode->i_sb, "block %d < 0", block); +- return -EIO; +- + abort_toobig: + return 0; + } diff --git a/fs/afs/flock.c b/fs/afs/flock.c index 3ff8bdd..0931bc1 100644 --- a/fs/afs/flock.c @@ -1605345,6 +1672875,72 @@ index 47d4a01..d11c51f 100644 return error; } EXPORT_SYMBOL_GPL(anon_inode_getfd); +diff --git a/fs/attr.c b/fs/attr.c +index 9fe1b1b..96d394b 100644 +--- a/fs/attr.c ++++ b/fs/attr.c +@@ -18,7 +18,7 @@ + /* Taken over from the old code... */ + + /* POSIX UID/GID verification for setting inode attributes. */ +-int inode_change_ok(struct inode *inode, struct iattr *attr) ++int inode_change_ok(const struct inode *inode, struct iattr *attr) + { + int retval = -EPERM; + unsigned int ia_valid = attr->ia_valid; +@@ -60,9 +60,51 @@ fine: + error: + return retval; + } +- + EXPORT_SYMBOL(inode_change_ok); + ++/** ++ * inode_newsize_ok - may this inode be truncated to a given size ++ * @inode: the inode to be truncated ++ * @offset: the new size to assign to the inode ++ * @Returns: 0 on success, -ve errno on failure ++ * ++ * inode_newsize_ok will check filesystem limits and ulimits to check that the ++ * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ ++ * when necessary. Caller must not proceed with inode size change if failure is ++ * returned. @inode must be a file (not directory), with appropriate ++ * permissions to allow truncate (inode_newsize_ok does NOT check these ++ * conditions). ++ * ++ * inode_newsize_ok must be called with i_mutex held. ++ */ ++int inode_newsize_ok(const struct inode *inode, loff_t offset) ++{ ++ if (inode->i_size < offset) { ++ unsigned long limit; ++ ++ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; ++ if (limit != RLIM_INFINITY && offset > limit) ++ goto out_sig; ++ if (offset > inode->i_sb->s_maxbytes) ++ goto out_big; ++ } else { ++ /* ++ * truncation of in-use swapfiles is disallowed - it would ++ * cause subsequent swapout to scribble on the now-freed ++ * blocks. ++ */ ++ if (IS_SWAPFILE(inode)) ++ return -ETXTBSY; ++ } ++ ++ return 0; ++out_sig: ++ send_sig(SIGXFSZ, current, 0); ++out_big: ++ return -EFBIG; ++} ++EXPORT_SYMBOL(inode_newsize_ok); ++ + int inode_setattr(struct inode * inode, struct iattr * attr) + { + unsigned int ia_valid = attr->ia_valid; diff --git a/fs/autofs/dirhash.c b/fs/autofs/dirhash.c index 2316e94..e947915 100644 --- a/fs/autofs/dirhash.c @@ -1605359,10 +1672955,24 @@ index 2316e94..e947915 100644 umount_ok = may_umount(path.mnt); path_put(&path); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c -index 615d549..dd376c1 100644 +index 615d549..33baf27 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c -@@ -842,7 +842,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) +@@ -737,12 +737,7 @@ befs_put_super(struct super_block *sb) + { + kfree(BEFS_SB(sb)->mount_opts.iocharset); + BEFS_SB(sb)->mount_opts.iocharset = NULL; +- +- if (BEFS_SB(sb)->nls) { +- unload_nls(BEFS_SB(sb)->nls); +- BEFS_SB(sb)->nls = NULL; +- } +- ++ unload_nls(BEFS_SB(sb)->nls); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + } +@@ -842,7 +837,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = BEFS_SUPER_MAGIC; /* Set real blocksize of fs */ sb_set_blocksize(sb, (ulong) befs_sb->block_size); @@ -1605372,7 +1672982,7 @@ index 615d549..dd376c1 100644 if (IS_ERR(root)) { ret = PTR_ERR(root); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c -index b7c1603..442d94f 100644 +index b7c1603..b9b3bb5 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -501,22 +501,22 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, @@ -1605422,7 +1673032,89 @@ index b7c1603..442d94f 100644 static void fill_elf_header(struct elfhdr *elf, int segs, u16 machine, u32 flags, u8 osabi) -@@ -2016,7 +2013,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un +@@ -1714,42 +1711,52 @@ struct elf_note_info { + int numnote; + }; + +-static int fill_note_info(struct elfhdr *elf, int phdrs, +- struct elf_note_info *info, +- long signr, struct pt_regs *regs) ++static int elf_note_info_init(struct elf_note_info *info) + { +-#define NUM_NOTES 6 +- struct list_head *t; +- +- info->notes = NULL; +- info->prstatus = NULL; +- info->psinfo = NULL; +- info->fpu = NULL; +-#ifdef ELF_CORE_COPY_XFPREGS +- info->xfpu = NULL; +-#endif ++ memset(info, 0, sizeof(*info)); + INIT_LIST_HEAD(&info->thread_list); + +- info->notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), +- GFP_KERNEL); ++ /* Allocate space for six ELF notes */ ++ info->notes = kmalloc(6 * sizeof(struct memelfnote), GFP_KERNEL); + if (!info->notes) + return 0; + info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL); + if (!info->psinfo) +- return 0; ++ goto notes_free; + info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL); + if (!info->prstatus) +- return 0; ++ goto psinfo_free; + info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL); + if (!info->fpu) +- return 0; ++ goto prstatus_free; + #ifdef ELF_CORE_COPY_XFPREGS + info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL); + if (!info->xfpu) +- return 0; ++ goto fpu_free; ++#endif ++ return 1; ++#ifdef ELF_CORE_COPY_XFPREGS ++ fpu_free: ++ kfree(info->fpu); + #endif ++ prstatus_free: ++ kfree(info->prstatus); ++ psinfo_free: ++ kfree(info->psinfo); ++ notes_free: ++ kfree(info->notes); ++ return 0; ++} ++ ++static int fill_note_info(struct elfhdr *elf, int phdrs, ++ struct elf_note_info *info, ++ long signr, struct pt_regs *regs) ++{ ++ struct list_head *t; ++ ++ if (!elf_note_info_init(info)) ++ return 0; + +- info->thread_status_size = 0; + if (signr) { + struct core_thread *ct; + struct elf_thread_status *ets; +@@ -1809,8 +1816,6 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, + #endif + + return 1; +- +-#undef NUM_NOTES + } + + static size_t get_note_info_size(struct elf_note_info *info) +@@ -2016,7 +2021,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un goto end_coredump; /* Align to page */ @@ -1605432,7 +1673124,7 @@ index b7c1603..442d94f 100644 for (vma = first_vma(current, gate_vma); vma != NULL; vma = next_vma(vma, gate_vma)) { -@@ -2027,33 +2025,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un +@@ -2027,33 +2033,19 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { struct page *page; @@ -1605479,10 +1673171,41 @@ index b7c1603..442d94f 100644 } diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c -index 20fbece..7628547 100644 +index 20fbece..38502c6 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c -@@ -1325,9 +1325,6 @@ static int writenote(struct memelfnote *men, struct file *file) +@@ -283,20 +283,23 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, + } + + stack_size = exec_params.stack_size; +- if (stack_size < interp_params.stack_size) +- stack_size = interp_params.stack_size; +- + if (exec_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) + executable_stack = EXSTACK_ENABLE_X; + else if (exec_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) + executable_stack = EXSTACK_DISABLE_X; +- else if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) +- executable_stack = EXSTACK_ENABLE_X; +- else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) +- executable_stack = EXSTACK_DISABLE_X; + else + executable_stack = EXSTACK_DEFAULT; + ++ if (stack_size == 0) { ++ stack_size = interp_params.stack_size; ++ if (interp_params.flags & ELF_FDPIC_FLAG_EXEC_STACK) ++ executable_stack = EXSTACK_ENABLE_X; ++ else if (interp_params.flags & ELF_FDPIC_FLAG_NOEXEC_STACK) ++ executable_stack = EXSTACK_DISABLE_X; ++ else ++ executable_stack = EXSTACK_DEFAULT; ++ } ++ + retval = -ENOEXEC; + if (stack_size == 0) + goto error; +@@ -1325,9 +1328,6 @@ static int writenote(struct memelfnote *men, struct file *file) #define DUMP_WRITE(addr, nr) \ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ goto end_coredump; @@ -1605492,7 +1673215,7 @@ index 20fbece..7628547 100644 static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) { -@@ -1518,6 +1515,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, +@@ -1518,6 +1518,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, unsigned long *limit, unsigned long mm_flags) { struct vm_area_struct *vma; @@ -1605500,7 +1673223,7 @@ index 20fbece..7628547 100644 for (vma = current->mm->mmap; vma; vma = vma->vm_next) { unsigned long addr; -@@ -1525,43 +1523,26 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, +@@ -1525,43 +1526,26 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, if (!maydump(vma, mm_flags)) continue; @@ -1605560,7 +1673283,7 @@ index 20fbece..7628547 100644 } #endif -@@ -1802,7 +1783,8 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, +@@ -1802,7 +1786,8 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, goto end_coredump; } @@ -1605570,11 +1673293,286 @@ index 20fbece..7628547 100644 if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) goto end_coredump; +diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c +index e92f229..a279665 100644 +--- a/fs/binfmt_flat.c ++++ b/fs/binfmt_flat.c +@@ -278,8 +278,6 @@ static int decompress_exec( + ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); + if (ret <= 0) + break; +- if (ret >= (unsigned long) -4096) +- break; + len -= ret; + + strm.next_in = buf; +@@ -335,7 +333,7 @@ calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) + "(%d != %d)", (unsigned) r, curid, id); + goto failed; + } else if ( ! p->lib_list[id].loaded && +- load_flat_shared_library(id, p) > (unsigned long) -4096) { ++ IS_ERR_VALUE(load_flat_shared_library(id, p))) { + printk("BINFMT_FLAT: failed to load library %d", id); + goto failed; + } +@@ -545,7 +543,7 @@ static int load_flat_file(struct linux_binprm * bprm, + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, + MAP_PRIVATE|MAP_EXECUTABLE, 0); + up_write(¤t->mm->mmap_sem); +- if (!textpos || textpos >= (unsigned long) -4096) { ++ if (!textpos || IS_ERR_VALUE(textpos)) { + if (!textpos) + textpos = (unsigned long) -ENOMEM; + printk("Unable to mmap process text, errno %d\n", (int)-textpos); +@@ -560,7 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm, + PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); + +- if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { ++ if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { + if (!realdatastart) + realdatastart = (unsigned long) -ENOMEM; + printk("Unable to allocate RAM for process data, errno %d\n", +@@ -587,7 +585,7 @@ static int load_flat_file(struct linux_binprm * bprm, + result = bprm->file->f_op->read(bprm->file, (char *) datapos, + data_len + (relocs * sizeof(unsigned long)), &fpos); + } +- if (result >= (unsigned long)-4096) { ++ if (IS_ERR_VALUE(result)) { + printk("Unable to read data+bss, errno %d\n", (int)-result); + do_munmap(current->mm, textpos, text_len); + do_munmap(current->mm, realdatastart, data_len + extra); +@@ -607,7 +605,7 @@ static int load_flat_file(struct linux_binprm * bprm, + PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); + +- if (!textpos || textpos >= (unsigned long) -4096) { ++ if (!textpos || IS_ERR_VALUE(textpos)) { + if (!textpos) + textpos = (unsigned long) -ENOMEM; + printk("Unable to allocate RAM for process text/data, errno %d\n", +@@ -641,7 +639,7 @@ static int load_flat_file(struct linux_binprm * bprm, + fpos = 0; + result = bprm->file->f_op->read(bprm->file, + (char *) textpos, text_len, &fpos); +- if (result < (unsigned long) -4096) ++ if (!IS_ERR_VALUE(result)) + result = decompress_exec(bprm, text_len, (char *) datapos, + data_len + (relocs * sizeof(unsigned long)), 0); + } +@@ -651,13 +649,13 @@ static int load_flat_file(struct linux_binprm * bprm, + fpos = 0; + result = bprm->file->f_op->read(bprm->file, + (char *) textpos, text_len, &fpos); +- if (result < (unsigned long) -4096) { ++ if (!IS_ERR_VALUE(result)) { + fpos = ntohl(hdr->data_start); + result = bprm->file->f_op->read(bprm->file, (char *) datapos, + data_len + (relocs * sizeof(unsigned long)), &fpos); + } + } +- if (result >= (unsigned long)-4096) { ++ if (IS_ERR_VALUE(result)) { + printk("Unable to read code+data+bss, errno %d\n",(int)-result); + do_munmap(current->mm, textpos, text_len + data_len + extra + + MAX_SHARED_LIBS * sizeof(unsigned long)); +@@ -835,7 +833,7 @@ static int load_flat_shared_library(int id, struct lib_info *libs) + + res = prepare_binprm(&bprm); + +- if (res <= (unsigned long)-4096) ++ if (!IS_ERR_VALUE(res)) + res = load_flat_file(&bprm, libs, id, NULL); + + abort_creds(bprm.cred); +@@ -880,7 +878,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) + stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ + + res = load_flat_file(bprm, &libinfo, 0, &stack_len); +- if (res > (unsigned long)-4096) ++ if (IS_ERR_VALUE(res)) + return res; + + /* Update data segment pointers for all libraries */ diff --git a/fs/block_dev.c b/fs/block_dev.c -index 94dfda2..5d1ed50 100644 +index 94dfda2..9cf4b92 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c -@@ -420,7 +420,6 @@ static void bdev_destroy_inode(struct inode *inode) +@@ -216,8 +216,6 @@ EXPORT_SYMBOL(fsync_bdev); + * freeze_bdev -- lock a filesystem and force it into a consistent state + * @bdev: blockdevice to lock + * +- * This takes the block device bd_mount_sem to make sure no new mounts +- * happen on bdev until thaw_bdev() is called. + * If a superblock is found on this device, we take the s_umount semaphore + * on it to make sure nobody unmounts until the snapshot creation is done. + * The reference counter (bd_fsfreeze_count) guarantees that only the last +@@ -232,46 +230,55 @@ struct super_block *freeze_bdev(struct block_device *bdev) + int error = 0; + + mutex_lock(&bdev->bd_fsfreeze_mutex); +- if (bdev->bd_fsfreeze_count > 0) { +- bdev->bd_fsfreeze_count++; ++ if (++bdev->bd_fsfreeze_count > 1) { ++ /* ++ * We don't even need to grab a reference - the first call ++ * to freeze_bdev grab an active reference and only the last ++ * thaw_bdev drops it. ++ */ + sb = get_super(bdev); ++ drop_super(sb); + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return sb; + } +- bdev->bd_fsfreeze_count++; +- +- down(&bdev->bd_mount_sem); +- sb = get_super(bdev); +- if (sb && !(sb->s_flags & MS_RDONLY)) { +- sb->s_frozen = SB_FREEZE_WRITE; +- smp_wmb(); +- +- sync_filesystem(sb); +- +- sb->s_frozen = SB_FREEZE_TRANS; +- smp_wmb(); +- +- sync_blockdev(sb->s_bdev); +- +- if (sb->s_op->freeze_fs) { +- error = sb->s_op->freeze_fs(sb); +- if (error) { +- printk(KERN_ERR +- "VFS:Filesystem freeze failed\n"); +- sb->s_frozen = SB_UNFROZEN; +- drop_super(sb); +- up(&bdev->bd_mount_sem); +- bdev->bd_fsfreeze_count--; +- mutex_unlock(&bdev->bd_fsfreeze_mutex); +- return ERR_PTR(error); +- } ++ ++ sb = get_active_super(bdev); ++ if (!sb) ++ goto out; ++ if (sb->s_flags & MS_RDONLY) { ++ deactivate_locked_super(sb); ++ mutex_unlock(&bdev->bd_fsfreeze_mutex); ++ return sb; ++ } ++ ++ sb->s_frozen = SB_FREEZE_WRITE; ++ smp_wmb(); ++ ++ sync_filesystem(sb); ++ ++ sb->s_frozen = SB_FREEZE_TRANS; ++ smp_wmb(); ++ ++ sync_blockdev(sb->s_bdev); ++ ++ if (sb->s_op->freeze_fs) { ++ error = sb->s_op->freeze_fs(sb); ++ if (error) { ++ printk(KERN_ERR ++ "VFS:Filesystem freeze failed\n"); ++ sb->s_frozen = SB_UNFROZEN; ++ deactivate_locked_super(sb); ++ bdev->bd_fsfreeze_count--; ++ mutex_unlock(&bdev->bd_fsfreeze_mutex); ++ return ERR_PTR(error); + } + } ++ up_write(&sb->s_umount); + ++ out: + sync_blockdev(bdev); + mutex_unlock(&bdev->bd_fsfreeze_mutex); +- +- return sb; /* thaw_bdev releases s->s_umount and bd_mount_sem */ ++ return sb; /* thaw_bdev releases s->s_umount */ + } + EXPORT_SYMBOL(freeze_bdev); + +@@ -284,44 +291,44 @@ EXPORT_SYMBOL(freeze_bdev); + */ + int thaw_bdev(struct block_device *bdev, struct super_block *sb) + { +- int error = 0; ++ int error = -EINVAL; + + mutex_lock(&bdev->bd_fsfreeze_mutex); +- if (!bdev->bd_fsfreeze_count) { +- mutex_unlock(&bdev->bd_fsfreeze_mutex); +- return -EINVAL; +- } +- +- bdev->bd_fsfreeze_count--; +- if (bdev->bd_fsfreeze_count > 0) { +- if (sb) +- drop_super(sb); +- mutex_unlock(&bdev->bd_fsfreeze_mutex); +- return 0; +- } +- +- if (sb) { +- BUG_ON(sb->s_bdev != bdev); +- if (!(sb->s_flags & MS_RDONLY)) { +- if (sb->s_op->unfreeze_fs) { +- error = sb->s_op->unfreeze_fs(sb); +- if (error) { +- printk(KERN_ERR +- "VFS:Filesystem thaw failed\n"); +- sb->s_frozen = SB_FREEZE_TRANS; +- bdev->bd_fsfreeze_count++; +- mutex_unlock(&bdev->bd_fsfreeze_mutex); +- return error; +- } +- } +- sb->s_frozen = SB_UNFROZEN; +- smp_wmb(); +- wake_up(&sb->s_wait_unfrozen); ++ if (!bdev->bd_fsfreeze_count) ++ goto out_unlock; ++ ++ error = 0; ++ if (--bdev->bd_fsfreeze_count > 0) ++ goto out_unlock; ++ ++ if (!sb) ++ goto out_unlock; ++ ++ BUG_ON(sb->s_bdev != bdev); ++ down_write(&sb->s_umount); ++ if (sb->s_flags & MS_RDONLY) ++ goto out_deactivate; ++ ++ if (sb->s_op->unfreeze_fs) { ++ error = sb->s_op->unfreeze_fs(sb); ++ if (error) { ++ printk(KERN_ERR ++ "VFS:Filesystem thaw failed\n"); ++ sb->s_frozen = SB_FREEZE_TRANS; ++ bdev->bd_fsfreeze_count++; ++ mutex_unlock(&bdev->bd_fsfreeze_mutex); ++ return error; + } +- drop_super(sb); + } + +- up(&bdev->bd_mount_sem); ++ sb->s_frozen = SB_UNFROZEN; ++ smp_wmb(); ++ wake_up(&sb->s_wait_unfrozen); ++ ++out_deactivate: ++ if (sb) ++ deactivate_locked_super(sb); ++out_unlock: + mutex_unlock(&bdev->bd_fsfreeze_mutex); + return 0; + } +@@ -420,7 +427,6 @@ static void bdev_destroy_inode(struct inode *inode) { struct bdev_inode *bdi = BDEV_I(inode); @@ -1605582,7 +1673580,15 @@ index 94dfda2..5d1ed50 100644 kmem_cache_free(bdev_cachep, bdi); } -@@ -1115,7 +1114,7 @@ EXPORT_SYMBOL(revalidate_disk); +@@ -431,7 +437,6 @@ static void init_once(void *foo) + + memset(bdev, 0, sizeof(*bdev)); + mutex_init(&bdev->bd_mutex); +- sema_init(&bdev->bd_mount_sem, 1); + INIT_LIST_HEAD(&bdev->bd_inodes); + INIT_LIST_HEAD(&bdev->bd_list); + #ifdef CONFIG_SYSFS +@@ -1115,7 +1120,7 @@ EXPORT_SYMBOL(revalidate_disk); int check_disk_change(struct block_device *bdev) { struct gendisk *disk = bdev->bd_disk; @@ -1605591,7 +1673597,7 @@ index 94dfda2..5d1ed50 100644 if (!bdops->media_changed) return 0; -@@ -1405,6 +1404,33 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) +@@ -1405,6 +1410,33 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg) } /* @@ -1605625,7 +1673631,7 @@ index 94dfda2..5d1ed50 100644 * Try to release a page associated with block device when the system * is under memory pressure. */ -@@ -1436,7 +1462,7 @@ const struct file_operations def_blk_fops = { +@@ -1436,7 +1468,7 @@ const struct file_operations def_blk_fops = { .read = do_sync_read, .write = do_sync_write, .aio_read = generic_file_aio_read, @@ -1605634,11 +1673640,916 @@ index 94dfda2..5d1ed50 100644 .mmap = generic_file_mmap, .fsync = block_fsync, .unlocked_ioctl = block_ioctl, +diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c +index 019e8af..282ca08 100644 +--- a/fs/btrfs/async-thread.c ++++ b/fs/btrfs/async-thread.c +@@ -48,6 +48,9 @@ struct btrfs_worker_thread { + /* number of things on the pending list */ + atomic_t num_pending; + ++ /* reference counter for this struct */ ++ atomic_t refs; ++ + unsigned long sequence; + + /* protects the pending list. */ +@@ -71,7 +74,12 @@ static void check_idle_worker(struct btrfs_worker_thread *worker) + unsigned long flags; + spin_lock_irqsave(&worker->workers->lock, flags); + worker->idle = 1; +- list_move(&worker->worker_list, &worker->workers->idle_list); ++ ++ /* the list may be empty if the worker is just starting */ ++ if (!list_empty(&worker->worker_list)) { ++ list_move(&worker->worker_list, ++ &worker->workers->idle_list); ++ } + spin_unlock_irqrestore(&worker->workers->lock, flags); + } + } +@@ -87,23 +95,49 @@ static void check_busy_worker(struct btrfs_worker_thread *worker) + unsigned long flags; + spin_lock_irqsave(&worker->workers->lock, flags); + worker->idle = 0; +- list_move_tail(&worker->worker_list, +- &worker->workers->worker_list); ++ ++ if (!list_empty(&worker->worker_list)) { ++ list_move_tail(&worker->worker_list, ++ &worker->workers->worker_list); ++ } + spin_unlock_irqrestore(&worker->workers->lock, flags); + } + } + +-static noinline int run_ordered_completions(struct btrfs_workers *workers, +- struct btrfs_work *work) ++static void check_pending_worker_creates(struct btrfs_worker_thread *worker) + { ++ struct btrfs_workers *workers = worker->workers; + unsigned long flags; + ++ rmb(); ++ if (!workers->atomic_start_pending) ++ return; ++ ++ spin_lock_irqsave(&workers->lock, flags); ++ if (!workers->atomic_start_pending) ++ goto out; ++ ++ workers->atomic_start_pending = 0; ++ if (workers->num_workers >= workers->max_workers) ++ goto out; ++ ++ spin_unlock_irqrestore(&workers->lock, flags); ++ btrfs_start_workers(workers, 1); ++ return; ++ ++out: ++ spin_unlock_irqrestore(&workers->lock, flags); ++} ++ ++static noinline int run_ordered_completions(struct btrfs_workers *workers, ++ struct btrfs_work *work) ++{ + if (!workers->ordered) + return 0; + + set_bit(WORK_DONE_BIT, &work->flags); + +- spin_lock_irqsave(&workers->lock, flags); ++ spin_lock(&workers->order_lock); + + while (1) { + if (!list_empty(&workers->prio_order_list)) { +@@ -126,45 +160,118 @@ static noinline int run_ordered_completions(struct btrfs_workers *workers, + if (test_and_set_bit(WORK_ORDER_DONE_BIT, &work->flags)) + break; + +- spin_unlock_irqrestore(&workers->lock, flags); ++ spin_unlock(&workers->order_lock); + + work->ordered_func(work); + + /* now take the lock again and call the freeing code */ +- spin_lock_irqsave(&workers->lock, flags); ++ spin_lock(&workers->order_lock); + list_del(&work->order_list); + work->ordered_free(work); + } + +- spin_unlock_irqrestore(&workers->lock, flags); ++ spin_unlock(&workers->order_lock); + return 0; + } + ++static void put_worker(struct btrfs_worker_thread *worker) ++{ ++ if (atomic_dec_and_test(&worker->refs)) ++ kfree(worker); ++} ++ ++static int try_worker_shutdown(struct btrfs_worker_thread *worker) ++{ ++ int freeit = 0; ++ ++ spin_lock_irq(&worker->lock); ++ spin_lock(&worker->workers->lock); ++ if (worker->workers->num_workers > 1 && ++ worker->idle && ++ !worker->working && ++ !list_empty(&worker->worker_list) && ++ list_empty(&worker->prio_pending) && ++ list_empty(&worker->pending) && ++ atomic_read(&worker->num_pending) == 0) { ++ freeit = 1; ++ list_del_init(&worker->worker_list); ++ worker->workers->num_workers--; ++ } ++ spin_unlock(&worker->workers->lock); ++ spin_unlock_irq(&worker->lock); ++ ++ if (freeit) ++ put_worker(worker); ++ return freeit; ++} ++ ++static struct btrfs_work *get_next_work(struct btrfs_worker_thread *worker, ++ struct list_head *prio_head, ++ struct list_head *head) ++{ ++ struct btrfs_work *work = NULL; ++ struct list_head *cur = NULL; ++ ++ if(!list_empty(prio_head)) ++ cur = prio_head->next; ++ ++ smp_mb(); ++ if (!list_empty(&worker->prio_pending)) ++ goto refill; ++ ++ if (!list_empty(head)) ++ cur = head->next; ++ ++ if (cur) ++ goto out; ++ ++refill: ++ spin_lock_irq(&worker->lock); ++ list_splice_tail_init(&worker->prio_pending, prio_head); ++ list_splice_tail_init(&worker->pending, head); ++ ++ if (!list_empty(prio_head)) ++ cur = prio_head->next; ++ else if (!list_empty(head)) ++ cur = head->next; ++ spin_unlock_irq(&worker->lock); ++ ++ if (!cur) ++ goto out_fail; ++ ++out: ++ work = list_entry(cur, struct btrfs_work, list); ++ ++out_fail: ++ return work; ++} ++ + /* + * main loop for servicing work items + */ + static int worker_loop(void *arg) + { + struct btrfs_worker_thread *worker = arg; +- struct list_head *cur; ++ struct list_head head; ++ struct list_head prio_head; + struct btrfs_work *work; ++ ++ INIT_LIST_HEAD(&head); ++ INIT_LIST_HEAD(&prio_head); ++ + do { +- spin_lock_irq(&worker->lock); +-again_locked: ++again: + while (1) { +- if (!list_empty(&worker->prio_pending)) +- cur = worker->prio_pending.next; +- else if (!list_empty(&worker->pending)) +- cur = worker->pending.next; +- else ++ ++ ++ work = get_next_work(worker, &prio_head, &head); ++ if (!work) + break; + +- work = list_entry(cur, struct btrfs_work, list); + list_del(&work->list); + clear_bit(WORK_QUEUED_BIT, &work->flags); + + work->worker = worker; +- spin_unlock_irq(&worker->lock); + + work->func(work); + +@@ -175,9 +282,13 @@ again_locked: + */ + run_ordered_completions(worker->workers, work); + +- spin_lock_irq(&worker->lock); +- check_idle_worker(worker); ++ check_pending_worker_creates(worker); ++ + } ++ ++ spin_lock_irq(&worker->lock); ++ check_idle_worker(worker); ++ + if (freezing(current)) { + worker->working = 0; + spin_unlock_irq(&worker->lock); +@@ -216,8 +327,10 @@ again_locked: + spin_lock_irq(&worker->lock); + set_current_state(TASK_INTERRUPTIBLE); + if (!list_empty(&worker->pending) || +- !list_empty(&worker->prio_pending)) +- goto again_locked; ++ !list_empty(&worker->prio_pending)) { ++ spin_unlock_irq(&worker->lock); ++ goto again; ++ } + + /* + * this makes sure we get a wakeup when someone +@@ -226,8 +339,13 @@ again_locked: + worker->working = 0; + spin_unlock_irq(&worker->lock); + +- if (!kthread_should_stop()) +- schedule(); ++ if (!kthread_should_stop()) { ++ schedule_timeout(HZ * 120); ++ if (!worker->working && ++ try_worker_shutdown(worker)) { ++ return 0; ++ } ++ } + } + __set_current_state(TASK_RUNNING); + } +@@ -242,16 +360,30 @@ int btrfs_stop_workers(struct btrfs_workers *workers) + { + struct list_head *cur; + struct btrfs_worker_thread *worker; ++ int can_stop; + ++ spin_lock_irq(&workers->lock); + list_splice_init(&workers->idle_list, &workers->worker_list); + while (!list_empty(&workers->worker_list)) { + cur = workers->worker_list.next; + worker = list_entry(cur, struct btrfs_worker_thread, + worker_list); +- kthread_stop(worker->task); +- list_del(&worker->worker_list); +- kfree(worker); ++ ++ atomic_inc(&worker->refs); ++ workers->num_workers -= 1; ++ if (!list_empty(&worker->worker_list)) { ++ list_del_init(&worker->worker_list); ++ put_worker(worker); ++ can_stop = 1; ++ } else ++ can_stop = 0; ++ spin_unlock_irq(&workers->lock); ++ if (can_stop) ++ kthread_stop(worker->task); ++ spin_lock_irq(&workers->lock); ++ put_worker(worker); + } ++ spin_unlock_irq(&workers->lock); + return 0; + } + +@@ -266,10 +398,13 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max) + INIT_LIST_HEAD(&workers->order_list); + INIT_LIST_HEAD(&workers->prio_order_list); + spin_lock_init(&workers->lock); ++ spin_lock_init(&workers->order_lock); + workers->max_workers = max; + workers->idle_thresh = 32; + workers->name = name; + workers->ordered = 0; ++ workers->atomic_start_pending = 0; ++ workers->atomic_worker_start = 0; + } + + /* +@@ -293,7 +428,9 @@ int btrfs_start_workers(struct btrfs_workers *workers, int num_workers) + INIT_LIST_HEAD(&worker->prio_pending); + INIT_LIST_HEAD(&worker->worker_list); + spin_lock_init(&worker->lock); ++ + atomic_set(&worker->num_pending, 0); ++ atomic_set(&worker->refs, 1); + worker->workers = workers; + worker->task = kthread_run(worker_loop, worker, + "btrfs-%s-%d", workers->name, +@@ -303,7 +440,6 @@ int btrfs_start_workers(struct btrfs_workers *workers, int num_workers) + kfree(worker); + goto fail; + } +- + spin_lock_irq(&workers->lock); + list_add_tail(&worker->worker_list, &workers->idle_list); + worker->idle = 1; +@@ -350,7 +486,6 @@ static struct btrfs_worker_thread *next_worker(struct btrfs_workers *workers) + */ + next = workers->worker_list.next; + worker = list_entry(next, struct btrfs_worker_thread, worker_list); +- atomic_inc(&worker->num_pending); + worker->sequence++; + + if (worker->sequence % workers->idle_thresh == 0) +@@ -367,28 +502,18 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers) + { + struct btrfs_worker_thread *worker; + unsigned long flags; ++ struct list_head *fallback; + + again: + spin_lock_irqsave(&workers->lock, flags); + worker = next_worker(workers); +- spin_unlock_irqrestore(&workers->lock, flags); + + if (!worker) { +- spin_lock_irqsave(&workers->lock, flags); + if (workers->num_workers >= workers->max_workers) { +- struct list_head *fallback = NULL; +- /* +- * we have failed to find any workers, just +- * return the force one +- */ +- if (!list_empty(&workers->worker_list)) +- fallback = workers->worker_list.next; +- if (!list_empty(&workers->idle_list)) +- fallback = workers->idle_list.next; +- BUG_ON(!fallback); +- worker = list_entry(fallback, +- struct btrfs_worker_thread, worker_list); +- spin_unlock_irqrestore(&workers->lock, flags); ++ goto fallback; ++ } else if (workers->atomic_worker_start) { ++ workers->atomic_start_pending = 1; ++ goto fallback; + } else { + spin_unlock_irqrestore(&workers->lock, flags); + /* we're below the limit, start another worker */ +@@ -396,6 +521,28 @@ again: + goto again; + } + } ++ goto found; ++ ++fallback: ++ fallback = NULL; ++ /* ++ * we have failed to find any workers, just ++ * return the first one we can find. ++ */ ++ if (!list_empty(&workers->worker_list)) ++ fallback = workers->worker_list.next; ++ if (!list_empty(&workers->idle_list)) ++ fallback = workers->idle_list.next; ++ BUG_ON(!fallback); ++ worker = list_entry(fallback, ++ struct btrfs_worker_thread, worker_list); ++found: ++ /* ++ * this makes sure the worker doesn't exit before it is placed ++ * onto a busy/idle list ++ */ ++ atomic_inc(&worker->num_pending); ++ spin_unlock_irqrestore(&workers->lock, flags); + return worker; + } + +@@ -427,7 +574,7 @@ int btrfs_requeue_work(struct btrfs_work *work) + spin_lock(&worker->workers->lock); + worker->idle = 0; + list_move_tail(&worker->worker_list, +- &worker->workers->worker_list); ++ &worker->workers->worker_list); + spin_unlock(&worker->workers->lock); + } + if (!worker->working) { +@@ -435,9 +582,9 @@ int btrfs_requeue_work(struct btrfs_work *work) + worker->working = 1; + } + +- spin_unlock_irqrestore(&worker->lock, flags); + if (wake) + wake_up_process(worker->task); ++ spin_unlock_irqrestore(&worker->lock, flags); + out: + + return 0; +@@ -463,14 +610,18 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) + + worker = find_worker(workers); + if (workers->ordered) { +- spin_lock_irqsave(&workers->lock, flags); ++ /* ++ * you're not allowed to do ordered queues from an ++ * interrupt handler ++ */ ++ spin_lock(&workers->order_lock); + if (test_bit(WORK_HIGH_PRIO_BIT, &work->flags)) { + list_add_tail(&work->order_list, + &workers->prio_order_list); + } else { + list_add_tail(&work->order_list, &workers->order_list); + } +- spin_unlock_irqrestore(&workers->lock, flags); ++ spin_unlock(&workers->order_lock); + } else { + INIT_LIST_HEAD(&work->order_list); + } +@@ -481,7 +632,6 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) + list_add_tail(&work->list, &worker->prio_pending); + else + list_add_tail(&work->list, &worker->pending); +- atomic_inc(&worker->num_pending); + check_busy_worker(worker); + + /* +@@ -492,10 +642,10 @@ int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work) + wake = 1; + worker->working = 1; + +- spin_unlock_irqrestore(&worker->lock, flags); +- + if (wake) + wake_up_process(worker->task); ++ spin_unlock_irqrestore(&worker->lock, flags); ++ + out: + return 0; + } +diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h +index 1b511c1..fc089b9 100644 +--- a/fs/btrfs/async-thread.h ++++ b/fs/btrfs/async-thread.h +@@ -73,6 +73,15 @@ struct btrfs_workers { + /* force completions in the order they were queued */ + int ordered; + ++ /* more workers required, but in an interrupt handler */ ++ int atomic_start_pending; ++ ++ /* ++ * are we allowed to sleep while starting workers or are we required ++ * to start them at a later time? ++ */ ++ int atomic_worker_start; ++ + /* list with all the work threads. The workers on the idle thread + * may be actively servicing jobs, but they haven't yet hit the + * idle thresh limit above. +@@ -90,6 +99,9 @@ struct btrfs_workers { + /* lock for finding the next worker thread to queue on */ + spinlock_t lock; + ++ /* lock for the ordered lists */ ++ spinlock_t order_lock; ++ + /* extra name for this worker, used for current->name */ + char *name; + }; +diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h +index ea1ea0a..82ee56b 100644 +--- a/fs/btrfs/btrfs_inode.h ++++ b/fs/btrfs/btrfs_inode.h +@@ -138,6 +138,7 @@ struct btrfs_inode { + * of these. + */ + unsigned ordered_data_close:1; ++ unsigned dummy_inode:1; + + struct inode vfs_inode; + }; +diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c +index 9d8ba4d..a11a320 100644 +--- a/fs/btrfs/compression.c ++++ b/fs/btrfs/compression.c +@@ -506,10 +506,10 @@ static noinline int add_ra_bio_pages(struct inode *inode, + */ + set_page_extent_mapped(page); + lock_extent(tree, last_offset, end, GFP_NOFS); +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, last_offset, + PAGE_CACHE_SIZE); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + if (!em || last_offset < em->start || + (last_offset + PAGE_CACHE_SIZE > extent_map_end(em)) || +@@ -593,11 +593,11 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, + em_tree = &BTRFS_I(inode)->extent_tree; + + /* we need the actual starting offset of this extent in the file */ +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, + page_offset(bio->bi_io_vec->bv_page), + PAGE_CACHE_SIZE); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + compressed_len = em->block_len; + cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 3fdcc05..ec96f3a 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -2853,6 +2853,12 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, + int split; + int num_doubles = 0; + ++ l = path->nodes[0]; ++ slot = path->slots[0]; ++ if (extend && data_size + btrfs_item_size_nr(l, slot) + ++ sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root)) ++ return -EOVERFLOW; ++ + /* first try to make some room by pushing left and right */ + if (data_size && ins_key->type != BTRFS_DIR_ITEM_KEY) { + wret = push_leaf_right(trans, root, path, data_size, 0); +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index 837435c..80599b4 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -114,6 +114,10 @@ struct btrfs_ordered_sum; + */ + #define BTRFS_DEV_ITEMS_OBJECTID 1ULL + ++#define BTRFS_BTREE_INODE_OBJECTID 1 ++ ++#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2 ++ + /* + * we can actually store much bigger names, but lets not confuse the rest + * of linux +@@ -670,6 +674,7 @@ struct btrfs_space_info { + u64 bytes_reserved; /* total bytes the allocator has reserved for + current allocations */ + u64 bytes_readonly; /* total bytes that are read only */ ++ u64 bytes_super; /* total bytes reserved for the super blocks */ + + /* delalloc accounting */ + u64 bytes_delalloc; /* number of bytes reserved for allocation, +@@ -726,6 +731,15 @@ enum btrfs_caching_type { + BTRFS_CACHE_FINISHED = 2, + }; + ++struct btrfs_caching_control { ++ struct list_head list; ++ struct mutex mutex; ++ wait_queue_head_t wait; ++ struct btrfs_block_group_cache *block_group; ++ u64 progress; ++ atomic_t count; ++}; ++ + struct btrfs_block_group_cache { + struct btrfs_key key; + struct btrfs_block_group_item item; +@@ -733,6 +747,7 @@ struct btrfs_block_group_cache { + spinlock_t lock; + u64 pinned; + u64 reserved; ++ u64 bytes_super; + u64 flags; + u64 sectorsize; + int extents_thresh; +@@ -742,8 +757,9 @@ struct btrfs_block_group_cache { + int dirty; + + /* cache tracking stuff */ +- wait_queue_head_t caching_q; + int cached; ++ struct btrfs_caching_control *caching_ctl; ++ u64 last_byte_to_unpin; + + struct btrfs_space_info *space_info; + +@@ -782,13 +798,16 @@ struct btrfs_fs_info { + + /* the log root tree is a directory of all the other log roots */ + struct btrfs_root *log_root_tree; ++ ++ spinlock_t fs_roots_radix_lock; + struct radix_tree_root fs_roots_radix; + + /* block group cache stuff */ + spinlock_t block_group_cache_lock; + struct rb_root block_group_cache_tree; + +- struct extent_io_tree pinned_extents; ++ struct extent_io_tree freed_extents[2]; ++ struct extent_io_tree *pinned_extents; + + /* logical->physical extent mapping */ + struct btrfs_mapping_tree mapping_tree; +@@ -822,11 +841,7 @@ struct btrfs_fs_info { + struct mutex transaction_kthread_mutex; + struct mutex cleaner_mutex; + struct mutex chunk_mutex; +- struct mutex drop_mutex; + struct mutex volume_mutex; +- struct mutex tree_reloc_mutex; +- struct rw_semaphore extent_commit_sem; +- + /* + * this protects the ordered operations list only while we are + * processing all of the entries on it. This way we make +@@ -835,10 +850,16 @@ struct btrfs_fs_info { + * before jumping into the main commit. + */ + struct mutex ordered_operations_mutex; ++ struct rw_semaphore extent_commit_sem; ++ ++ struct rw_semaphore subvol_sem; ++ ++ struct srcu_struct subvol_srcu; + + struct list_head trans_list; + struct list_head hashers; + struct list_head dead_roots; ++ struct list_head caching_block_groups; + + atomic_t nr_async_submits; + atomic_t async_submit_draining; +@@ -996,10 +1017,12 @@ struct btrfs_root { + u32 stripesize; + + u32 type; +- u64 highest_inode; +- u64 last_inode_alloc; ++ ++ u64 highest_objectid; + int ref_cows; + int track_dirty; ++ int in_radix; ++ + u64 defrag_trans_start; + struct btrfs_key defrag_progress; + struct btrfs_key defrag_max; +@@ -1920,8 +1943,8 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache); + int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, + struct btrfs_root *root, unsigned long count); + int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); +-int btrfs_update_pinned_extents(struct btrfs_root *root, +- u64 bytenr, u64 num, int pin); ++int btrfs_pin_extent(struct btrfs_root *root, ++ u64 bytenr, u64 num, int reserved); + int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct extent_buffer *leaf); + int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, +@@ -1971,9 +1994,10 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, + u64 root_objectid, u64 owner, u64 offset); + + int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); ++int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root); + int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct extent_io_tree *unpin); ++ struct btrfs_root *root); + int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, +@@ -1984,6 +2008,7 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, + int btrfs_extent_readonly(struct btrfs_root *root, u64 bytenr); + int btrfs_free_block_groups(struct btrfs_fs_info *info); + int btrfs_read_block_groups(struct btrfs_root *root); ++int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr); + int btrfs_make_block_group(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 bytes_used, + u64 type, u64 chunk_objectid, u64 chunk_offset, +@@ -2006,7 +2031,6 @@ void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, + u64 bytes); + void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, + u64 bytes); +-void btrfs_free_pinned_extents(struct btrfs_fs_info *info); + /* ctree.c */ + int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, + int level, int *slot); +@@ -2100,12 +2124,15 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, + struct extent_buffer *parent); + /* root-item.c */ + int btrfs_find_root_ref(struct btrfs_root *tree_root, +- struct btrfs_path *path, +- u64 root_id, u64 ref_id); ++ struct btrfs_path *path, ++ u64 root_id, u64 ref_id); + int btrfs_add_root_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *tree_root, +- u64 root_id, u8 type, u64 ref_id, +- u64 dirid, u64 sequence, ++ u64 root_id, u64 ref_id, u64 dirid, u64 sequence, ++ const char *name, int name_len); ++int btrfs_del_root_ref(struct btrfs_trans_handle *trans, ++ struct btrfs_root *tree_root, ++ u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, + const char *name, int name_len); + int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_key *key); +@@ -2120,6 +2147,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct + int btrfs_search_root(struct btrfs_root *root, u64 search_start, + u64 *found_objectid); + int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); ++int btrfs_find_orphan_roots(struct btrfs_root *tree_root); + int btrfs_set_root_node(struct btrfs_root_item *item, + struct extent_buffer *node); + /* dir-item.c */ +@@ -2138,6 +2166,10 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, + struct btrfs_path *path, u64 dir, + u64 objectid, const char *name, int name_len, + int mod); ++struct btrfs_dir_item * ++btrfs_search_dir_index_item(struct btrfs_root *root, ++ struct btrfs_path *path, u64 dirid, ++ const char *name, int name_len); + struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, + struct btrfs_path *path, + const char *name, int name_len); +@@ -2160,6 +2192,7 @@ int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 offset); + int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, u64 offset); ++int btrfs_find_orphan_item(struct btrfs_root *root, u64 offset); + + /* inode-map.c */ + int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, +@@ -2232,6 +2265,10 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans, + int btrfs_add_link(struct btrfs_trans_handle *trans, + struct inode *parent_inode, struct inode *inode, + const char *name, int name_len, int add_backref, u64 index); ++int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct inode *dir, u64 objectid, ++ const char *name, int name_len); + int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode, u64 new_size, +@@ -2242,7 +2279,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end); + int btrfs_writepages(struct address_space *mapping, + struct writeback_control *wbc); + int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, +- struct btrfs_root *new_root, struct dentry *dentry, ++ struct btrfs_root *new_root, + u64 new_dirid, u64 alloc_hint); + int btrfs_merge_bio_hook(struct page *page, unsigned long offset, + size_t size, struct bio *bio, unsigned long bio_flags); +@@ -2258,6 +2295,7 @@ int btrfs_write_inode(struct inode *inode, int wait); + void btrfs_dirty_inode(struct inode *inode); + struct inode *btrfs_alloc_inode(struct super_block *sb); + void btrfs_destroy_inode(struct inode *inode); ++void btrfs_drop_inode(struct inode *inode); + int btrfs_init_cachep(void); + void btrfs_destroy_cachep(void); + long btrfs_ioctl_trans_end(struct file *file); +@@ -2275,6 +2313,8 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode); + int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode); + void btrfs_orphan_cleanup(struct btrfs_root *root); + int btrfs_cont_expand(struct inode *inode, loff_t size); ++int btrfs_invalidate_inodes(struct btrfs_root *root); ++extern struct dentry_operations btrfs_dentry_operations; + + /* ioctl.c */ + long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +@@ -2290,7 +2330,7 @@ extern struct file_operations btrfs_file_operations; + int btrfs_drop_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, + u64 start, u64 end, u64 locked_end, +- u64 inline_limit, u64 *hint_block); ++ u64 inline_limit, u64 *hint_block, int drop_cache); + int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct inode *inode, u64 start, u64 end); +diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c +index 1d70236..f3a6075 100644 +--- a/fs/btrfs/dir-item.c ++++ b/fs/btrfs/dir-item.c +@@ -281,6 +281,53 @@ btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans, + return btrfs_match_dir_item_name(root, path, name, name_len); + } + ++struct btrfs_dir_item * ++btrfs_search_dir_index_item(struct btrfs_root *root, ++ struct btrfs_path *path, u64 dirid, ++ const char *name, int name_len) ++{ ++ struct extent_buffer *leaf; ++ struct btrfs_dir_item *di; ++ struct btrfs_key key; ++ u32 nritems; ++ int ret; ++ ++ key.objectid = dirid; ++ key.type = BTRFS_DIR_INDEX_KEY; ++ key.offset = 0; ++ ++ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ leaf = path->nodes[0]; ++ nritems = btrfs_header_nritems(leaf); ++ ++ while (1) { ++ if (path->slots[0] >= nritems) { ++ ret = btrfs_next_leaf(root, path); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ if (ret > 0) ++ break; ++ leaf = path->nodes[0]; ++ nritems = btrfs_header_nritems(leaf); ++ continue; ++ } ++ ++ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); ++ if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY) ++ break; ++ ++ di = btrfs_match_dir_item_name(root, path, name, name_len); ++ if (di) ++ return di; ++ ++ path->slots[0]++; ++ } ++ return NULL; ++} ++ + struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, u64 dir, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c -index e83be2e..6c41731 100644 +index e83be2e..644e796 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c -@@ -772,7 +772,7 @@ static void btree_invalidatepage(struct page *page, unsigned long offset) +@@ -41,6 +41,7 @@ + + static struct extent_io_ops btree_extent_io_ops; + static void end_workqueue_fn(struct btrfs_work *work); ++static void free_fs_root(struct btrfs_root *root); + + static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); + +@@ -123,15 +124,15 @@ static struct extent_map *btree_get_extent(struct inode *inode, + struct extent_map *em; + int ret; + +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, start, len); + if (em) { + em->bdev = + BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + goto out; + } +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + em = alloc_extent_map(GFP_NOFS); + if (!em) { +@@ -144,7 +145,7 @@ static struct extent_map *btree_get_extent(struct inode *inode, + em->block_start = 0; + em->bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; + +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); + if (ret == -EEXIST) { + u64 failed_start = em->start; +@@ -163,7 +164,7 @@ static struct extent_map *btree_get_extent(struct inode *inode, + free_extent_map(em); + em = NULL; + } +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + + if (ret) + em = ERR_PTR(ret); +@@ -772,7 +773,7 @@ static void btree_invalidatepage(struct page *page, unsigned long offset) } } @@ -1605647,7 +1674558,212 @@ index e83be2e..6c41731 100644 .readpage = btree_readpage, .writepage = btree_writepage, .writepages = btree_writepages, -@@ -1352,6 +1352,7 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) +@@ -895,8 +896,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, + root->fs_info = fs_info; + root->objectid = objectid; + root->last_trans = 0; +- root->highest_inode = 0; +- root->last_inode_alloc = 0; ++ root->highest_objectid = 0; + root->name = NULL; + root->in_sysfs = 0; + root->inode_tree.rb_node = NULL; +@@ -952,14 +952,16 @@ static int find_and_setup_root(struct btrfs_root *tree_root, + root, fs_info, objectid); + ret = btrfs_find_last_root(tree_root, objectid, + &root->root_item, &root->root_key); ++ if (ret > 0) ++ return -ENOENT; + BUG_ON(ret); + + generation = btrfs_root_generation(&root->root_item); + blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); + root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), + blocksize, generation); +- root->commit_root = btrfs_root_node(root); + BUG_ON(!root->node); ++ root->commit_root = btrfs_root_node(root); + return 0; + } + +@@ -1095,7 +1097,6 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, + struct btrfs_fs_info *fs_info = tree_root->fs_info; + struct btrfs_path *path; + struct extent_buffer *l; +- u64 highest_inode; + u64 generation; + u32 blocksize; + int ret = 0; +@@ -1110,7 +1111,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, + kfree(root); + return ERR_PTR(ret); + } +- goto insert; ++ goto out; + } + + __setup_root(tree_root->nodesize, tree_root->leafsize, +@@ -1120,39 +1121,30 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, + path = btrfs_alloc_path(); + BUG_ON(!path); + ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); +- if (ret != 0) { +- if (ret > 0) +- ret = -ENOENT; +- goto out; ++ if (ret == 0) { ++ l = path->nodes[0]; ++ read_extent_buffer(l, &root->root_item, ++ btrfs_item_ptr_offset(l, path->slots[0]), ++ sizeof(root->root_item)); ++ memcpy(&root->root_key, location, sizeof(*location)); + } +- l = path->nodes[0]; +- read_extent_buffer(l, &root->root_item, +- btrfs_item_ptr_offset(l, path->slots[0]), +- sizeof(root->root_item)); +- memcpy(&root->root_key, location, sizeof(*location)); +- ret = 0; +-out: +- btrfs_release_path(root, path); + btrfs_free_path(path); + if (ret) { +- kfree(root); ++ if (ret > 0) ++ ret = -ENOENT; + return ERR_PTR(ret); + } ++ + generation = btrfs_root_generation(&root->root_item); + blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); + root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), + blocksize, generation); + root->commit_root = btrfs_root_node(root); + BUG_ON(!root->node); +-insert: +- if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { ++out: ++ if (location->objectid != BTRFS_TREE_LOG_OBJECTID) + root->ref_cows = 1; +- ret = btrfs_find_highest_inode(root, &highest_inode); +- if (ret == 0) { +- root->highest_inode = highest_inode; +- root->last_inode_alloc = highest_inode; +- } +- } ++ + return root; + } + +@@ -1187,39 +1179,66 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, + return fs_info->dev_root; + if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) + return fs_info->csum_root; +- ++again: ++ spin_lock(&fs_info->fs_roots_radix_lock); + root = radix_tree_lookup(&fs_info->fs_roots_radix, + (unsigned long)location->objectid); ++ spin_unlock(&fs_info->fs_roots_radix_lock); + if (root) + return root; + ++ ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid); ++ if (ret == 0) ++ ret = -ENOENT; ++ if (ret < 0) ++ return ERR_PTR(ret); ++ + root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); + if (IS_ERR(root)) + return root; + ++ WARN_ON(btrfs_root_refs(&root->root_item) == 0); + set_anon_super(&root->anon_super, NULL); + ++ ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); ++ if (ret) ++ goto fail; ++ ++ spin_lock(&fs_info->fs_roots_radix_lock); + ret = radix_tree_insert(&fs_info->fs_roots_radix, + (unsigned long)root->root_key.objectid, + root); ++ if (ret == 0) ++ root->in_radix = 1; ++ spin_unlock(&fs_info->fs_roots_radix_lock); ++ radix_tree_preload_end(); + if (ret) { +- free_extent_buffer(root->node); +- kfree(root); +- return ERR_PTR(ret); ++ if (ret == -EEXIST) { ++ free_fs_root(root); ++ goto again; ++ } ++ goto fail; + } +- if (!(fs_info->sb->s_flags & MS_RDONLY)) { +- ret = btrfs_find_dead_roots(fs_info->tree_root, +- root->root_key.objectid); +- BUG_ON(ret); ++ ++ ret = btrfs_find_dead_roots(fs_info->tree_root, ++ root->root_key.objectid); ++ WARN_ON(ret); ++ ++ if (!(fs_info->sb->s_flags & MS_RDONLY)) + btrfs_orphan_cleanup(root); +- } ++ + return root; ++fail: ++ free_fs_root(root); ++ return ERR_PTR(ret); + } + + struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, + struct btrfs_key *location, + const char *name, int namelen) + { ++ return btrfs_read_fs_root_no_name(fs_info, location); ++#if 0 + struct btrfs_root *root; + int ret; + +@@ -1236,7 +1255,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, + kfree(root); + return ERR_PTR(ret); + } +-#if 0 ++ + ret = btrfs_sysfs_add_root(root); + if (ret) { + free_extent_buffer(root->node); +@@ -1244,9 +1263,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, + kfree(root); + return ERR_PTR(ret); + } +-#endif + root->in_sysfs = 1; + return root; ++#endif + } + + static int btrfs_congested_fn(void *congested_data, int bdi_bits) +@@ -1325,9 +1344,9 @@ static void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) + offset = page_offset(page); + + em_tree = &BTRFS_I(inode)->extent_tree; +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + if (!em) { + __unplug_io_fn(bdi, page); + return; +@@ -1352,6 +1371,7 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) { int err; @@ -1605655,19 +1674771,847 @@ index e83be2e..6c41731 100644 bdi->capabilities = BDI_CAP_MAP_COPY; err = bdi_init(bdi); if (err) -@@ -1599,6 +1600,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, +@@ -1359,8 +1379,10 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) + + err = bdi_register(bdi, NULL, "btrfs-%d", + atomic_inc_return(&btrfs_bdi_num)); +- if (err) ++ if (err) { ++ bdi_destroy(bdi); + return err; ++ } + + bdi->ra_pages = default_backing_dev_info.ra_pages; + bdi->unplug_io_fn = btrfs_unplug_io_fn; +@@ -1450,9 +1472,12 @@ static int cleaner_kthread(void *arg) + break; + + vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); +- mutex_lock(&root->fs_info->cleaner_mutex); +- btrfs_clean_old_snapshots(root); +- mutex_unlock(&root->fs_info->cleaner_mutex); ++ ++ if (!(root->fs_info->sb->s_flags & MS_RDONLY) && ++ mutex_trylock(&root->fs_info->cleaner_mutex)) { ++ btrfs_clean_old_snapshots(root); ++ mutex_unlock(&root->fs_info->cleaner_mutex); ++ } + + if (freezing(current)) { + refrigerator(); +@@ -1557,15 +1582,36 @@ struct btrfs_root *open_ctree(struct super_block *sb, + err = -ENOMEM; + goto fail; + } +- INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); ++ ++ ret = init_srcu_struct(&fs_info->subvol_srcu); ++ if (ret) { ++ err = ret; ++ goto fail; ++ } ++ ++ ret = setup_bdi(fs_info, &fs_info->bdi); ++ if (ret) { ++ err = ret; ++ goto fail_srcu; ++ } ++ ++ fs_info->btree_inode = new_inode(sb); ++ if (!fs_info->btree_inode) { ++ err = -ENOMEM; ++ goto fail_bdi; ++ } ++ ++ INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); + INIT_LIST_HEAD(&fs_info->trans_list); + INIT_LIST_HEAD(&fs_info->dead_roots); + INIT_LIST_HEAD(&fs_info->hashers); + INIT_LIST_HEAD(&fs_info->delalloc_inodes); + INIT_LIST_HEAD(&fs_info->ordered_operations); ++ INIT_LIST_HEAD(&fs_info->caching_block_groups); + spin_lock_init(&fs_info->delalloc_lock); + spin_lock_init(&fs_info->new_trans_lock); + spin_lock_init(&fs_info->ref_cache_lock); ++ spin_lock_init(&fs_info->fs_roots_radix_lock); + + init_completion(&fs_info->kobj_unregister); + fs_info->tree_root = tree_root; +@@ -1584,11 +1630,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, + fs_info->sb = sb; + fs_info->max_extent = (u64)-1; + fs_info->max_inline = 8192 * 1024; +- if (setup_bdi(fs_info, &fs_info->bdi)) +- goto fail_bdi; +- fs_info->btree_inode = new_inode(sb); +- fs_info->btree_inode->i_ino = 1; +- fs_info->btree_inode->i_nlink = 1; + fs_info->metadata_ratio = 8; + + fs_info->thread_pool_size = min_t(unsigned long, +@@ -1599,7 +1640,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, sb->s_blocksize = 4096; sb->s_blocksize_bits = blksize_bits(4096); + sb->s_bdi = &fs_info->bdi; ++ fs_info->btree_inode->i_ino = BTRFS_BTREE_INODE_OBJECTID; ++ fs_info->btree_inode->i_nlink = 1; /* * we set the i_size on the btree inode to the max possible int. + * the real end of the address space is determined by all of +@@ -1618,28 +1662,32 @@ struct btrfs_root *open_ctree(struct super_block *sb, + + BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; + ++ BTRFS_I(fs_info->btree_inode)->root = tree_root; ++ memset(&BTRFS_I(fs_info->btree_inode)->location, 0, ++ sizeof(struct btrfs_key)); ++ BTRFS_I(fs_info->btree_inode)->dummy_inode = 1; ++ insert_inode_hash(fs_info->btree_inode); ++ + spin_lock_init(&fs_info->block_group_cache_lock); + fs_info->block_group_cache_tree.rb_node = NULL; + +- extent_io_tree_init(&fs_info->pinned_extents, ++ extent_io_tree_init(&fs_info->freed_extents[0], + fs_info->btree_inode->i_mapping, GFP_NOFS); ++ extent_io_tree_init(&fs_info->freed_extents[1], ++ fs_info->btree_inode->i_mapping, GFP_NOFS); ++ fs_info->pinned_extents = &fs_info->freed_extents[0]; + fs_info->do_barriers = 1; + +- BTRFS_I(fs_info->btree_inode)->root = tree_root; +- memset(&BTRFS_I(fs_info->btree_inode)->location, 0, +- sizeof(struct btrfs_key)); +- insert_inode_hash(fs_info->btree_inode); + + mutex_init(&fs_info->trans_mutex); + mutex_init(&fs_info->ordered_operations_mutex); + mutex_init(&fs_info->tree_log_mutex); +- mutex_init(&fs_info->drop_mutex); + mutex_init(&fs_info->chunk_mutex); + mutex_init(&fs_info->transaction_kthread_mutex); + mutex_init(&fs_info->cleaner_mutex); + mutex_init(&fs_info->volume_mutex); +- mutex_init(&fs_info->tree_reloc_mutex); + init_rwsem(&fs_info->extent_commit_sem); ++ init_rwsem(&fs_info->subvol_sem); + + btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); + btrfs_init_free_cluster(&fs_info->data_alloc_cluster); +@@ -1698,7 +1746,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, + err = -EINVAL; + goto fail_iput; + } +- ++printk("thread pool is %d\n", fs_info->thread_pool_size); + /* + * we need to start all the end_io workers up front because the + * queue work function gets called at interrupt time, and so it +@@ -1743,20 +1791,22 @@ struct btrfs_root *open_ctree(struct super_block *sb, + fs_info->endio_workers.idle_thresh = 4; + fs_info->endio_meta_workers.idle_thresh = 4; + +- fs_info->endio_write_workers.idle_thresh = 64; +- fs_info->endio_meta_write_workers.idle_thresh = 64; ++ fs_info->endio_write_workers.idle_thresh = 2; ++ fs_info->endio_meta_write_workers.idle_thresh = 2; ++ ++ fs_info->endio_workers.atomic_worker_start = 1; ++ fs_info->endio_meta_workers.atomic_worker_start = 1; ++ fs_info->endio_write_workers.atomic_worker_start = 1; ++ fs_info->endio_meta_write_workers.atomic_worker_start = 1; + + btrfs_start_workers(&fs_info->workers, 1); + btrfs_start_workers(&fs_info->submit_workers, 1); + btrfs_start_workers(&fs_info->delalloc_workers, 1); + btrfs_start_workers(&fs_info->fixup_workers, 1); +- btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); +- btrfs_start_workers(&fs_info->endio_meta_workers, +- fs_info->thread_pool_size); +- btrfs_start_workers(&fs_info->endio_meta_write_workers, +- fs_info->thread_pool_size); +- btrfs_start_workers(&fs_info->endio_write_workers, +- fs_info->thread_pool_size); ++ btrfs_start_workers(&fs_info->endio_workers, 1); ++ btrfs_start_workers(&fs_info->endio_meta_workers, 1); ++ btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); ++ btrfs_start_workers(&fs_info->endio_write_workers, 1); + + fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); + fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, +@@ -1916,6 +1966,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, + } + } + ++ ret = btrfs_find_orphan_roots(tree_root); ++ BUG_ON(ret); ++ + if (!(sb->s_flags & MS_RDONLY)) { + ret = btrfs_recover_relocation(tree_root); + BUG_ON(ret); +@@ -1975,6 +2028,8 @@ fail_iput: + btrfs_mapping_tree_free(&fs_info->mapping_tree); + fail_bdi: + bdi_destroy(&fs_info->bdi); ++fail_srcu: ++ cleanup_srcu_struct(&fs_info->subvol_srcu); + fail: + kfree(extent_root); + kfree(tree_root); +@@ -2234,20 +2289,29 @@ int write_ctree_super(struct btrfs_trans_handle *trans, + + int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) + { +- WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); ++ spin_lock(&fs_info->fs_roots_radix_lock); + radix_tree_delete(&fs_info->fs_roots_radix, + (unsigned long)root->root_key.objectid); ++ spin_unlock(&fs_info->fs_roots_radix_lock); ++ ++ if (btrfs_root_refs(&root->root_item) == 0) ++ synchronize_srcu(&fs_info->subvol_srcu); ++ ++ free_fs_root(root); ++ return 0; ++} ++ ++static void free_fs_root(struct btrfs_root *root) ++{ ++ WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); + if (root->anon_super.s_dev) { + down_write(&root->anon_super.s_umount); + kill_anon_super(&root->anon_super); + } +- if (root->node) +- free_extent_buffer(root->node); +- if (root->commit_root) +- free_extent_buffer(root->commit_root); ++ free_extent_buffer(root->node); ++ free_extent_buffer(root->commit_root); + kfree(root->name); + kfree(root); +- return 0; + } + + static int del_fs_roots(struct btrfs_fs_info *fs_info) +@@ -2256,6 +2320,20 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info) + struct btrfs_root *gang[8]; + int i; + ++ while (!list_empty(&fs_info->dead_roots)) { ++ gang[0] = list_entry(fs_info->dead_roots.next, ++ struct btrfs_root, root_list); ++ list_del(&gang[0]->root_list); ++ ++ if (gang[0]->in_radix) { ++ btrfs_free_fs_root(fs_info, gang[0]); ++ } else { ++ free_extent_buffer(gang[0]->node); ++ free_extent_buffer(gang[0]->commit_root); ++ kfree(gang[0]); ++ } ++ } ++ + while (1) { + ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, + (void **)gang, 0, +@@ -2285,9 +2363,6 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) + root_objectid = gang[ret - 1]->root_key.objectid + 1; + for (i = 0; i < ret; i++) { + root_objectid = gang[i]->root_key.objectid; +- ret = btrfs_find_dead_roots(fs_info->tree_root, +- root_objectid); +- BUG_ON(ret); + btrfs_orphan_cleanup(gang[i]); + } + root_objectid++; +@@ -2357,7 +2432,6 @@ int close_ctree(struct btrfs_root *root) + free_extent_buffer(root->fs_info->csum_root->commit_root); + + btrfs_free_block_groups(root->fs_info); +- btrfs_free_pinned_extents(root->fs_info); + + del_fs_roots(fs_info); + +@@ -2376,6 +2450,7 @@ int close_ctree(struct btrfs_root *root) + btrfs_mapping_tree_free(&fs_info->mapping_tree); + + bdi_destroy(&fs_info->bdi); ++ cleanup_srcu_struct(&fs_info->subvol_srcu); + + kfree(fs_info->extent_root); + kfree(fs_info->tree_root); +diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c +index 9596b40..ba5c3fd 100644 +--- a/fs/btrfs/export.c ++++ b/fs/btrfs/export.c +@@ -28,7 +28,7 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, + len = BTRFS_FID_SIZE_NON_CONNECTABLE; + type = FILEID_BTRFS_WITHOUT_PARENT; + +- fid->objectid = BTRFS_I(inode)->location.objectid; ++ fid->objectid = inode->i_ino; + fid->root_objectid = BTRFS_I(inode)->root->objectid; + fid->gen = inode->i_generation; + +@@ -60,34 +60,61 @@ static int btrfs_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, + } + + static struct dentry *btrfs_get_dentry(struct super_block *sb, u64 objectid, +- u64 root_objectid, u32 generation) ++ u64 root_objectid, u32 generation, ++ int check_generation) + { ++ struct btrfs_fs_info *fs_info = btrfs_sb(sb)->fs_info; + struct btrfs_root *root; ++ struct dentry *dentry; + struct inode *inode; + struct btrfs_key key; ++ int index; ++ int err = 0; ++ ++ if (objectid < BTRFS_FIRST_FREE_OBJECTID) ++ return ERR_PTR(-ESTALE); + + key.objectid = root_objectid; + btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + key.offset = (u64)-1; + +- root = btrfs_read_fs_root_no_name(btrfs_sb(sb)->fs_info, &key); +- if (IS_ERR(root)) +- return ERR_CAST(root); ++ index = srcu_read_lock(&fs_info->subvol_srcu); ++ ++ root = btrfs_read_fs_root_no_name(fs_info, &key); ++ if (IS_ERR(root)) { ++ err = PTR_ERR(root); ++ goto fail; ++ } ++ ++ if (btrfs_root_refs(&root->root_item) == 0) { ++ err = -ENOENT; ++ goto fail; ++ } + + key.objectid = objectid; + btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); + key.offset = 0; + + inode = btrfs_iget(sb, &key, root); +- if (IS_ERR(inode)) +- return (void *)inode; ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ goto fail; ++ } ++ ++ srcu_read_unlock(&fs_info->subvol_srcu, index); + +- if (generation != inode->i_generation) { ++ if (check_generation && generation != inode->i_generation) { + iput(inode); + return ERR_PTR(-ESTALE); + } + +- return d_obtain_alias(inode); ++ dentry = d_obtain_alias(inode); ++ if (!IS_ERR(dentry)) ++ dentry->d_op = &btrfs_dentry_operations; ++ return dentry; ++fail: ++ srcu_read_unlock(&fs_info->subvol_srcu, index); ++ return ERR_PTR(err); + } + + static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh, +@@ -111,7 +138,7 @@ static struct dentry *btrfs_fh_to_parent(struct super_block *sb, struct fid *fh, + objectid = fid->parent_objectid; + generation = fid->parent_gen; + +- return btrfs_get_dentry(sb, objectid, root_objectid, generation); ++ return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1); + } + + static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, +@@ -133,66 +160,76 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, + root_objectid = fid->root_objectid; + generation = fid->gen; + +- return btrfs_get_dentry(sb, objectid, root_objectid, generation); ++ return btrfs_get_dentry(sb, objectid, root_objectid, generation, 1); + } + + static struct dentry *btrfs_get_parent(struct dentry *child) + { + struct inode *dir = child->d_inode; ++ static struct dentry *dentry; + struct btrfs_root *root = BTRFS_I(dir)->root; +- struct btrfs_key key; + struct btrfs_path *path; + struct extent_buffer *leaf; +- int slot; +- u64 objectid; ++ struct btrfs_root_ref *ref; ++ struct btrfs_key key; ++ struct btrfs_key found_key; + int ret; + + path = btrfs_alloc_path(); + +- key.objectid = dir->i_ino; +- btrfs_set_key_type(&key, BTRFS_INODE_REF_KEY); +- key.offset = (u64)-1; ++ if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) { ++ key.objectid = root->root_key.objectid; ++ key.type = BTRFS_ROOT_BACKREF_KEY; ++ key.offset = (u64)-1; ++ root = root->fs_info->tree_root; ++ } else { ++ key.objectid = dir->i_ino; ++ key.type = BTRFS_INODE_REF_KEY; ++ key.offset = (u64)-1; ++ } + + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); +- if (ret < 0) { +- /* Error */ +- btrfs_free_path(path); +- return ERR_PTR(ret); ++ if (ret < 0) ++ goto fail; ++ ++ BUG_ON(ret == 0); ++ if (path->slots[0] == 0) { ++ ret = -ENOENT; ++ goto fail; + } ++ ++ path->slots[0]--; + leaf = path->nodes[0]; +- slot = path->slots[0]; +- if (ret) { +- /* btrfs_search_slot() returns the slot where we'd want to +- insert a backref for parent inode #0xFFFFFFFFFFFFFFFF. +- The _real_ backref, telling us what the parent inode +- _actually_ is, will be in the slot _before_ the one +- that btrfs_search_slot() returns. */ +- if (!slot) { +- /* Unless there is _no_ key in the tree before... */ +- btrfs_free_path(path); +- return ERR_PTR(-EIO); +- } +- slot--; ++ ++ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); ++ if (found_key.objectid != key.objectid || found_key.type != key.type) { ++ ret = -ENOENT; ++ goto fail; + } + +- btrfs_item_key_to_cpu(leaf, &key, slot); ++ if (found_key.type == BTRFS_ROOT_BACKREF_KEY) { ++ ref = btrfs_item_ptr(leaf, path->slots[0], ++ struct btrfs_root_ref); ++ key.objectid = btrfs_root_ref_dirid(leaf, ref); ++ } else { ++ key.objectid = found_key.offset; ++ } + btrfs_free_path(path); + +- if (key.objectid != dir->i_ino || key.type != BTRFS_INODE_REF_KEY) +- return ERR_PTR(-EINVAL); +- +- objectid = key.offset; +- +- /* If we are already at the root of a subvol, return the real root */ +- if (objectid == dir->i_ino) +- return dget(dir->i_sb->s_root); ++ if (found_key.type == BTRFS_ROOT_BACKREF_KEY) { ++ return btrfs_get_dentry(root->fs_info->sb, key.objectid, ++ found_key.offset, 0, 0); ++ } + +- /* Build a new key for the inode item */ +- key.objectid = objectid; +- btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); ++ key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; +- +- return d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); ++ dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root)); ++ if (!IS_ERR(dentry)) ++ dentry->d_op = &btrfs_dentry_operations; ++ return dentry; ++fail: ++ btrfs_free_path(path); ++ return ERR_PTR(ret); + } + + const struct export_operations btrfs_export_ops = { diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c -index 72a2b9c..535f85b 100644 +index 72a2b9c..993f93f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c -@@ -1511,7 +1511,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, +@@ -32,12 +32,12 @@ + #include "locking.h" + #include "free-space-cache.h" + +-static int update_reserved_extents(struct btrfs_root *root, +- u64 bytenr, u64 num, int reserve); + static int update_block_group(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, int alloc, + int mark_free); ++static int update_reserved_extents(struct btrfs_block_group_cache *cache, ++ u64 num_bytes, int reserve); + static int __btrfs_free_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, +@@ -57,10 +57,17 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, + u64 parent, u64 root_objectid, + u64 flags, struct btrfs_disk_key *key, + int level, struct btrfs_key *ins); +- + static int do_chunk_alloc(struct btrfs_trans_handle *trans, + struct btrfs_root *extent_root, u64 alloc_bytes, + u64 flags, int force); ++static int pin_down_bytes(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct btrfs_path *path, ++ u64 bytenr, u64 num_bytes, ++ int is_data, int reserved, ++ struct extent_buffer **must_clean); ++static int find_next_key(struct btrfs_path *path, int level, ++ struct btrfs_key *key); + + static noinline int + block_group_cache_done(struct btrfs_block_group_cache *cache) +@@ -153,34 +160,34 @@ block_group_cache_tree_search(struct btrfs_fs_info *info, u64 bytenr, + return ret; + } + +-/* +- * We always set EXTENT_LOCKED for the super mirror extents so we don't +- * overwrite them, so those bits need to be unset. Also, if we are unmounting +- * with pinned extents still sitting there because we had a block group caching, +- * we need to clear those now, since we are done. +- */ +-void btrfs_free_pinned_extents(struct btrfs_fs_info *info) ++static int add_excluded_extent(struct btrfs_root *root, ++ u64 start, u64 num_bytes) + { +- u64 start, end, last = 0; +- int ret; ++ u64 end = start + num_bytes - 1; ++ set_extent_bits(&root->fs_info->freed_extents[0], ++ start, end, EXTENT_UPTODATE, GFP_NOFS); ++ set_extent_bits(&root->fs_info->freed_extents[1], ++ start, end, EXTENT_UPTODATE, GFP_NOFS); ++ return 0; ++} + +- while (1) { +- ret = find_first_extent_bit(&info->pinned_extents, last, +- &start, &end, +- EXTENT_LOCKED|EXTENT_DIRTY); +- if (ret) +- break; ++static void free_excluded_extents(struct btrfs_root *root, ++ struct btrfs_block_group_cache *cache) ++{ ++ u64 start, end; + +- clear_extent_bits(&info->pinned_extents, start, end, +- EXTENT_LOCKED|EXTENT_DIRTY, GFP_NOFS); +- last = end+1; +- } ++ start = cache->key.objectid; ++ end = start + cache->key.offset - 1; ++ ++ clear_extent_bits(&root->fs_info->freed_extents[0], ++ start, end, EXTENT_UPTODATE, GFP_NOFS); ++ clear_extent_bits(&root->fs_info->freed_extents[1], ++ start, end, EXTENT_UPTODATE, GFP_NOFS); + } + +-static int remove_sb_from_cache(struct btrfs_root *root, +- struct btrfs_block_group_cache *cache) ++static int exclude_super_stripes(struct btrfs_root *root, ++ struct btrfs_block_group_cache *cache) + { +- struct btrfs_fs_info *fs_info = root->fs_info; + u64 bytenr; + u64 *logical; + int stripe_len; +@@ -192,17 +199,42 @@ static int remove_sb_from_cache(struct btrfs_root *root, + cache->key.objectid, bytenr, + 0, &logical, &nr, &stripe_len); + BUG_ON(ret); ++ + while (nr--) { +- try_lock_extent(&fs_info->pinned_extents, +- logical[nr], +- logical[nr] + stripe_len - 1, GFP_NOFS); ++ cache->bytes_super += stripe_len; ++ ret = add_excluded_extent(root, logical[nr], ++ stripe_len); ++ BUG_ON(ret); + } ++ + kfree(logical); + } +- + return 0; + } + ++static struct btrfs_caching_control * ++get_caching_control(struct btrfs_block_group_cache *cache) ++{ ++ struct btrfs_caching_control *ctl; ++ ++ spin_lock(&cache->lock); ++ if (cache->cached != BTRFS_CACHE_STARTED) { ++ spin_unlock(&cache->lock); ++ return NULL; ++ } ++ ++ ctl = cache->caching_ctl; ++ atomic_inc(&ctl->count); ++ spin_unlock(&cache->lock); ++ return ctl; ++} ++ ++static void put_caching_control(struct btrfs_caching_control *ctl) ++{ ++ if (atomic_dec_and_test(&ctl->count)) ++ kfree(ctl); ++} ++ + /* + * this is only called by cache_block_group, since we could have freed extents + * we need to check the pinned_extents for any extents that can't be used yet +@@ -215,9 +247,9 @@ static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, + int ret; + + while (start < end) { +- ret = find_first_extent_bit(&info->pinned_extents, start, ++ ret = find_first_extent_bit(info->pinned_extents, start, + &extent_start, &extent_end, +- EXTENT_DIRTY|EXTENT_LOCKED); ++ EXTENT_DIRTY | EXTENT_UPTODATE); + if (ret) + break; + +@@ -249,22 +281,27 @@ static int caching_kthread(void *data) + { + struct btrfs_block_group_cache *block_group = data; + struct btrfs_fs_info *fs_info = block_group->fs_info; +- u64 last = 0; ++ struct btrfs_caching_control *caching_ctl = block_group->caching_ctl; ++ struct btrfs_root *extent_root = fs_info->extent_root; + struct btrfs_path *path; +- int ret = 0; +- struct btrfs_key key; + struct extent_buffer *leaf; +- int slot; ++ struct btrfs_key key; + u64 total_found = 0; +- +- BUG_ON(!fs_info); ++ u64 last = 0; ++ u32 nritems; ++ int ret = 0; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + +- atomic_inc(&block_group->space_info->caching_threads); ++ exclude_super_stripes(extent_root, block_group); ++ spin_lock(&block_group->space_info->lock); ++ block_group->space_info->bytes_super += block_group->bytes_super; ++ spin_unlock(&block_group->space_info->lock); ++ + last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); ++ + /* + * We don't want to deadlock with somebody trying to allocate a new + * extent for the extent root while also trying to search the extent +@@ -277,74 +314,64 @@ static int caching_kthread(void *data) + + key.objectid = last; + key.offset = 0; +- btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); ++ key.type = BTRFS_EXTENT_ITEM_KEY; + again: ++ mutex_lock(&caching_ctl->mutex); + /* need to make sure the commit_root doesn't disappear */ + down_read(&fs_info->extent_commit_sem); + +- ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); ++ ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); + if (ret < 0) + goto err; + ++ leaf = path->nodes[0]; ++ nritems = btrfs_header_nritems(leaf); ++ + while (1) { + smp_mb(); +- if (block_group->fs_info->closing > 1) { ++ if (fs_info->closing > 1) { + last = (u64)-1; + break; + } + +- leaf = path->nodes[0]; +- slot = path->slots[0]; +- if (slot >= btrfs_header_nritems(leaf)) { +- ret = btrfs_next_leaf(fs_info->extent_root, path); +- if (ret < 0) +- goto err; +- else if (ret) ++ if (path->slots[0] < nritems) { ++ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); ++ } else { ++ ret = find_next_key(path, 0, &key); ++ if (ret) + break; + +- if (need_resched() || +- btrfs_transaction_in_commit(fs_info)) { +- leaf = path->nodes[0]; +- +- /* this shouldn't happen, but if the +- * leaf is empty just move on. +- */ +- if (btrfs_header_nritems(leaf) == 0) +- break; +- /* +- * we need to copy the key out so that +- * we are sure the next search advances +- * us forward in the btree. +- */ +- btrfs_item_key_to_cpu(leaf, &key, 0); +- btrfs_release_path(fs_info->extent_root, path); +- up_read(&fs_info->extent_commit_sem); ++ caching_ctl->progress = last; ++ btrfs_release_path(extent_root, path); ++ up_read(&fs_info->extent_commit_sem); ++ mutex_unlock(&caching_ctl->mutex); ++ if (btrfs_transaction_in_commit(fs_info)) + schedule_timeout(1); +- goto again; +- } ++ else ++ cond_resched(); ++ goto again; ++ } + ++ if (key.objectid < block_group->key.objectid) { ++ path->slots[0]++; + continue; + } +- btrfs_item_key_to_cpu(leaf, &key, slot); +- if (key.objectid < block_group->key.objectid) +- goto next; + + if (key.objectid >= block_group->key.objectid + + block_group->key.offset) + break; + +- if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) { ++ if (key.type == BTRFS_EXTENT_ITEM_KEY) { + total_found += add_new_free_space(block_group, + fs_info, last, + key.objectid); + last = key.objectid + key.offset; +- } + +- if (total_found > (1024 * 1024 * 2)) { +- total_found = 0; +- wake_up(&block_group->caching_q); ++ if (total_found > (1024 * 1024 * 2)) { ++ total_found = 0; ++ wake_up(&caching_ctl->wait); ++ } + } +-next: + path->slots[0]++; + } + ret = 0; +@@ -352,33 +379,65 @@ next: + total_found += add_new_free_space(block_group, fs_info, last, + block_group->key.objectid + + block_group->key.offset); ++ caching_ctl->progress = (u64)-1; + + spin_lock(&block_group->lock); ++ block_group->caching_ctl = NULL; + block_group->cached = BTRFS_CACHE_FINISHED; + spin_unlock(&block_group->lock); + + err: + btrfs_free_path(path); + up_read(&fs_info->extent_commit_sem); +- atomic_dec(&block_group->space_info->caching_threads); +- wake_up(&block_group->caching_q); + ++ free_excluded_extents(extent_root, block_group); ++ ++ mutex_unlock(&caching_ctl->mutex); ++ wake_up(&caching_ctl->wait); ++ ++ put_caching_control(caching_ctl); ++ atomic_dec(&block_group->space_info->caching_threads); + return 0; + } + + static int cache_block_group(struct btrfs_block_group_cache *cache) + { ++ struct btrfs_fs_info *fs_info = cache->fs_info; ++ struct btrfs_caching_control *caching_ctl; + struct task_struct *tsk; + int ret = 0; + ++ smp_mb(); ++ if (cache->cached != BTRFS_CACHE_NO) ++ return 0; ++ ++ caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_KERNEL); ++ BUG_ON(!caching_ctl); ++ ++ INIT_LIST_HEAD(&caching_ctl->list); ++ mutex_init(&caching_ctl->mutex); ++ init_waitqueue_head(&caching_ctl->wait); ++ caching_ctl->block_group = cache; ++ caching_ctl->progress = cache->key.objectid; ++ /* one for caching kthread, one for caching block group list */ ++ atomic_set(&caching_ctl->count, 2); ++ + spin_lock(&cache->lock); + if (cache->cached != BTRFS_CACHE_NO) { + spin_unlock(&cache->lock); +- return ret; ++ kfree(caching_ctl); ++ return 0; + } ++ cache->caching_ctl = caching_ctl; + cache->cached = BTRFS_CACHE_STARTED; + spin_unlock(&cache->lock); + ++ down_write(&fs_info->extent_commit_sem); ++ list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups); ++ up_write(&fs_info->extent_commit_sem); ++ ++ atomic_inc(&cache->space_info->caching_threads); ++ + tsk = kthread_run(caching_kthread, cache, "btrfs-cache-%llu\n", + cache->key.objectid); + if (IS_ERR(tsk)) { +@@ -1511,7 +1570,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans, static void btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len) { @@ -1605677,8 +1675621,3349 @@ index 72a2b9c..535f85b 100644 } #endif +@@ -1656,7 +1716,6 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans, + parent, ref_root, flags, + ref->objectid, ref->offset, + &ins, node->ref_mod); +- update_reserved_extents(root, ins.objectid, ins.offset, 0); + } else if (node->action == BTRFS_ADD_DELAYED_REF) { + ret = __btrfs_inc_extent_ref(trans, root, node->bytenr, + node->num_bytes, parent, +@@ -1782,7 +1841,6 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans, + extent_op->flags_to_set, + &extent_op->key, + ref->level, &ins); +- update_reserved_extents(root, ins.objectid, ins.offset, 0); + } else if (node->action == BTRFS_ADD_DELAYED_REF) { + ret = __btrfs_inc_extent_ref(trans, root, node->bytenr, + node->num_bytes, parent, ref_root, +@@ -1817,16 +1875,32 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans, + BUG_ON(extent_op); + head = btrfs_delayed_node_to_head(node); + if (insert_reserved) { ++ int mark_free = 0; ++ struct extent_buffer *must_clean = NULL; ++ ++ ret = pin_down_bytes(trans, root, NULL, ++ node->bytenr, node->num_bytes, ++ head->is_data, 1, &must_clean); ++ if (ret > 0) ++ mark_free = 1; ++ ++ if (must_clean) { ++ clean_tree_block(NULL, root, must_clean); ++ btrfs_tree_unlock(must_clean); ++ free_extent_buffer(must_clean); ++ } + if (head->is_data) { + ret = btrfs_del_csums(trans, root, + node->bytenr, + node->num_bytes); + BUG_ON(ret); + } +- btrfs_update_pinned_extents(root, node->bytenr, +- node->num_bytes, 1); +- update_reserved_extents(root, node->bytenr, +- node->num_bytes, 0); ++ if (mark_free) { ++ ret = btrfs_free_reserved_extent(root, ++ node->bytenr, ++ node->num_bytes); ++ BUG_ON(ret); ++ } + } + mutex_unlock(&head->mutex); + return 0; +@@ -2705,6 +2779,8 @@ int btrfs_check_metadata_free_space(struct btrfs_root *root) + /* get the space info for where the metadata will live */ + alloc_target = btrfs_get_alloc_profile(root, 0); + meta_sinfo = __find_space_info(info, alloc_target); ++ if (!meta_sinfo) ++ goto alloc; + + again: + spin_lock(&meta_sinfo->lock); +@@ -2716,12 +2792,13 @@ again: + do_div(thresh, 100); + + if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + +- meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly > thresh) { ++ meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly + ++ meta_sinfo->bytes_super > thresh) { + struct btrfs_trans_handle *trans; + if (!meta_sinfo->full) { + meta_sinfo->force_alloc = 1; + spin_unlock(&meta_sinfo->lock); +- ++alloc: + trans = btrfs_start_transaction(root, 1); + if (!trans) + return -ENOMEM; +@@ -2729,6 +2806,10 @@ again: + ret = do_chunk_alloc(trans, root->fs_info->extent_root, + 2 * 1024 * 1024, alloc_target, 0); + btrfs_end_transaction(trans, root); ++ if (!meta_sinfo) { ++ meta_sinfo = __find_space_info(info, ++ alloc_target); ++ } + goto again; + } + spin_unlock(&meta_sinfo->lock); +@@ -2764,13 +2845,16 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, + bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); + + data_sinfo = BTRFS_I(inode)->space_info; ++ if (!data_sinfo) ++ goto alloc; ++ + again: + /* make sure we have enough space to handle the data first */ + spin_lock(&data_sinfo->lock); + if (data_sinfo->total_bytes - data_sinfo->bytes_used - + data_sinfo->bytes_delalloc - data_sinfo->bytes_reserved - + data_sinfo->bytes_pinned - data_sinfo->bytes_readonly - +- data_sinfo->bytes_may_use < bytes) { ++ data_sinfo->bytes_may_use - data_sinfo->bytes_super < bytes) { + struct btrfs_trans_handle *trans; + + /* +@@ -2782,7 +2866,7 @@ again: + + data_sinfo->force_alloc = 1; + spin_unlock(&data_sinfo->lock); +- ++alloc: + alloc_target = btrfs_get_alloc_profile(root, 1); + trans = btrfs_start_transaction(root, 1); + if (!trans) +@@ -2794,6 +2878,11 @@ again: + btrfs_end_transaction(trans, root); + if (ret) + return ret; ++ ++ if (!data_sinfo) { ++ btrfs_set_inode_space_info(root, inode); ++ data_sinfo = BTRFS_I(inode)->space_info; ++ } + goto again; + } + spin_unlock(&data_sinfo->lock); +@@ -3008,10 +3097,12 @@ static int update_block_group(struct btrfs_trans_handle *trans, + num_bytes = min(total, cache->key.offset - byte_in_group); + if (alloc) { + old_val += num_bytes; ++ btrfs_set_block_group_used(&cache->item, old_val); ++ cache->reserved -= num_bytes; + cache->space_info->bytes_used += num_bytes; ++ cache->space_info->bytes_reserved -= num_bytes; + if (cache->ro) + cache->space_info->bytes_readonly -= num_bytes; +- btrfs_set_block_group_used(&cache->item, old_val); + spin_unlock(&cache->lock); + spin_unlock(&cache->space_info->lock); + } else { +@@ -3056,127 +3147,136 @@ static u64 first_logical_byte(struct btrfs_root *root, u64 search_start) + return bytenr; + } + +-int btrfs_update_pinned_extents(struct btrfs_root *root, +- u64 bytenr, u64 num, int pin) ++/* ++ * this function must be called within transaction ++ */ ++int btrfs_pin_extent(struct btrfs_root *root, ++ u64 bytenr, u64 num_bytes, int reserved) + { +- u64 len; +- struct btrfs_block_group_cache *cache; + struct btrfs_fs_info *fs_info = root->fs_info; ++ struct btrfs_block_group_cache *cache; + +- if (pin) +- set_extent_dirty(&fs_info->pinned_extents, +- bytenr, bytenr + num - 1, GFP_NOFS); +- +- while (num > 0) { +- cache = btrfs_lookup_block_group(fs_info, bytenr); +- BUG_ON(!cache); +- len = min(num, cache->key.offset - +- (bytenr - cache->key.objectid)); +- if (pin) { +- spin_lock(&cache->space_info->lock); +- spin_lock(&cache->lock); +- cache->pinned += len; +- cache->space_info->bytes_pinned += len; +- spin_unlock(&cache->lock); +- spin_unlock(&cache->space_info->lock); +- fs_info->total_pinned += len; +- } else { +- int unpin = 0; ++ cache = btrfs_lookup_block_group(fs_info, bytenr); ++ BUG_ON(!cache); + +- /* +- * in order to not race with the block group caching, we +- * only want to unpin the extent if we are cached. If +- * we aren't cached, we want to start async caching this +- * block group so we can free the extent the next time +- * around. +- */ +- spin_lock(&cache->space_info->lock); +- spin_lock(&cache->lock); +- unpin = (cache->cached == BTRFS_CACHE_FINISHED); +- if (likely(unpin)) { +- cache->pinned -= len; +- cache->space_info->bytes_pinned -= len; +- fs_info->total_pinned -= len; +- } +- spin_unlock(&cache->lock); +- spin_unlock(&cache->space_info->lock); ++ spin_lock(&cache->space_info->lock); ++ spin_lock(&cache->lock); ++ cache->pinned += num_bytes; ++ cache->space_info->bytes_pinned += num_bytes; ++ if (reserved) { ++ cache->reserved -= num_bytes; ++ cache->space_info->bytes_reserved -= num_bytes; ++ } ++ spin_unlock(&cache->lock); ++ spin_unlock(&cache->space_info->lock); + +- if (likely(unpin)) +- clear_extent_dirty(&fs_info->pinned_extents, +- bytenr, bytenr + len -1, +- GFP_NOFS); +- else +- cache_block_group(cache); ++ btrfs_put_block_group(cache); + +- if (unpin) +- btrfs_add_free_space(cache, bytenr, len); +- } +- btrfs_put_block_group(cache); +- bytenr += len; +- num -= len; ++ set_extent_dirty(fs_info->pinned_extents, ++ bytenr, bytenr + num_bytes - 1, GFP_NOFS); ++ return 0; ++} ++ ++static int update_reserved_extents(struct btrfs_block_group_cache *cache, ++ u64 num_bytes, int reserve) ++{ ++ spin_lock(&cache->space_info->lock); ++ spin_lock(&cache->lock); ++ if (reserve) { ++ cache->reserved += num_bytes; ++ cache->space_info->bytes_reserved += num_bytes; ++ } else { ++ cache->reserved -= num_bytes; ++ cache->space_info->bytes_reserved -= num_bytes; + } ++ spin_unlock(&cache->lock); ++ spin_unlock(&cache->space_info->lock); + return 0; + } + +-static int update_reserved_extents(struct btrfs_root *root, +- u64 bytenr, u64 num, int reserve) ++int btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root) + { +- u64 len; +- struct btrfs_block_group_cache *cache; + struct btrfs_fs_info *fs_info = root->fs_info; ++ struct btrfs_caching_control *next; ++ struct btrfs_caching_control *caching_ctl; ++ struct btrfs_block_group_cache *cache; + +- while (num > 0) { +- cache = btrfs_lookup_block_group(fs_info, bytenr); +- BUG_ON(!cache); +- len = min(num, cache->key.offset - +- (bytenr - cache->key.objectid)); ++ down_write(&fs_info->extent_commit_sem); + +- spin_lock(&cache->space_info->lock); +- spin_lock(&cache->lock); +- if (reserve) { +- cache->reserved += len; +- cache->space_info->bytes_reserved += len; ++ list_for_each_entry_safe(caching_ctl, next, ++ &fs_info->caching_block_groups, list) { ++ cache = caching_ctl->block_group; ++ if (block_group_cache_done(cache)) { ++ cache->last_byte_to_unpin = (u64)-1; ++ list_del_init(&caching_ctl->list); ++ put_caching_control(caching_ctl); + } else { +- cache->reserved -= len; +- cache->space_info->bytes_reserved -= len; ++ cache->last_byte_to_unpin = caching_ctl->progress; + } +- spin_unlock(&cache->lock); +- spin_unlock(&cache->space_info->lock); +- btrfs_put_block_group(cache); +- bytenr += len; +- num -= len; + } ++ ++ if (fs_info->pinned_extents == &fs_info->freed_extents[0]) ++ fs_info->pinned_extents = &fs_info->freed_extents[1]; ++ else ++ fs_info->pinned_extents = &fs_info->freed_extents[0]; ++ ++ up_write(&fs_info->extent_commit_sem); + return 0; + } + +-int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy) ++static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) + { +- u64 last = 0; +- u64 start; +- u64 end; +- struct extent_io_tree *pinned_extents = &root->fs_info->pinned_extents; +- int ret; ++ struct btrfs_fs_info *fs_info = root->fs_info; ++ struct btrfs_block_group_cache *cache = NULL; ++ u64 len; + +- while (1) { +- ret = find_first_extent_bit(pinned_extents, last, +- &start, &end, EXTENT_DIRTY); +- if (ret) +- break; ++ while (start <= end) { ++ if (!cache || ++ start >= cache->key.objectid + cache->key.offset) { ++ if (cache) ++ btrfs_put_block_group(cache); ++ cache = btrfs_lookup_block_group(fs_info, start); ++ BUG_ON(!cache); ++ } ++ ++ len = cache->key.objectid + cache->key.offset - start; ++ len = min(len, end + 1 - start); + +- set_extent_dirty(copy, start, end, GFP_NOFS); +- last = end + 1; ++ if (start < cache->last_byte_to_unpin) { ++ len = min(len, cache->last_byte_to_unpin - start); ++ btrfs_add_free_space(cache, start, len); ++ } ++ ++ spin_lock(&cache->space_info->lock); ++ spin_lock(&cache->lock); ++ cache->pinned -= len; ++ cache->space_info->bytes_pinned -= len; ++ spin_unlock(&cache->lock); ++ spin_unlock(&cache->space_info->lock); ++ ++ start += len; + } ++ ++ if (cache) ++ btrfs_put_block_group(cache); + return 0; + } + + int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct extent_io_tree *unpin) ++ struct btrfs_root *root) + { ++ struct btrfs_fs_info *fs_info = root->fs_info; ++ struct extent_io_tree *unpin; + u64 start; + u64 end; + int ret; + ++ if (fs_info->pinned_extents == &fs_info->freed_extents[0]) ++ unpin = &fs_info->freed_extents[1]; ++ else ++ unpin = &fs_info->freed_extents[0]; ++ + while (1) { + ret = find_first_extent_bit(unpin, 0, &start, &end, + EXTENT_DIRTY); +@@ -3185,10 +3285,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, + + ret = btrfs_discard_extent(root, start, end + 1 - start); + +- /* unlocks the pinned mutex */ +- btrfs_update_pinned_extents(root, start, end + 1 - start, 0); + clear_extent_dirty(unpin, start, end, GFP_NOFS); +- ++ unpin_extent_range(root, start, end); + cond_resched(); + } + +@@ -3198,7 +3296,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, + static int pin_down_bytes(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, +- u64 bytenr, u64 num_bytes, int is_data, ++ u64 bytenr, u64 num_bytes, ++ int is_data, int reserved, + struct extent_buffer **must_clean) + { + int err = 0; +@@ -3230,15 +3329,15 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans, + } + free_extent_buffer(buf); + pinit: +- btrfs_set_path_blocking(path); ++ if (path) ++ btrfs_set_path_blocking(path); + /* unlocks the pinned mutex */ +- btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); ++ btrfs_pin_extent(root, bytenr, num_bytes, reserved); + + BUG_ON(err < 0); + return 0; + } + +- + static int __btrfs_free_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, +@@ -3412,7 +3511,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, + } + + ret = pin_down_bytes(trans, root, path, bytenr, +- num_bytes, is_data, &must_clean); ++ num_bytes, is_data, 0, &must_clean); + if (ret > 0) + mark_free = 1; + BUG_ON(ret < 0); +@@ -3543,8 +3642,7 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, + if (root_objectid == BTRFS_TREE_LOG_OBJECTID) { + WARN_ON(owner >= BTRFS_FIRST_FREE_OBJECTID); + /* unlocks the pinned mutex */ +- btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); +- update_reserved_extents(root, bytenr, num_bytes, 0); ++ btrfs_pin_extent(root, bytenr, num_bytes, 1); + ret = 0; + } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { + ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, +@@ -3584,19 +3682,33 @@ static noinline int + wait_block_group_cache_progress(struct btrfs_block_group_cache *cache, + u64 num_bytes) + { ++ struct btrfs_caching_control *caching_ctl; + DEFINE_WAIT(wait); + +- prepare_to_wait(&cache->caching_q, &wait, TASK_UNINTERRUPTIBLE); +- +- if (block_group_cache_done(cache)) { +- finish_wait(&cache->caching_q, &wait); ++ caching_ctl = get_caching_control(cache); ++ if (!caching_ctl) + return 0; +- } +- schedule(); +- finish_wait(&cache->caching_q, &wait); + +- wait_event(cache->caching_q, block_group_cache_done(cache) || ++ wait_event(caching_ctl->wait, block_group_cache_done(cache) || + (cache->free_space >= num_bytes)); ++ ++ put_caching_control(caching_ctl); ++ return 0; ++} ++ ++static noinline int ++wait_block_group_cache_done(struct btrfs_block_group_cache *cache) ++{ ++ struct btrfs_caching_control *caching_ctl; ++ DEFINE_WAIT(wait); ++ ++ caching_ctl = get_caching_control(cache); ++ if (!caching_ctl) ++ return 0; ++ ++ wait_event(caching_ctl->wait, block_group_cache_done(cache)); ++ ++ put_caching_control(caching_ctl); + return 0; + } + +@@ -3634,6 +3746,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, + int last_ptr_loop = 0; + int loop = 0; + bool found_uncached_bg = false; ++ bool failed_cluster_refill = false; + + WARN_ON(num_bytes < root->sectorsize); + btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); +@@ -3731,7 +3844,16 @@ have_block_group: + if (unlikely(block_group->ro)) + goto loop; + +- if (last_ptr) { ++ /* ++ * Ok we want to try and use the cluster allocator, so lets look ++ * there, unless we are on LOOP_NO_EMPTY_SIZE, since we will ++ * have tried the cluster allocator plenty of times at this ++ * point and not have found anything, so we are likely way too ++ * fragmented for the clustering stuff to find anything, so lets ++ * just skip it and let the allocator find whatever block it can ++ * find ++ */ ++ if (last_ptr && loop < LOOP_NO_EMPTY_SIZE) { + /* + * the refill lock keeps out other + * people trying to start a new cluster +@@ -3806,9 +3928,11 @@ refill_cluster: + spin_unlock(&last_ptr->refill_lock); + goto checks; + } +- } else if (!cached && loop > LOOP_CACHING_NOWAIT) { ++ } else if (!cached && loop > LOOP_CACHING_NOWAIT ++ && !failed_cluster_refill) { + spin_unlock(&last_ptr->refill_lock); + ++ failed_cluster_refill = true; + wait_block_group_cache_progress(block_group, + num_bytes + empty_cluster + empty_size); + goto have_block_group; +@@ -3820,13 +3944,9 @@ refill_cluster: + * cluster. Free the cluster we've been trying + * to use, and go to the next block group + */ +- if (loop < LOOP_NO_EMPTY_SIZE) { +- btrfs_return_cluster_to_free_space(NULL, +- last_ptr); +- spin_unlock(&last_ptr->refill_lock); +- goto loop; +- } ++ btrfs_return_cluster_to_free_space(NULL, last_ptr); + spin_unlock(&last_ptr->refill_lock); ++ goto loop; + } + + offset = btrfs_find_space_for_alloc(block_group, search_start, +@@ -3880,9 +4000,12 @@ checks: + search_start - offset); + BUG_ON(offset > search_start); + ++ update_reserved_extents(block_group, num_bytes, 1); ++ + /* we are all good, lets return */ + break; + loop: ++ failed_cluster_refill = false; + btrfs_put_block_group(block_group); + } + up_read(&space_info->groups_sem); +@@ -3972,12 +4095,12 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes) + up_read(&info->groups_sem); + } + +-static int __btrfs_reserve_extent(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- u64 num_bytes, u64 min_alloc_size, +- u64 empty_size, u64 hint_byte, +- u64 search_end, struct btrfs_key *ins, +- u64 data) ++int btrfs_reserve_extent(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ u64 num_bytes, u64 min_alloc_size, ++ u64 empty_size, u64 hint_byte, ++ u64 search_end, struct btrfs_key *ins, ++ u64 data) + { + int ret; + u64 search_start = 0; +@@ -4043,25 +4166,8 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len) + ret = btrfs_discard_extent(root, start, len); + + btrfs_add_free_space(cache, start, len); ++ update_reserved_extents(cache, len, 0); + btrfs_put_block_group(cache); +- update_reserved_extents(root, start, len, 0); +- +- return ret; +-} +- +-int btrfs_reserve_extent(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- u64 num_bytes, u64 min_alloc_size, +- u64 empty_size, u64 hint_byte, +- u64 search_end, struct btrfs_key *ins, +- u64 data) +-{ +- int ret; +- ret = __btrfs_reserve_extent(trans, root, num_bytes, min_alloc_size, +- empty_size, hint_byte, search_end, ins, +- data); +- if (!ret) +- update_reserved_extents(root, ins->objectid, ins->offset, 1); + + return ret; + } +@@ -4222,15 +4328,46 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, + { + int ret; + struct btrfs_block_group_cache *block_group; ++ struct btrfs_caching_control *caching_ctl; ++ u64 start = ins->objectid; ++ u64 num_bytes = ins->offset; + + block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); + cache_block_group(block_group); +- wait_event(block_group->caching_q, +- block_group_cache_done(block_group)); ++ caching_ctl = get_caching_control(block_group); + +- ret = btrfs_remove_free_space(block_group, ins->objectid, +- ins->offset); +- BUG_ON(ret); ++ if (!caching_ctl) { ++ BUG_ON(!block_group_cache_done(block_group)); ++ ret = btrfs_remove_free_space(block_group, start, num_bytes); ++ BUG_ON(ret); ++ } else { ++ mutex_lock(&caching_ctl->mutex); ++ ++ if (start >= caching_ctl->progress) { ++ ret = add_excluded_extent(root, start, num_bytes); ++ BUG_ON(ret); ++ } else if (start + num_bytes <= caching_ctl->progress) { ++ ret = btrfs_remove_free_space(block_group, ++ start, num_bytes); ++ BUG_ON(ret); ++ } else { ++ num_bytes = caching_ctl->progress - start; ++ ret = btrfs_remove_free_space(block_group, ++ start, num_bytes); ++ BUG_ON(ret); ++ ++ start = caching_ctl->progress; ++ num_bytes = ins->objectid + ins->offset - ++ caching_ctl->progress; ++ ret = add_excluded_extent(root, start, num_bytes); ++ BUG_ON(ret); ++ } ++ ++ mutex_unlock(&caching_ctl->mutex); ++ put_caching_control(caching_ctl); ++ } ++ ++ update_reserved_extents(block_group, ins->offset, 1); + btrfs_put_block_group(block_group); + ret = alloc_reserved_file_extent(trans, root, 0, root_objectid, + 0, owner, offset, ins, 1); +@@ -4254,9 +4391,9 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, + int ret; + u64 flags = 0; + +- ret = __btrfs_reserve_extent(trans, root, num_bytes, num_bytes, +- empty_size, hint_byte, search_end, +- ins, 0); ++ ret = btrfs_reserve_extent(trans, root, num_bytes, num_bytes, ++ empty_size, hint_byte, search_end, ++ ins, 0); + if (ret) + return ret; + +@@ -4267,7 +4404,6 @@ static int alloc_tree_block(struct btrfs_trans_handle *trans, + } else + BUG_ON(parent > 0); + +- update_reserved_extents(root, ins->objectid, ins->offset, 1); + if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { + struct btrfs_delayed_extent_op *extent_op; + extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS); +@@ -4346,452 +4482,99 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, + return buf; + } + +-#if 0 +-int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, struct extent_buffer *leaf) +-{ +- u64 disk_bytenr; +- u64 num_bytes; +- struct btrfs_key key; +- struct btrfs_file_extent_item *fi; +- u32 nritems; +- int i; +- int ret; +- +- BUG_ON(!btrfs_is_leaf(leaf)); +- nritems = btrfs_header_nritems(leaf); +- +- for (i = 0; i < nritems; i++) { +- cond_resched(); +- btrfs_item_key_to_cpu(leaf, &key, i); +- +- /* only extents have references, skip everything else */ +- if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY) +- continue; +- +- fi = btrfs_item_ptr(leaf, i, struct btrfs_file_extent_item); +- +- /* inline extents live in the btree, they don't have refs */ +- if (btrfs_file_extent_type(leaf, fi) == +- BTRFS_FILE_EXTENT_INLINE) +- continue; +- +- disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi); +- +- /* holes don't have refs */ +- if (disk_bytenr == 0) +- continue; +- +- num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi); +- ret = btrfs_free_extent(trans, root, disk_bytenr, num_bytes, +- leaf->start, 0, key.objectid, 0); +- BUG_ON(ret); +- } +- return 0; +-} +- +-static noinline int cache_drop_leaf_ref(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct btrfs_leaf_ref *ref) +-{ +- int i; +- int ret; +- struct btrfs_extent_info *info; +- struct refsort *sorted; +- +- if (ref->nritems == 0) +- return 0; +- +- sorted = kmalloc(sizeof(*sorted) * ref->nritems, GFP_NOFS); +- for (i = 0; i < ref->nritems; i++) { +- sorted[i].bytenr = ref->extents[i].bytenr; +- sorted[i].slot = i; +- } +- sort(sorted, ref->nritems, sizeof(struct refsort), refsort_cmp, NULL); +- +- /* +- * the items in the ref were sorted when the ref was inserted +- * into the ref cache, so this is already in order +- */ +- for (i = 0; i < ref->nritems; i++) { +- info = ref->extents + sorted[i].slot; +- ret = btrfs_free_extent(trans, root, info->bytenr, +- info->num_bytes, ref->bytenr, +- ref->owner, ref->generation, +- info->objectid, 0); +- +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- +- BUG_ON(ret); +- info++; +- } +- +- kfree(sorted); +- return 0; +-} +- +- +-static int drop_snap_lookup_refcount(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, u64 start, +- u64 len, u32 *refs) +-{ +- int ret; +- +- ret = btrfs_lookup_extent_refs(trans, root, start, len, refs); +- BUG_ON(ret); +- +-#if 0 /* some debugging code in case we see problems here */ +- /* if the refs count is one, it won't get increased again. But +- * if the ref count is > 1, someone may be decreasing it at +- * the same time we are. +- */ +- if (*refs != 1) { +- struct extent_buffer *eb = NULL; +- eb = btrfs_find_create_tree_block(root, start, len); +- if (eb) +- btrfs_tree_lock(eb); +- +- mutex_lock(&root->fs_info->alloc_mutex); +- ret = lookup_extent_ref(NULL, root, start, len, refs); +- BUG_ON(ret); +- mutex_unlock(&root->fs_info->alloc_mutex); +- +- if (eb) { +- btrfs_tree_unlock(eb); +- free_extent_buffer(eb); +- } +- if (*refs == 1) { +- printk(KERN_ERR "btrfs block %llu went down to one " +- "during drop_snap\n", (unsigned long long)start); +- } +- +- } +-#endif +- +- cond_resched(); +- return ret; +-} ++struct walk_control { ++ u64 refs[BTRFS_MAX_LEVEL]; ++ u64 flags[BTRFS_MAX_LEVEL]; ++ struct btrfs_key update_progress; ++ int stage; ++ int level; ++ int shared_level; ++ int update_ref; ++ int keep_locks; ++ int reada_slot; ++ int reada_count; ++}; + ++#define DROP_REFERENCE 1 ++#define UPDATE_BACKREF 2 + +-/* +- * this is used while deleting old snapshots, and it drops the refs +- * on a whole subtree starting from a level 1 node. +- * +- * The idea is to sort all the leaf pointers, and then drop the +- * ref on all the leaves in order. Most of the time the leaves +- * will have ref cache entries, so no leaf IOs will be required to +- * find the extents they have references on. +- * +- * For each leaf, any references it has are also dropped in order +- * +- * This ends up dropping the references in something close to optimal +- * order for reading and modifying the extent allocation tree. +- */ +-static noinline int drop_level_one_refs(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct btrfs_path *path) ++static noinline void reada_walk_down(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct walk_control *wc, ++ struct btrfs_path *path) + { + u64 bytenr; +- u64 root_owner; +- u64 root_gen; +- struct extent_buffer *eb = path->nodes[1]; +- struct extent_buffer *leaf; +- struct btrfs_leaf_ref *ref; +- struct refsort *sorted = NULL; +- int nritems = btrfs_header_nritems(eb); ++ u64 generation; ++ u64 refs; ++ u64 last = 0; ++ u32 nritems; ++ u32 blocksize; ++ struct btrfs_key key; ++ struct extent_buffer *eb; + int ret; +- int i; +- int refi = 0; +- int slot = path->slots[1]; +- u32 blocksize = btrfs_level_size(root, 0); +- u32 refs; +- +- if (nritems == 0) +- goto out; +- +- root_owner = btrfs_header_owner(eb); +- root_gen = btrfs_header_generation(eb); +- sorted = kmalloc(sizeof(*sorted) * nritems, GFP_NOFS); ++ int slot; ++ int nread = 0; + +- /* +- * step one, sort all the leaf pointers so we don't scribble +- * randomly into the extent allocation tree +- */ +- for (i = slot; i < nritems; i++) { +- sorted[refi].bytenr = btrfs_node_blockptr(eb, i); +- sorted[refi].slot = i; +- refi++; ++ if (path->slots[wc->level] < wc->reada_slot) { ++ wc->reada_count = wc->reada_count * 2 / 3; ++ wc->reada_count = max(wc->reada_count, 2); ++ } else { ++ wc->reada_count = wc->reada_count * 3 / 2; ++ wc->reada_count = min_t(int, wc->reada_count, ++ BTRFS_NODEPTRS_PER_BLOCK(root)); + } + +- /* +- * nritems won't be zero, but if we're picking up drop_snapshot +- * after a crash, slot might be > 0, so double check things +- * just in case. +- */ +- if (refi == 0) +- goto out; ++ eb = path->nodes[wc->level]; ++ nritems = btrfs_header_nritems(eb); ++ blocksize = btrfs_level_size(root, wc->level - 1); + +- sort(sorted, refi, sizeof(struct refsort), refsort_cmp, NULL); ++ for (slot = path->slots[wc->level]; slot < nritems; slot++) { ++ if (nread >= wc->reada_count) ++ break; + +- /* +- * the first loop frees everything the leaves point to +- */ +- for (i = 0; i < refi; i++) { +- u64 ptr_gen; ++ cond_resched(); ++ bytenr = btrfs_node_blockptr(eb, slot); ++ generation = btrfs_node_ptr_generation(eb, slot); + +- bytenr = sorted[i].bytenr; ++ if (slot == path->slots[wc->level]) ++ goto reada; + +- /* +- * check the reference count on this leaf. If it is > 1 +- * we just decrement it below and don't update any +- * of the refs the leaf points to. +- */ +- ret = drop_snap_lookup_refcount(trans, root, bytenr, +- blocksize, &refs); +- BUG_ON(ret); +- if (refs != 1) ++ if (wc->stage == UPDATE_BACKREF && ++ generation <= root->root_key.offset) + continue; + +- ptr_gen = btrfs_node_ptr_generation(eb, sorted[i].slot); +- +- /* +- * the leaf only had one reference, which means the +- * only thing pointing to this leaf is the snapshot +- * we're deleting. It isn't possible for the reference +- * count to increase again later +- * +- * The reference cache is checked for the leaf, +- * and if found we'll be able to drop any refs held by +- * the leaf without needing to read it in. +- */ +- ref = btrfs_lookup_leaf_ref(root, bytenr); +- if (ref && ref->generation != ptr_gen) { +- btrfs_free_leaf_ref(root, ref); +- ref = NULL; +- } +- if (ref) { +- ret = cache_drop_leaf_ref(trans, root, ref); +- BUG_ON(ret); +- btrfs_remove_leaf_ref(root, ref); +- btrfs_free_leaf_ref(root, ref); +- } else { +- /* +- * the leaf wasn't in the reference cache, so +- * we have to read it. +- */ +- leaf = read_tree_block(root, bytenr, blocksize, +- ptr_gen); +- ret = btrfs_drop_leaf_ref(trans, root, leaf); ++ if (wc->stage == DROP_REFERENCE) { ++ ret = btrfs_lookup_extent_info(trans, root, ++ bytenr, blocksize, ++ &refs, NULL); + BUG_ON(ret); +- free_extent_buffer(leaf); +- } +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- } +- +- /* +- * run through the loop again to free the refs on the leaves. +- * This is faster than doing it in the loop above because +- * the leaves are likely to be clustered together. We end up +- * working in nice chunks on the extent allocation tree. +- */ +- for (i = 0; i < refi; i++) { +- bytenr = sorted[i].bytenr; +- ret = btrfs_free_extent(trans, root, bytenr, +- blocksize, eb->start, +- root_owner, root_gen, 0, 1); +- BUG_ON(ret); +- +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- } +-out: +- kfree(sorted); +- +- /* +- * update the path to show we've processed the entire level 1 +- * node. This will get saved into the root's drop_snapshot_progress +- * field so these drops are not repeated again if this transaction +- * commits. +- */ +- path->slots[1] = nritems; +- return 0; +-} +- +-/* +- * helper function for drop_snapshot, this walks down the tree dropping ref +- * counts as it goes. +- */ +-static noinline int walk_down_tree(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- struct btrfs_path *path, int *level) +-{ +- u64 root_owner; +- u64 root_gen; +- u64 bytenr; +- u64 ptr_gen; +- struct extent_buffer *next; +- struct extent_buffer *cur; +- struct extent_buffer *parent; +- u32 blocksize; +- int ret; +- u32 refs; +- +- WARN_ON(*level < 0); +- WARN_ON(*level >= BTRFS_MAX_LEVEL); +- ret = drop_snap_lookup_refcount(trans, root, path->nodes[*level]->start, +- path->nodes[*level]->len, &refs); +- BUG_ON(ret); +- if (refs > 1) +- goto out; +- +- /* +- * walk down to the last node level and free all the leaves +- */ +- while (*level >= 0) { +- WARN_ON(*level < 0); +- WARN_ON(*level >= BTRFS_MAX_LEVEL); +- cur = path->nodes[*level]; +- +- if (btrfs_header_level(cur) != *level) +- WARN_ON(1); ++ BUG_ON(refs == 0); ++ if (refs == 1) ++ goto reada; + +- if (path->slots[*level] >= +- btrfs_header_nritems(cur)) +- break; +- +- /* the new code goes down to level 1 and does all the +- * leaves pointed to that node in bulk. So, this check +- * for level 0 will always be false. +- * +- * But, the disk format allows the drop_snapshot_progress +- * field in the root to leave things in a state where +- * a leaf will need cleaning up here. If someone crashes +- * with the old code and then boots with the new code, +- * we might find a leaf here. +- */ +- if (*level == 0) { +- ret = btrfs_drop_leaf_ref(trans, root, cur); +- BUG_ON(ret); +- break; ++ if (!wc->update_ref || ++ generation <= root->root_key.offset) ++ continue; ++ btrfs_node_key_to_cpu(eb, &key, slot); ++ ret = btrfs_comp_cpu_keys(&key, ++ &wc->update_progress); ++ if (ret < 0) ++ continue; + } +- +- /* +- * once we get to level one, process the whole node +- * at once, including everything below it. +- */ +- if (*level == 1) { +- ret = drop_level_one_refs(trans, root, path); +- BUG_ON(ret); ++reada: ++ ret = readahead_tree_block(root, bytenr, blocksize, ++ generation); ++ if (ret) + break; +- } +- +- bytenr = btrfs_node_blockptr(cur, path->slots[*level]); +- ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); +- blocksize = btrfs_level_size(root, *level - 1); +- +- ret = drop_snap_lookup_refcount(trans, root, bytenr, +- blocksize, &refs); +- BUG_ON(ret); +- +- /* +- * if there is more than one reference, we don't need +- * to read that node to drop any references it has. We +- * just drop the ref we hold on that node and move on to the +- * next slot in this level. +- */ +- if (refs != 1) { +- parent = path->nodes[*level]; +- root_owner = btrfs_header_owner(parent); +- root_gen = btrfs_header_generation(parent); +- path->slots[*level]++; +- +- ret = btrfs_free_extent(trans, root, bytenr, +- blocksize, parent->start, +- root_owner, root_gen, +- *level - 1, 1); +- BUG_ON(ret); +- +- atomic_inc(&root->fs_info->throttle_gen); +- wake_up(&root->fs_info->transaction_throttle); +- cond_resched(); +- +- continue; +- } +- +- /* +- * we need to keep freeing things in the next level down. +- * read the block and loop around to process it +- */ +- next = read_tree_block(root, bytenr, blocksize, ptr_gen); +- WARN_ON(*level <= 0); +- if (path->nodes[*level-1]) +- free_extent_buffer(path->nodes[*level-1]); +- path->nodes[*level-1] = next; +- *level = btrfs_header_level(next); +- path->slots[*level] = 0; +- cond_resched(); ++ last = bytenr + blocksize; ++ nread++; + } +-out: +- WARN_ON(*level < 0); +- WARN_ON(*level >= BTRFS_MAX_LEVEL); +- +- if (path->nodes[*level] == root->node) { +- parent = path->nodes[*level]; +- bytenr = path->nodes[*level]->start; +- } else { +- parent = path->nodes[*level + 1]; +- bytenr = btrfs_node_blockptr(parent, path->slots[*level + 1]); +- } +- +- blocksize = btrfs_level_size(root, *level); +- root_owner = btrfs_header_owner(parent); +- root_gen = btrfs_header_generation(parent); +- +- /* +- * cleanup and free the reference on the last node +- * we processed +- */ +- ret = btrfs_free_extent(trans, root, bytenr, blocksize, +- parent->start, root_owner, root_gen, +- *level, 1); +- free_extent_buffer(path->nodes[*level]); +- path->nodes[*level] = NULL; +- +- *level += 1; +- BUG_ON(ret); +- +- cond_resched(); +- return 0; ++ wc->reada_slot = slot; + } +-#endif +- +-struct walk_control { +- u64 refs[BTRFS_MAX_LEVEL]; +- u64 flags[BTRFS_MAX_LEVEL]; +- struct btrfs_key update_progress; +- int stage; +- int level; +- int shared_level; +- int update_ref; +- int keep_locks; +-}; +- +-#define DROP_REFERENCE 1 +-#define UPDATE_BACKREF 2 + + /* + * hepler to process tree block while walking down the tree. + * +- * when wc->stage == DROP_REFERENCE, this function checks +- * reference count of the block. if the block is shared and +- * we need update back refs for the subtree rooted at the +- * block, this function changes wc->stage to UPDATE_BACKREF +- * + * when wc->stage == UPDATE_BACKREF, this function updates + * back refs for pointers in the block. + * +@@ -4804,7 +4587,6 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + { + int level = wc->level; + struct extent_buffer *eb = path->nodes[level]; +- struct btrfs_key key; + u64 flag = BTRFS_BLOCK_FLAG_FULL_BACKREF; + int ret; + +@@ -4827,21 +4609,6 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + BUG_ON(wc->refs[level] == 0); + } + +- if (wc->stage == DROP_REFERENCE && +- wc->update_ref && wc->refs[level] > 1) { +- BUG_ON(eb == root->node); +- BUG_ON(path->slots[level] > 0); +- if (level == 0) +- btrfs_item_key_to_cpu(eb, &key, path->slots[level]); +- else +- btrfs_node_key_to_cpu(eb, &key, path->slots[level]); +- if (btrfs_header_owner(eb) == root->root_key.objectid && +- btrfs_comp_cpu_keys(&key, &wc->update_progress) >= 0) { +- wc->stage = UPDATE_BACKREF; +- wc->shared_level = level; +- } +- } +- + if (wc->stage == DROP_REFERENCE) { + if (wc->refs[level] > 1) + return 1; +@@ -4878,6 +4645,123 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, + } + + /* ++ * hepler to process tree block pointer. ++ * ++ * when wc->stage == DROP_REFERENCE, this function checks ++ * reference count of the block pointed to. if the block ++ * is shared and we need update back refs for the subtree ++ * rooted at the block, this function changes wc->stage to ++ * UPDATE_BACKREF. if the block is shared and there is no ++ * need to update back, this function drops the reference ++ * to the block. ++ * ++ * NOTE: return value 1 means we should stop walking down. ++ */ ++static noinline int do_walk_down(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct btrfs_path *path, ++ struct walk_control *wc) ++{ ++ u64 bytenr; ++ u64 generation; ++ u64 parent; ++ u32 blocksize; ++ struct btrfs_key key; ++ struct extent_buffer *next; ++ int level = wc->level; ++ int reada = 0; ++ int ret = 0; ++ ++ generation = btrfs_node_ptr_generation(path->nodes[level], ++ path->slots[level]); ++ /* ++ * if the lower level block was created before the snapshot ++ * was created, we know there is no need to update back refs ++ * for the subtree ++ */ ++ if (wc->stage == UPDATE_BACKREF && ++ generation <= root->root_key.offset) ++ return 1; ++ ++ bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); ++ blocksize = btrfs_level_size(root, level - 1); ++ ++ next = btrfs_find_tree_block(root, bytenr, blocksize); ++ if (!next) { ++ next = btrfs_find_create_tree_block(root, bytenr, blocksize); ++ reada = 1; ++ } ++ btrfs_tree_lock(next); ++ btrfs_set_lock_blocking(next); ++ ++ if (wc->stage == DROP_REFERENCE) { ++ ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, ++ &wc->refs[level - 1], ++ &wc->flags[level - 1]); ++ BUG_ON(ret); ++ BUG_ON(wc->refs[level - 1] == 0); ++ ++ if (wc->refs[level - 1] > 1) { ++ if (!wc->update_ref || ++ generation <= root->root_key.offset) ++ goto skip; ++ ++ btrfs_node_key_to_cpu(path->nodes[level], &key, ++ path->slots[level]); ++ ret = btrfs_comp_cpu_keys(&key, &wc->update_progress); ++ if (ret < 0) ++ goto skip; ++ ++ wc->stage = UPDATE_BACKREF; ++ wc->shared_level = level - 1; ++ } ++ } ++ ++ if (!btrfs_buffer_uptodate(next, generation)) { ++ btrfs_tree_unlock(next); ++ free_extent_buffer(next); ++ next = NULL; ++ } ++ ++ if (!next) { ++ if (reada && level == 1) ++ reada_walk_down(trans, root, wc, path); ++ next = read_tree_block(root, bytenr, blocksize, generation); ++ btrfs_tree_lock(next); ++ btrfs_set_lock_blocking(next); ++ } ++ ++ level--; ++ BUG_ON(level != btrfs_header_level(next)); ++ path->nodes[level] = next; ++ path->slots[level] = 0; ++ path->locks[level] = 1; ++ wc->level = level; ++ if (wc->level == 1) ++ wc->reada_slot = 0; ++ return 0; ++skip: ++ wc->refs[level - 1] = 0; ++ wc->flags[level - 1] = 0; ++ ++ if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { ++ parent = path->nodes[level]->start; ++ } else { ++ BUG_ON(root->root_key.objectid != ++ btrfs_header_owner(path->nodes[level])); ++ parent = 0; ++ } ++ ++ ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, ++ root->root_key.objectid, level - 1, 0); ++ BUG_ON(ret); ++ ++ btrfs_tree_unlock(next); ++ free_extent_buffer(next); ++ return 1; ++} ++ ++/* + * hepler to process tree block while walking up the tree. + * + * when wc->stage == DROP_REFERENCE, this function drops +@@ -4904,7 +4788,6 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, + if (level < wc->shared_level) + goto out; + +- BUG_ON(wc->refs[level] <= 1); + ret = find_next_key(path, level + 1, &wc->update_progress); + if (ret > 0) + wc->update_ref = 0; +@@ -4935,8 +4818,6 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, + path->locks[level] = 0; + return 1; + } +- } else { +- BUG_ON(level != 0); + } + } + +@@ -4989,17 +4870,13 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, + struct btrfs_path *path, + struct walk_control *wc) + { +- struct extent_buffer *next; +- struct extent_buffer *cur; +- u64 bytenr; +- u64 ptr_gen; +- u32 blocksize; + int level = wc->level; + int ret; + + while (level >= 0) { +- cur = path->nodes[level]; +- BUG_ON(path->slots[level] >= btrfs_header_nritems(cur)); ++ if (path->slots[level] >= ++ btrfs_header_nritems(path->nodes[level])) ++ break; + + ret = walk_down_proc(trans, root, path, wc); + if (ret > 0) +@@ -5008,20 +4885,12 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans, + if (level == 0) + break; + +- bytenr = btrfs_node_blockptr(cur, path->slots[level]); +- blocksize = btrfs_level_size(root, level - 1); +- ptr_gen = btrfs_node_ptr_generation(cur, path->slots[level]); +- +- next = read_tree_block(root, bytenr, blocksize, ptr_gen); +- btrfs_tree_lock(next); +- btrfs_set_lock_blocking(next); +- +- level--; +- BUG_ON(level != btrfs_header_level(next)); +- path->nodes[level] = next; +- path->slots[level] = 0; +- path->locks[level] = 1; +- wc->level = level; ++ ret = do_walk_down(trans, root, path, wc); ++ if (ret > 0) { ++ path->slots[level]++; ++ continue; ++ } ++ level = wc->level; + } + return 0; + } +@@ -5111,9 +4980,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) + err = ret; + goto out; + } +- btrfs_node_key_to_cpu(path->nodes[level], &key, +- path->slots[level]); +- WARN_ON(memcmp(&key, &wc->update_progress, sizeof(key))); ++ WARN_ON(ret > 0); + + /* + * unlock our path, this is safe because only this +@@ -5148,6 +5015,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) + wc->stage = DROP_REFERENCE; + wc->update_ref = update_ref; + wc->keep_locks = 0; ++ wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); + + while (1) { + ret = walk_down_tree(trans, root, path, wc); +@@ -5200,9 +5068,24 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) + ret = btrfs_del_root(trans, tree_root, &root->root_key); + BUG_ON(ret); + +- free_extent_buffer(root->node); +- free_extent_buffer(root->commit_root); +- kfree(root); ++ if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID) { ++ ret = btrfs_find_last_root(tree_root, root->root_key.objectid, ++ NULL, NULL); ++ BUG_ON(ret < 0); ++ if (ret > 0) { ++ ret = btrfs_del_orphan_item(trans, tree_root, ++ root->root_key.objectid); ++ BUG_ON(ret); ++ } ++ } ++ ++ if (root->in_radix) { ++ btrfs_free_fs_root(tree_root->fs_info, root); ++ } else { ++ free_extent_buffer(root->node); ++ free_extent_buffer(root->commit_root); ++ kfree(root); ++ } + out: + btrfs_end_transaction(trans, tree_root); + kfree(wc); +@@ -5254,6 +5137,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, + wc->stage = DROP_REFERENCE; + wc->update_ref = 0; + wc->keep_locks = 1; ++ wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); + + while (1) { + wret = walk_down_tree(trans, root, path, wc); +@@ -5396,9 +5280,9 @@ static noinline int relocate_data_extent(struct inode *reloc_inode, + lock_extent(&BTRFS_I(reloc_inode)->io_tree, start, end, GFP_NOFS); + while (1) { + int ret; +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + if (ret != -EEXIST) { + free_extent_map(em); + break; +@@ -6841,287 +6725,86 @@ int btrfs_prepare_block_group_relocation(struct btrfs_root *root, + return 0; + } + +-#if 0 +-static int __insert_orphan_inode(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- u64 objectid, u64 size) +-{ +- struct btrfs_path *path; +- struct btrfs_inode_item *item; +- struct extent_buffer *leaf; +- int ret; +- +- path = btrfs_alloc_path(); +- if (!path) +- return -ENOMEM; +- +- path->leave_spinning = 1; +- ret = btrfs_insert_empty_inode(trans, root, path, objectid); +- if (ret) +- goto out; +- +- leaf = path->nodes[0]; +- item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item); +- memset_extent_buffer(leaf, 0, (unsigned long)item, sizeof(*item)); +- btrfs_set_inode_generation(leaf, item, 1); +- btrfs_set_inode_size(leaf, item, size); +- btrfs_set_inode_mode(leaf, item, S_IFREG | 0600); +- btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS); +- btrfs_mark_buffer_dirty(leaf); +- btrfs_release_path(root, path); +-out: +- btrfs_free_path(path); +- return ret; +-} +- +-static noinline struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, +- struct btrfs_block_group_cache *group) ++/* ++ * checks to see if its even possible to relocate this block group. ++ * ++ * @return - -1 if it's not a good idea to relocate this block group, 0 if its ++ * ok to go ahead and try. ++ */ ++int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) + { +- struct inode *inode = NULL; +- struct btrfs_trans_handle *trans; +- struct btrfs_root *root; +- struct btrfs_key root_key; +- u64 objectid = BTRFS_FIRST_FREE_OBJECTID; +- int err = 0; ++ struct btrfs_block_group_cache *block_group; ++ struct btrfs_space_info *space_info; ++ struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; ++ struct btrfs_device *device; ++ int full = 0; ++ int ret = 0; + +- root_key.objectid = BTRFS_DATA_RELOC_TREE_OBJECTID; +- root_key.type = BTRFS_ROOT_ITEM_KEY; +- root_key.offset = (u64)-1; +- root = btrfs_read_fs_root_no_name(fs_info, &root_key); +- if (IS_ERR(root)) +- return ERR_CAST(root); ++ block_group = btrfs_lookup_block_group(root->fs_info, bytenr); + +- trans = btrfs_start_transaction(root, 1); +- BUG_ON(!trans); ++ /* odd, couldn't find the block group, leave it alone */ ++ if (!block_group) ++ return -1; + +- err = btrfs_find_free_objectid(trans, root, objectid, &objectid); +- if (err) ++ /* no bytes used, we're good */ ++ if (!btrfs_block_group_used(&block_group->item)) + goto out; + +- err = __insert_orphan_inode(trans, root, objectid, group->key.offset); +- BUG_ON(err); +- +- err = btrfs_insert_file_extent(trans, root, objectid, 0, 0, 0, +- group->key.offset, 0, group->key.offset, +- 0, 0, 0); +- BUG_ON(err); +- +- inode = btrfs_iget_locked(root->fs_info->sb, objectid, root); +- if (inode->i_state & I_NEW) { +- BTRFS_I(inode)->root = root; +- BTRFS_I(inode)->location.objectid = objectid; +- BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; +- BTRFS_I(inode)->location.offset = 0; +- btrfs_read_locked_inode(inode); +- unlock_new_inode(inode); +- BUG_ON(is_bad_inode(inode)); +- } else { +- BUG_ON(1); +- } +- BTRFS_I(inode)->index_cnt = group->key.objectid; +- +- err = btrfs_orphan_add(trans, inode); +-out: +- btrfs_end_transaction(trans, root); +- if (err) { +- if (inode) +- iput(inode); +- inode = ERR_PTR(err); +- } +- return inode; +-} +- +-int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len) +-{ +- +- struct btrfs_ordered_sum *sums; +- struct btrfs_sector_sum *sector_sum; +- struct btrfs_ordered_extent *ordered; +- struct btrfs_root *root = BTRFS_I(inode)->root; +- struct list_head list; +- size_t offset; +- int ret; +- u64 disk_bytenr; +- +- INIT_LIST_HEAD(&list); +- +- ordered = btrfs_lookup_ordered_extent(inode, file_pos); +- BUG_ON(ordered->file_offset != file_pos || ordered->len != len); +- +- disk_bytenr = file_pos + BTRFS_I(inode)->index_cnt; +- ret = btrfs_lookup_csums_range(root->fs_info->csum_root, disk_bytenr, +- disk_bytenr + len - 1, &list); +- +- while (!list_empty(&list)) { +- sums = list_entry(list.next, struct btrfs_ordered_sum, list); +- list_del_init(&sums->list); +- +- sector_sum = sums->sums; +- sums->bytenr = ordered->start; ++ space_info = block_group->space_info; ++ spin_lock(&space_info->lock); + +- offset = 0; +- while (offset < sums->len) { +- sector_sum->bytenr += ordered->start - disk_bytenr; +- sector_sum++; +- offset += root->sectorsize; +- } ++ full = space_info->full; + +- btrfs_add_ordered_sum(inode, ordered, sums); ++ /* ++ * if this is the last block group we have in this space, we can't ++ * relocate it unless we're able to allocate a new chunk below. ++ * ++ * Otherwise, we need to make sure we have room in the space to handle ++ * all of the extents from this block group. If we can, we're good ++ */ ++ if ((space_info->total_bytes != block_group->key.offset) && ++ (space_info->bytes_used + space_info->bytes_reserved + ++ space_info->bytes_pinned + space_info->bytes_readonly + ++ btrfs_block_group_used(&block_group->item) < ++ space_info->total_bytes)) { ++ spin_unlock(&space_info->lock); ++ goto out; + } +- btrfs_put_ordered_extent(ordered); +- return 0; +-} +- +-int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start) +-{ +- struct btrfs_trans_handle *trans; +- struct btrfs_path *path; +- struct btrfs_fs_info *info = root->fs_info; +- struct extent_buffer *leaf; +- struct inode *reloc_inode; +- struct btrfs_block_group_cache *block_group; +- struct btrfs_key key; +- u64 skipped; +- u64 cur_byte; +- u64 total_found; +- u32 nritems; +- int ret; +- int progress; +- int pass = 0; +- +- root = root->fs_info->extent_root; +- +- block_group = btrfs_lookup_block_group(info, group_start); +- BUG_ON(!block_group); +- +- printk(KERN_INFO "btrfs relocating block group %llu flags %llu\n", +- (unsigned long long)block_group->key.objectid, +- (unsigned long long)block_group->flags); +- +- path = btrfs_alloc_path(); +- BUG_ON(!path); +- +- reloc_inode = create_reloc_inode(info, block_group); +- BUG_ON(IS_ERR(reloc_inode)); +- +- __alloc_chunk_for_shrink(root, block_group, 1); +- set_block_group_readonly(block_group); +- +- btrfs_start_delalloc_inodes(info->tree_root); +- btrfs_wait_ordered_extents(info->tree_root, 0); +-again: +- skipped = 0; +- total_found = 0; +- progress = 0; +- key.objectid = block_group->key.objectid; +- key.offset = 0; +- key.type = 0; +- cur_byte = key.objectid; +- +- trans = btrfs_start_transaction(info->tree_root, 1); +- btrfs_commit_transaction(trans, info->tree_root); ++ spin_unlock(&space_info->lock); + +- mutex_lock(&root->fs_info->cleaner_mutex); +- btrfs_clean_old_snapshots(info->tree_root); +- btrfs_remove_leaf_refs(info->tree_root, (u64)-1, 1); +- mutex_unlock(&root->fs_info->cleaner_mutex); ++ /* ++ * ok we don't have enough space, but maybe we have free space on our ++ * devices to allocate new chunks for relocation, so loop through our ++ * alloc devices and guess if we have enough space. However, if we ++ * were marked as full, then we know there aren't enough chunks, and we ++ * can just return. ++ */ ++ ret = -1; ++ if (full) ++ goto out; + +- trans = btrfs_start_transaction(info->tree_root, 1); +- btrfs_commit_transaction(trans, info->tree_root); ++ mutex_lock(&root->fs_info->chunk_mutex); ++ list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { ++ u64 min_free = btrfs_block_group_used(&block_group->item); ++ u64 dev_offset, max_avail; + +- while (1) { +- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); +- if (ret < 0) +- goto out; +-next: +- leaf = path->nodes[0]; +- nritems = btrfs_header_nritems(leaf); +- if (path->slots[0] >= nritems) { +- ret = btrfs_next_leaf(root, path); +- if (ret < 0) +- goto out; +- if (ret == 1) { +- ret = 0; ++ /* ++ * check to make sure we can actually find a chunk with enough ++ * space to fit our block group in. ++ */ ++ if (device->total_bytes > device->bytes_used + min_free) { ++ ret = find_free_dev_extent(NULL, device, min_free, ++ &dev_offset, &max_avail); ++ if (!ret) + break; +- } +- leaf = path->nodes[0]; +- nritems = btrfs_header_nritems(leaf); ++ ret = -1; + } +- +- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); +- +- if (key.objectid >= block_group->key.objectid + +- block_group->key.offset) +- break; +- +- if (progress && need_resched()) { +- btrfs_release_path(root, path); +- cond_resched(); +- progress = 0; +- continue; +- } +- progress = 1; +- +- if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY || +- key.objectid + key.offset <= cur_byte) { +- path->slots[0]++; +- goto next; +- } +- +- total_found++; +- cur_byte = key.objectid + key.offset; +- btrfs_release_path(root, path); +- +- __alloc_chunk_for_shrink(root, block_group, 0); +- ret = relocate_one_extent(root, path, &key, block_group, +- reloc_inode, pass); +- BUG_ON(ret < 0); +- if (ret > 0) +- skipped++; +- +- key.objectid = cur_byte; +- key.type = 0; +- key.offset = 0; +- } +- +- btrfs_release_path(root, path); +- +- if (pass == 0) { +- btrfs_wait_ordered_range(reloc_inode, 0, (u64)-1); +- invalidate_mapping_pages(reloc_inode->i_mapping, 0, -1); +- } +- +- if (total_found > 0) { +- printk(KERN_INFO "btrfs found %llu extents in pass %d\n", +- (unsigned long long)total_found, pass); +- pass++; +- if (total_found == skipped && pass > 2) { +- iput(reloc_inode); +- reloc_inode = create_reloc_inode(info, block_group); +- pass = 0; +- } +- goto again; + } +- +- /* delete reloc_inode */ +- iput(reloc_inode); +- +- /* unpin extents in this range */ +- trans = btrfs_start_transaction(info->tree_root, 1); +- btrfs_commit_transaction(trans, info->tree_root); +- +- spin_lock(&block_group->lock); +- WARN_ON(block_group->pinned > 0); +- WARN_ON(block_group->reserved > 0); +- WARN_ON(btrfs_block_group_used(&block_group->item) > 0); +- spin_unlock(&block_group->lock); +- btrfs_put_block_group(block_group); +- ret = 0; ++ mutex_unlock(&root->fs_info->chunk_mutex); + out: +- btrfs_free_path(path); ++ btrfs_put_block_group(block_group); + return ret; + } +-#endif + + static int find_first_block_group(struct btrfs_root *root, + struct btrfs_path *path, struct btrfs_key *key) +@@ -7164,8 +6847,18 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) + { + struct btrfs_block_group_cache *block_group; + struct btrfs_space_info *space_info; ++ struct btrfs_caching_control *caching_ctl; + struct rb_node *n; + ++ down_write(&info->extent_commit_sem); ++ while (!list_empty(&info->caching_block_groups)) { ++ caching_ctl = list_entry(info->caching_block_groups.next, ++ struct btrfs_caching_control, list); ++ list_del(&caching_ctl->list); ++ put_caching_control(caching_ctl); ++ } ++ up_write(&info->extent_commit_sem); ++ + spin_lock(&info->block_group_cache_lock); + while ((n = rb_last(&info->block_group_cache_tree)) != NULL) { + block_group = rb_entry(n, struct btrfs_block_group_cache, +@@ -7179,8 +6872,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) + up_write(&block_group->space_info->groups_sem); + + if (block_group->cached == BTRFS_CACHE_STARTED) +- wait_event(block_group->caching_q, +- block_group_cache_done(block_group)); ++ wait_block_group_cache_done(block_group); + + btrfs_remove_free_space_cache(block_group); + +@@ -7250,7 +6942,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) + spin_lock_init(&cache->lock); + spin_lock_init(&cache->tree_lock); + cache->fs_info = info; +- init_waitqueue_head(&cache->caching_q); + INIT_LIST_HEAD(&cache->list); + INIT_LIST_HEAD(&cache->cluster_list); + +@@ -7272,8 +6963,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) + cache->flags = btrfs_block_group_flags(&cache->item); + cache->sectorsize = root->sectorsize; + +- remove_sb_from_cache(root, cache); +- + /* + * check for two cases, either we are full, and therefore + * don't need to bother with the caching work since we won't +@@ -7282,13 +6971,19 @@ int btrfs_read_block_groups(struct btrfs_root *root) + * time, particularly in the full case. + */ + if (found_key.offset == btrfs_block_group_used(&cache->item)) { ++ exclude_super_stripes(root, cache); ++ cache->last_byte_to_unpin = (u64)-1; + cache->cached = BTRFS_CACHE_FINISHED; ++ free_excluded_extents(root, cache); + } else if (btrfs_block_group_used(&cache->item) == 0) { ++ exclude_super_stripes(root, cache); ++ cache->last_byte_to_unpin = (u64)-1; + cache->cached = BTRFS_CACHE_FINISHED; + add_new_free_space(cache, root->fs_info, + found_key.objectid, + found_key.objectid + + found_key.offset); ++ free_excluded_extents(root, cache); + } + + ret = update_space_info(info, cache->flags, found_key.offset, +@@ -7296,6 +6991,10 @@ int btrfs_read_block_groups(struct btrfs_root *root) + &space_info); + BUG_ON(ret); + cache->space_info = space_info; ++ spin_lock(&cache->space_info->lock); ++ cache->space_info->bytes_super += cache->bytes_super; ++ spin_unlock(&cache->space_info->lock); ++ + down_write(&space_info->groups_sem); + list_add_tail(&cache->list, &space_info->block_groups); + up_write(&space_info->groups_sem); +@@ -7345,7 +7044,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, + atomic_set(&cache->count, 1); + spin_lock_init(&cache->lock); + spin_lock_init(&cache->tree_lock); +- init_waitqueue_head(&cache->caching_q); + INIT_LIST_HEAD(&cache->list); + INIT_LIST_HEAD(&cache->cluster_list); + +@@ -7354,15 +7052,23 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, + cache->flags = type; + btrfs_set_block_group_flags(&cache->item, type); + ++ cache->last_byte_to_unpin = (u64)-1; + cache->cached = BTRFS_CACHE_FINISHED; +- remove_sb_from_cache(root, cache); ++ exclude_super_stripes(root, cache); + + add_new_free_space(cache, root->fs_info, chunk_offset, + chunk_offset + size); + ++ free_excluded_extents(root, cache); ++ + ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, + &cache->space_info); + BUG_ON(ret); ++ ++ spin_lock(&cache->space_info->lock); ++ cache->space_info->bytes_super += cache->bytes_super; ++ spin_unlock(&cache->space_info->lock); ++ + down_write(&cache->space_info->groups_sem); + list_add_tail(&cache->list, &cache->space_info->block_groups); + up_write(&cache->space_info->groups_sem); +@@ -7428,8 +7134,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, + up_write(&block_group->space_info->groups_sem); + + if (block_group->cached == BTRFS_CACHE_STARTED) +- wait_event(block_group->caching_q, +- block_group_cache_done(block_group)); ++ wait_block_group_cache_done(block_group); + + btrfs_remove_free_space_cache(block_group); + +diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c +index 6826018..0cb88f8 100644 +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -367,10 +367,10 @@ static int insert_state(struct extent_io_tree *tree, + } + if (bits & EXTENT_DIRTY) + tree->dirty_bytes += end - start + 1; +- set_state_cb(tree, state, bits); +- state->state |= bits; + state->start = start; + state->end = end; ++ set_state_cb(tree, state, bits); ++ state->state |= bits; + node = tree_insert(&tree->state, end, &state->rb_node); + if (node) { + struct extent_state *found; +@@ -471,10 +471,14 @@ static int clear_state_bit(struct extent_io_tree *tree, + * bits were already set, or zero if none of the bits were already set. + */ + int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +- int bits, int wake, int delete, gfp_t mask) ++ int bits, int wake, int delete, ++ struct extent_state **cached_state, ++ gfp_t mask) + { + struct extent_state *state; ++ struct extent_state *cached; + struct extent_state *prealloc = NULL; ++ struct rb_node *next_node; + struct rb_node *node; + u64 last_end; + int err; +@@ -488,6 +492,17 @@ again: + } + + spin_lock(&tree->lock); ++ if (cached_state) { ++ cached = *cached_state; ++ *cached_state = NULL; ++ cached_state = NULL; ++ if (cached && cached->tree && cached->start == start) { ++ atomic_dec(&cached->refs); ++ state = cached; ++ goto hit_next; ++ } ++ free_extent_state(cached); ++ } + /* + * this search will find the extents that end after + * our range starts +@@ -496,6 +511,7 @@ again: + if (!node) + goto out; + state = rb_entry(node, struct extent_state, rb_node); ++hit_next: + if (state->start > end) + goto out; + WARN_ON(state->end < start); +@@ -531,8 +547,6 @@ again: + if (last_end == (u64)-1) + goto out; + start = last_end + 1; +- } else { +- start = state->start; + } + goto search_again; + } +@@ -550,16 +564,28 @@ again: + + if (wake) + wake_up(&state->wq); ++ + set |= clear_state_bit(tree, prealloc, bits, + wake, delete); + prealloc = NULL; + goto out; + } + ++ if (state->end < end && prealloc && !need_resched()) ++ next_node = rb_next(&state->rb_node); ++ else ++ next_node = NULL; ++ + set |= clear_state_bit(tree, state, bits, wake, delete); + if (last_end == (u64)-1) + goto out; + start = last_end + 1; ++ if (start <= end && next_node) { ++ state = rb_entry(next_node, struct extent_state, ++ rb_node); ++ if (state->start == start) ++ goto hit_next; ++ } + goto search_again; + + out: +@@ -653,28 +679,40 @@ static void set_state_bits(struct extent_io_tree *tree, + state->state |= bits; + } + ++static void cache_state(struct extent_state *state, ++ struct extent_state **cached_ptr) ++{ ++ if (cached_ptr && !(*cached_ptr)) { ++ if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) { ++ *cached_ptr = state; ++ atomic_inc(&state->refs); ++ } ++ } ++} ++ + /* +- * set some bits on a range in the tree. This may require allocations +- * or sleeping, so the gfp mask is used to indicate what is allowed. ++ * set some bits on a range in the tree. This may require allocations or ++ * sleeping, so the gfp mask is used to indicate what is allowed. + * +- * If 'exclusive' == 1, this will fail with -EEXIST if some part of the +- * range already has the desired bits set. The start of the existing +- * range is returned in failed_start in this case. ++ * If any of the exclusive bits are set, this will fail with -EEXIST if some ++ * part of the range already has the desired bits set. The start of the ++ * existing range is returned in failed_start in this case. + * +- * [start, end] is inclusive +- * This takes the tree lock. ++ * [start, end] is inclusive This takes the tree lock. + */ ++ + static int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +- int bits, int exclusive, u64 *failed_start, ++ int bits, int exclusive_bits, u64 *failed_start, ++ struct extent_state **cached_state, + gfp_t mask) + { + struct extent_state *state; + struct extent_state *prealloc = NULL; + struct rb_node *node; + int err = 0; +- int set; + u64 last_start; + u64 last_end; ++ + again: + if (!prealloc && (mask & __GFP_WAIT)) { + prealloc = alloc_extent_state(mask); +@@ -683,6 +721,13 @@ again: + } + + spin_lock(&tree->lock); ++ if (cached_state && *cached_state) { ++ state = *cached_state; ++ if (state->start == start && state->tree) { ++ node = &state->rb_node; ++ goto hit_next; ++ } ++ } + /* + * this search will find all the extents that end after + * our range starts. +@@ -694,8 +739,8 @@ again: + BUG_ON(err == -EEXIST); + goto out; + } +- + state = rb_entry(node, struct extent_state, rb_node); ++hit_next: + last_start = state->start; + last_end = state->end; + +@@ -706,17 +751,29 @@ again: + * Just lock what we found and keep going + */ + if (state->start == start && state->end <= end) { +- set = state->state & bits; +- if (set && exclusive) { ++ struct rb_node *next_node; ++ if (state->state & exclusive_bits) { + *failed_start = state->start; + err = -EEXIST; + goto out; + } ++ + set_state_bits(tree, state, bits); ++ cache_state(state, cached_state); + merge_state(tree, state); + if (last_end == (u64)-1) + goto out; ++ + start = last_end + 1; ++ if (start < end && prealloc && !need_resched()) { ++ next_node = rb_next(node); ++ if (next_node) { ++ state = rb_entry(next_node, struct extent_state, ++ rb_node); ++ if (state->start == start) ++ goto hit_next; ++ } ++ } + goto search_again; + } + +@@ -737,8 +794,7 @@ again: + * desired bit on it. + */ + if (state->start < start) { +- set = state->state & bits; +- if (exclusive && set) { ++ if (state->state & exclusive_bits) { + *failed_start = start; + err = -EEXIST; + goto out; +@@ -750,12 +806,11 @@ again: + goto out; + if (state->end <= end) { + set_state_bits(tree, state, bits); ++ cache_state(state, cached_state); + merge_state(tree, state); + if (last_end == (u64)-1) + goto out; + start = last_end + 1; +- } else { +- start = state->start; + } + goto search_again; + } +@@ -774,6 +829,7 @@ again: + this_end = last_start - 1; + err = insert_state(tree, prealloc, start, this_end, + bits); ++ cache_state(prealloc, cached_state); + prealloc = NULL; + BUG_ON(err == -EEXIST); + if (err) +@@ -788,8 +844,7 @@ again: + * on the first half + */ + if (state->start <= end && state->end > end) { +- set = state->state & bits; +- if (exclusive && set) { ++ if (state->state & exclusive_bits) { + *failed_start = start; + err = -EEXIST; + goto out; +@@ -798,6 +853,7 @@ again: + BUG_ON(err == -EEXIST); + + set_state_bits(tree, prealloc, bits); ++ cache_state(prealloc, cached_state); + merge_state(tree, prealloc); + prealloc = NULL; + goto out; +@@ -826,86 +882,64 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + return set_extent_bit(tree, start, end, EXTENT_DIRTY, 0, NULL, +- mask); +-} +- +-int set_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, +- gfp_t mask) +-{ +- return set_extent_bit(tree, start, end, EXTENT_ORDERED, 0, NULL, mask); ++ NULL, mask); + } + + int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, + int bits, gfp_t mask) + { + return set_extent_bit(tree, start, end, bits, 0, NULL, +- mask); ++ NULL, mask); + } + + int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, + int bits, gfp_t mask) + { +- return clear_extent_bit(tree, start, end, bits, 0, 0, mask); ++ return clear_extent_bit(tree, start, end, bits, 0, 0, NULL, mask); + } + + int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + return set_extent_bit(tree, start, end, +- EXTENT_DELALLOC | EXTENT_DIRTY, +- 0, NULL, mask); ++ EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE, ++ 0, NULL, NULL, mask); + } + + int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + return clear_extent_bit(tree, start, end, +- EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, mask); +-} +- +-int clear_extent_ordered(struct extent_io_tree *tree, u64 start, u64 end, +- gfp_t mask) +-{ +- return clear_extent_bit(tree, start, end, EXTENT_ORDERED, 1, 0, mask); ++ EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, ++ NULL, mask); + } + + int set_extent_new(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + return set_extent_bit(tree, start, end, EXTENT_NEW, 0, NULL, +- mask); ++ NULL, mask); + } + + static int clear_extent_new(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { +- return clear_extent_bit(tree, start, end, EXTENT_NEW, 0, 0, mask); ++ return clear_extent_bit(tree, start, end, EXTENT_NEW, 0, 0, ++ NULL, mask); + } + + int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + return set_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, NULL, +- mask); ++ NULL, mask); + } + + static int clear_extent_uptodate(struct extent_io_tree *tree, u64 start, + u64 end, gfp_t mask) + { +- return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0, mask); +-} +- +-static int set_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end, +- gfp_t mask) +-{ +- return set_extent_bit(tree, start, end, EXTENT_WRITEBACK, +- 0, NULL, mask); +-} +- +-static int clear_extent_writeback(struct extent_io_tree *tree, u64 start, +- u64 end, gfp_t mask) +-{ +- return clear_extent_bit(tree, start, end, EXTENT_WRITEBACK, 1, 0, mask); ++ return clear_extent_bit(tree, start, end, EXTENT_UPTODATE, 0, 0, ++ NULL, mask); + } + + int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) +@@ -917,13 +951,15 @@ int wait_on_extent_writeback(struct extent_io_tree *tree, u64 start, u64 end) + * either insert or lock state struct between start and end use mask to tell + * us if waiting is desired. + */ +-int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) ++int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, ++ int bits, struct extent_state **cached_state, gfp_t mask) + { + int err; + u64 failed_start; + while (1) { +- err = set_extent_bit(tree, start, end, EXTENT_LOCKED, 1, +- &failed_start, mask); ++ err = set_extent_bit(tree, start, end, EXTENT_LOCKED | bits, ++ EXTENT_LOCKED, &failed_start, ++ cached_state, mask); + if (err == -EEXIST && (mask & __GFP_WAIT)) { + wait_extent_bit(tree, failed_start, end, EXTENT_LOCKED); + start = failed_start; +@@ -935,27 +971,40 @@ int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) + return err; + } + ++int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask) ++{ ++ return lock_extent_bits(tree, start, end, 0, NULL, mask); ++} ++ + int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { + int err; + u64 failed_start; + +- err = set_extent_bit(tree, start, end, EXTENT_LOCKED, 1, +- &failed_start, mask); ++ err = set_extent_bit(tree, start, end, EXTENT_LOCKED, EXTENT_LOCKED, ++ &failed_start, NULL, mask); + if (err == -EEXIST) { + if (failed_start > start) + clear_extent_bit(tree, start, failed_start - 1, +- EXTENT_LOCKED, 1, 0, mask); ++ EXTENT_LOCKED, 1, 0, NULL, mask); + return 0; + } + return 1; + } + ++int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, ++ struct extent_state **cached, gfp_t mask) ++{ ++ return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, cached, ++ mask); ++} ++ + int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask) + { +- return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, mask); ++ return clear_extent_bit(tree, start, end, EXTENT_LOCKED, 1, 0, NULL, ++ mask); + } + + /* +@@ -974,7 +1023,6 @@ int set_range_dirty(struct extent_io_tree *tree, u64 start, u64 end) + page_cache_release(page); + index++; + } +- set_extent_dirty(tree, start, end, GFP_NOFS); + return 0; + } + +@@ -994,7 +1042,6 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) + page_cache_release(page); + index++; + } +- set_extent_writeback(tree, start, end, GFP_NOFS); + return 0; + } + +@@ -1232,6 +1279,7 @@ static noinline u64 find_lock_delalloc_range(struct inode *inode, + u64 delalloc_start; + u64 delalloc_end; + u64 found; ++ struct extent_state *cached_state = NULL; + int ret; + int loops = 0; + +@@ -1269,6 +1317,7 @@ again: + /* some of the pages are gone, lets avoid looping by + * shortening the size of the delalloc range we're searching + */ ++ free_extent_state(cached_state); + if (!loops) { + unsigned long offset = (*start) & (PAGE_CACHE_SIZE - 1); + max_bytes = PAGE_CACHE_SIZE - offset; +@@ -1282,18 +1331,21 @@ again: + BUG_ON(ret); + + /* step three, lock the state bits for the whole range */ +- lock_extent(tree, delalloc_start, delalloc_end, GFP_NOFS); ++ lock_extent_bits(tree, delalloc_start, delalloc_end, ++ 0, &cached_state, GFP_NOFS); + + /* then test to make sure it is all still delalloc */ + ret = test_range_bit(tree, delalloc_start, delalloc_end, +- EXTENT_DELALLOC, 1); ++ EXTENT_DELALLOC, 1, cached_state); + if (!ret) { +- unlock_extent(tree, delalloc_start, delalloc_end, GFP_NOFS); ++ unlock_extent_cached(tree, delalloc_start, delalloc_end, ++ &cached_state, GFP_NOFS); + __unlock_for_delalloc(inode, locked_page, + delalloc_start, delalloc_end); + cond_resched(); + goto again; + } ++ free_extent_state(cached_state); + *start = delalloc_start; + *end = delalloc_end; + out_failed: +@@ -1307,7 +1359,8 @@ int extent_clear_unlock_delalloc(struct inode *inode, + int clear_unlock, + int clear_delalloc, int clear_dirty, + int set_writeback, +- int end_writeback) ++ int end_writeback, ++ int set_private2) + { + int ret; + struct page *pages[16]; +@@ -1325,8 +1378,9 @@ int extent_clear_unlock_delalloc(struct inode *inode, + if (clear_delalloc) + clear_bits |= EXTENT_DELALLOC; + +- clear_extent_bit(tree, start, end, clear_bits, 1, 0, GFP_NOFS); +- if (!(unlock_pages || clear_dirty || set_writeback || end_writeback)) ++ clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); ++ if (!(unlock_pages || clear_dirty || set_writeback || end_writeback || ++ set_private2)) + return 0; + + while (nr_pages > 0) { +@@ -1334,6 +1388,10 @@ int extent_clear_unlock_delalloc(struct inode *inode, + min_t(unsigned long, + nr_pages, ARRAY_SIZE(pages)), pages); + for (i = 0; i < ret; i++) { ++ ++ if (set_private2) ++ SetPagePrivate2(pages[i]); ++ + if (pages[i] == locked_page) { + page_cache_release(pages[i]); + continue; +@@ -1476,14 +1534,17 @@ out: + * range is found set. + */ + int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, +- int bits, int filled) ++ int bits, int filled, struct extent_state *cached) + { + struct extent_state *state = NULL; + struct rb_node *node; + int bitset = 0; + + spin_lock(&tree->lock); +- node = tree_search(tree, start); ++ if (cached && cached->tree && cached->start == start) ++ node = &cached->rb_node; ++ else ++ node = tree_search(tree, start); + while (node && start <= end) { + state = rb_entry(node, struct extent_state, rb_node); + +@@ -1503,6 +1564,10 @@ int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, + bitset = 0; + break; + } ++ ++ if (state->end == (u64)-1) ++ break; ++ + start = state->end + 1; + if (start > end) + break; +@@ -1526,7 +1591,7 @@ static int check_page_uptodate(struct extent_io_tree *tree, + { + u64 start = (u64)page->index << PAGE_CACHE_SHIFT; + u64 end = start + PAGE_CACHE_SIZE - 1; +- if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1)) ++ if (test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL)) + SetPageUptodate(page); + return 0; + } +@@ -1540,7 +1605,7 @@ static int check_page_locked(struct extent_io_tree *tree, + { + u64 start = (u64)page->index << PAGE_CACHE_SHIFT; + u64 end = start + PAGE_CACHE_SIZE - 1; +- if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0)) ++ if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL)) + unlock_page(page); + return 0; + } +@@ -1552,10 +1617,7 @@ static int check_page_locked(struct extent_io_tree *tree, + static int check_page_writeback(struct extent_io_tree *tree, + struct page *page) + { +- u64 start = (u64)page->index << PAGE_CACHE_SHIFT; +- u64 end = start + PAGE_CACHE_SIZE - 1; +- if (!test_range_bit(tree, start, end, EXTENT_WRITEBACK, 0)) +- end_page_writeback(page); ++ end_page_writeback(page); + return 0; + } + +@@ -1613,13 +1675,11 @@ static void end_bio_extent_writepage(struct bio *bio, int err) + } + + if (!uptodate) { +- clear_extent_uptodate(tree, start, end, GFP_ATOMIC); ++ clear_extent_uptodate(tree, start, end, GFP_NOFS); + ClearPageUptodate(page); + SetPageError(page); + } + +- clear_extent_writeback(tree, start, end, GFP_ATOMIC); +- + if (whole_page) + end_page_writeback(page); + else +@@ -1983,7 +2043,8 @@ static int __extent_read_full_page(struct extent_io_tree *tree, + continue; + } + /* the get_extent function already copied into the page */ +- if (test_range_bit(tree, cur, cur_end, EXTENT_UPTODATE, 1)) { ++ if (test_range_bit(tree, cur, cur_end, ++ EXTENT_UPTODATE, 1, NULL)) { + check_page_uptodate(tree, page); + unlock_extent(tree, cur, cur + iosize - 1, GFP_NOFS); + cur = cur + iosize; +@@ -2078,6 +2139,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + u64 iosize; + u64 unlock_start; + sector_t sector; ++ struct extent_state *cached_state = NULL; + struct extent_map *em; + struct block_device *bdev; + int ret; +@@ -2124,6 +2186,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + delalloc_end = 0; + page_started = 0; + if (!epd->extent_locked) { ++ u64 delalloc_to_write = 0; + /* + * make sure the wbc mapping index is at least updated + * to this page. +@@ -2143,8 +2206,24 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + tree->ops->fill_delalloc(inode, page, delalloc_start, + delalloc_end, &page_started, + &nr_written); ++ /* ++ * delalloc_end is already one less than the total ++ * length, so we don't subtract one from ++ * PAGE_CACHE_SIZE ++ */ ++ delalloc_to_write += (delalloc_end - delalloc_start + ++ PAGE_CACHE_SIZE) >> ++ PAGE_CACHE_SHIFT; + delalloc_start = delalloc_end + 1; + } ++ if (wbc->nr_to_write < delalloc_to_write) { ++ int thresh = 8192; ++ ++ if (delalloc_to_write < thresh * 2) ++ thresh = delalloc_to_write; ++ wbc->nr_to_write = min_t(u64, delalloc_to_write, ++ thresh); ++ } + + /* did the fill delalloc function already unlock and start + * the IO? +@@ -2160,15 +2239,10 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + goto done_unlocked; + } + } +- lock_extent(tree, start, page_end, GFP_NOFS); +- +- unlock_start = start; +- + if (tree->ops && tree->ops->writepage_start_hook) { + ret = tree->ops->writepage_start_hook(page, start, + page_end); + if (ret == -EAGAIN) { +- unlock_extent(tree, start, page_end, GFP_NOFS); + redirty_page_for_writepage(wbc, page); + update_nr_written(page, wbc, nr_written); + unlock_page(page); +@@ -2184,12 +2258,7 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + update_nr_written(page, wbc, nr_written + 1); + + end = page_end; +- if (test_range_bit(tree, start, page_end, EXTENT_DELALLOC, 0)) +- printk(KERN_ERR "btrfs delalloc bits after lock_extent\n"); +- + if (last_byte <= start) { +- clear_extent_dirty(tree, start, page_end, GFP_NOFS); +- unlock_extent(tree, start, page_end, GFP_NOFS); + if (tree->ops && tree->ops->writepage_end_io_hook) + tree->ops->writepage_end_io_hook(page, start, + page_end, NULL, 1); +@@ -2197,13 +2266,10 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + goto done; + } + +- set_extent_uptodate(tree, start, page_end, GFP_NOFS); + blocksize = inode->i_sb->s_blocksize; + + while (cur <= end) { + if (cur >= last_byte) { +- clear_extent_dirty(tree, cur, page_end, GFP_NOFS); +- unlock_extent(tree, unlock_start, page_end, GFP_NOFS); + if (tree->ops && tree->ops->writepage_end_io_hook) + tree->ops->writepage_end_io_hook(page, cur, + page_end, NULL, 1); +@@ -2235,12 +2301,6 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + */ + if (compressed || block_start == EXTENT_MAP_HOLE || + block_start == EXTENT_MAP_INLINE) { +- clear_extent_dirty(tree, cur, +- cur + iosize - 1, GFP_NOFS); +- +- unlock_extent(tree, unlock_start, cur + iosize - 1, +- GFP_NOFS); +- + /* + * end_io notification does not happen here for + * compressed extents +@@ -2265,13 +2325,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, + } + /* leave this out until we have a page_mkwrite call */ + if (0 && !test_range_bit(tree, cur, cur + iosize - 1, +- EXTENT_DIRTY, 0)) { ++ EXTENT_DIRTY, 0, NULL)) { + cur = cur + iosize; + pg_offset += iosize; + continue; + } + +- clear_extent_dirty(tree, cur, cur + iosize - 1, GFP_NOFS); + if (tree->ops && tree->ops->writepage_io_hook) { + ret = tree->ops->writepage_io_hook(page, cur, + cur + iosize - 1); +@@ -2309,12 +2368,12 @@ done: + set_page_writeback(page); + end_page_writeback(page); + } +- if (unlock_start <= page_end) +- unlock_extent(tree, unlock_start, page_end, GFP_NOFS); + unlock_page(page); + + done_unlocked: + ++ /* drop our reference on any cached states */ ++ free_extent_state(cached_state); + return 0; + } + +@@ -2339,9 +2398,9 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, + writepage_t writepage, void *data, + void (*flush_fn)(void *)) + { +- struct backing_dev_info *bdi = mapping->backing_dev_info; + int ret = 0; + int done = 0; ++ int nr_to_write_done = 0; + struct pagevec pvec; + int nr_pages; + pgoff_t index; +@@ -2361,7 +2420,7 @@ static int extent_write_cache_pages(struct extent_io_tree *tree, + scanned = 1; + } + retry: +- while (!done && (index <= end) && ++ while (!done && !nr_to_write_done && (index <= end) && + (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, min(end - index, + (pgoff_t)PAGEVEC_SIZE-1) + 1))) { +@@ -2412,12 +2471,15 @@ retry: + unlock_page(page); + ret = 0; + } +- if (ret || wbc->nr_to_write <= 0) +- done = 1; +- if (wbc->nonblocking && bdi_write_congested(bdi)) { +- wbc->encountered_congestion = 1; ++ if (ret) + done = 1; +- } ++ ++ /* ++ * the filesystem may choose to bump up nr_to_write. ++ * We have to make sure to honor the new nr_to_write ++ * at any time ++ */ ++ nr_to_write_done = wbc->nr_to_write <= 0; + } + pagevec_release(&pvec); + cond_resched(); +@@ -2604,10 +2666,10 @@ int extent_invalidatepage(struct extent_io_tree *tree, + return 0; + + lock_extent(tree, start, end, GFP_NOFS); +- wait_on_extent_writeback(tree, start, end); ++ wait_on_page_writeback(page); + clear_extent_bit(tree, start, end, + EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, +- 1, 1, GFP_NOFS); ++ 1, 1, NULL, GFP_NOFS); + return 0; + } + +@@ -2687,7 +2749,7 @@ int extent_prepare_write(struct extent_io_tree *tree, + !isnew && !PageUptodate(page) && + (block_off_end > to || block_off_start < from) && + !test_range_bit(tree, block_start, cur_end, +- EXTENT_UPTODATE, 1)) { ++ EXTENT_UPTODATE, 1, NULL)) { + u64 sector; + u64 extent_offset = block_start - em->start; + size_t iosize; +@@ -2701,7 +2763,7 @@ int extent_prepare_write(struct extent_io_tree *tree, + */ + set_extent_bit(tree, block_start, + block_start + iosize - 1, +- EXTENT_LOCKED, 0, NULL, GFP_NOFS); ++ EXTENT_LOCKED, 0, NULL, NULL, GFP_NOFS); + ret = submit_extent_page(READ, tree, page, + sector, iosize, page_offset, em->bdev, + NULL, 1, +@@ -2742,13 +2804,18 @@ int try_release_extent_state(struct extent_map_tree *map, + int ret = 1; + + if (test_range_bit(tree, start, end, +- EXTENT_IOBITS | EXTENT_ORDERED, 0)) ++ EXTENT_IOBITS, 0, NULL)) + ret = 0; + else { + if ((mask & GFP_NOFS) == GFP_NOFS) + mask = GFP_NOFS; +- clear_extent_bit(tree, start, end, EXTENT_UPTODATE, +- 1, 1, mask); ++ /* ++ * at this point we can safely clear everything except the ++ * locked bit and the nodatasum bit ++ */ ++ clear_extent_bit(tree, start, end, ++ ~(EXTENT_LOCKED | EXTENT_NODATASUM), ++ 0, 0, NULL, mask); + } + return ret; + } +@@ -2771,29 +2838,28 @@ int try_release_extent_mapping(struct extent_map_tree *map, + u64 len; + while (start <= end) { + len = end - start + 1; +- spin_lock(&map->lock); ++ write_lock(&map->lock); + em = lookup_extent_mapping(map, start, len); + if (!em || IS_ERR(em)) { +- spin_unlock(&map->lock); ++ write_unlock(&map->lock); + break; + } + if (test_bit(EXTENT_FLAG_PINNED, &em->flags) || + em->start != start) { +- spin_unlock(&map->lock); ++ write_unlock(&map->lock); + free_extent_map(em); + break; + } + if (!test_range_bit(tree, em->start, + extent_map_end(em) - 1, +- EXTENT_LOCKED | EXTENT_WRITEBACK | +- EXTENT_ORDERED, +- 0)) { ++ EXTENT_LOCKED | EXTENT_WRITEBACK, ++ 0, NULL)) { + remove_extent_mapping(map, em); + /* once for the rb tree */ + free_extent_map(em); + } + start = extent_map_end(em); +- spin_unlock(&map->lock); ++ write_unlock(&map->lock); + + /* once for us */ + free_extent_map(em); +@@ -3203,7 +3269,7 @@ int extent_range_uptodate(struct extent_io_tree *tree, + int uptodate; + unsigned long index; + +- ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1); ++ ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL); + if (ret) + return 1; + while (start <= end) { +@@ -3233,7 +3299,7 @@ int extent_buffer_uptodate(struct extent_io_tree *tree, + return 1; + + ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1, +- EXTENT_UPTODATE, 1); ++ EXTENT_UPTODATE, 1, NULL); + if (ret) + return ret; + +@@ -3269,7 +3335,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, + return 0; + + if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, +- EXTENT_UPTODATE, 1)) { ++ EXTENT_UPTODATE, 1, NULL)) { + return 0; + } + +diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h +index 5bc20ab..14ed16f 100644 +--- a/fs/btrfs/extent_io.h ++++ b/fs/btrfs/extent_io.h +@@ -13,10 +13,8 @@ + #define EXTENT_DEFRAG (1 << 6) + #define EXTENT_DEFRAG_DONE (1 << 7) + #define EXTENT_BUFFER_FILLED (1 << 8) +-#define EXTENT_ORDERED (1 << 9) +-#define EXTENT_ORDERED_METADATA (1 << 10) +-#define EXTENT_BOUNDARY (1 << 11) +-#define EXTENT_NODATASUM (1 << 12) ++#define EXTENT_BOUNDARY (1 << 9) ++#define EXTENT_NODATASUM (1 << 10) + #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) + + /* flags for bio submission */ +@@ -142,6 +140,8 @@ int try_release_extent_state(struct extent_map_tree *map, + struct extent_io_tree *tree, struct page *page, + gfp_t mask); + int lock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); ++int lock_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, ++ int bits, struct extent_state **cached, gfp_t mask); + int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end, gfp_t mask); + int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, + gfp_t mask); +@@ -155,11 +155,12 @@ u64 count_range_bits(struct extent_io_tree *tree, + u64 max_bytes, unsigned long bits); + + int test_range_bit(struct extent_io_tree *tree, u64 start, u64 end, +- int bits, int filled); ++ int bits, int filled, struct extent_state *cached_state); + int clear_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, + int bits, gfp_t mask); + int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, +- int bits, int wake, int delete, gfp_t mask); ++ int bits, int wake, int delete, struct extent_state **cached, ++ gfp_t mask); + int set_extent_bits(struct extent_io_tree *tree, u64 start, u64 end, + int bits, gfp_t mask); + int set_extent_uptodate(struct extent_io_tree *tree, u64 start, u64 end, +@@ -282,5 +283,6 @@ int extent_clear_unlock_delalloc(struct inode *inode, + int clear_unlock, + int clear_delalloc, int clear_dirty, + int set_writeback, +- int end_writeback); ++ int end_writeback, ++ int set_private2); + #endif +diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c +index 30c9365..2c726b7 100644 +--- a/fs/btrfs/extent_map.c ++++ b/fs/btrfs/extent_map.c +@@ -36,7 +36,7 @@ void extent_map_exit(void) + void extent_map_tree_init(struct extent_map_tree *tree, gfp_t mask) + { + tree->map.rb_node = NULL; +- spin_lock_init(&tree->lock); ++ rwlock_init(&tree->lock); + } + + /** +@@ -198,6 +198,56 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) + return 0; + } + ++int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) ++{ ++ int ret = 0; ++ struct extent_map *merge = NULL; ++ struct rb_node *rb; ++ struct extent_map *em; ++ ++ write_lock(&tree->lock); ++ em = lookup_extent_mapping(tree, start, len); ++ ++ WARN_ON(em->start != start || !em); ++ ++ if (!em) ++ goto out; ++ ++ clear_bit(EXTENT_FLAG_PINNED, &em->flags); ++ ++ if (em->start != 0) { ++ rb = rb_prev(&em->rb_node); ++ if (rb) ++ merge = rb_entry(rb, struct extent_map, rb_node); ++ if (rb && mergable_maps(merge, em)) { ++ em->start = merge->start; ++ em->len += merge->len; ++ em->block_len += merge->block_len; ++ em->block_start = merge->block_start; ++ merge->in_tree = 0; ++ rb_erase(&merge->rb_node, &tree->map); ++ free_extent_map(merge); ++ } ++ } ++ ++ rb = rb_next(&em->rb_node); ++ if (rb) ++ merge = rb_entry(rb, struct extent_map, rb_node); ++ if (rb && mergable_maps(em, merge)) { ++ em->len += merge->len; ++ em->block_len += merge->len; ++ rb_erase(&merge->rb_node, &tree->map); ++ merge->in_tree = 0; ++ free_extent_map(merge); ++ } ++ ++ free_extent_map(em); ++out: ++ write_unlock(&tree->lock); ++ return ret; ++ ++} ++ + /** + * add_extent_mapping - add new extent map to the extent tree + * @tree: tree to insert new map in +@@ -222,7 +272,6 @@ int add_extent_mapping(struct extent_map_tree *tree, + ret = -EEXIST; + goto out; + } +- assert_spin_locked(&tree->lock); + rb = tree_insert(&tree->map, em->start, &em->rb_node); + if (rb) { + ret = -EEXIST; +@@ -285,7 +334,6 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, + struct rb_node *next = NULL; + u64 end = range_end(start, len); + +- assert_spin_locked(&tree->lock); + rb_node = __tree_search(&tree->map, start, &prev, &next); + if (!rb_node && prev) { + em = rb_entry(prev, struct extent_map, rb_node); +@@ -319,6 +367,54 @@ out: + } + + /** ++ * search_extent_mapping - find a nearby extent map ++ * @tree: tree to lookup in ++ * @start: byte offset to start the search ++ * @len: length of the lookup range ++ * ++ * Find and return the first extent_map struct in @tree that intersects the ++ * [start, len] range. ++ * ++ * If one can't be found, any nearby extent may be returned ++ */ ++struct extent_map *search_extent_mapping(struct extent_map_tree *tree, ++ u64 start, u64 len) ++{ ++ struct extent_map *em; ++ struct rb_node *rb_node; ++ struct rb_node *prev = NULL; ++ struct rb_node *next = NULL; ++ ++ rb_node = __tree_search(&tree->map, start, &prev, &next); ++ if (!rb_node && prev) { ++ em = rb_entry(prev, struct extent_map, rb_node); ++ goto found; ++ } ++ if (!rb_node && next) { ++ em = rb_entry(next, struct extent_map, rb_node); ++ goto found; ++ } ++ if (!rb_node) { ++ em = NULL; ++ goto out; ++ } ++ if (IS_ERR(rb_node)) { ++ em = ERR_PTR(PTR_ERR(rb_node)); ++ goto out; ++ } ++ em = rb_entry(rb_node, struct extent_map, rb_node); ++ goto found; ++ ++ em = NULL; ++ goto out; ++ ++found: ++ atomic_inc(&em->refs); ++out: ++ return em; ++} ++ ++/** + * remove_extent_mapping - removes an extent_map from the extent tree + * @tree: extent tree to remove from + * @em: extent map beeing removed +@@ -331,7 +427,6 @@ int remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) + int ret = 0; + + WARN_ON(test_bit(EXTENT_FLAG_PINNED, &em->flags)); +- assert_spin_locked(&tree->lock); + rb_erase(&em->rb_node, &tree->map); + em->in_tree = 0; + return ret; +diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h +index fb6eeef..ab6d74b 100644 +--- a/fs/btrfs/extent_map.h ++++ b/fs/btrfs/extent_map.h +@@ -31,7 +31,7 @@ struct extent_map { + + struct extent_map_tree { + struct rb_root map; +- spinlock_t lock; ++ rwlock_t lock; + }; + + static inline u64 extent_map_end(struct extent_map *em) +@@ -59,4 +59,7 @@ struct extent_map *alloc_extent_map(gfp_t mask); + void free_extent_map(struct extent_map *em); + int __init extent_map_init(void); + void extent_map_exit(void); ++int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len); ++struct extent_map *search_extent_mapping(struct extent_map_tree *tree, ++ u64 start, u64 len); + #endif +diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c +index 4b83397..571ad3c 100644 +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -112,8 +112,6 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, + int err = 0; + int i; + struct inode *inode = fdentry(file)->d_inode; +- struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; +- u64 hint_byte; + u64 num_bytes; + u64 start_pos; + u64 end_of_last_block; +@@ -125,22 +123,6 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); + + end_of_last_block = start_pos + num_bytes - 1; +- +- lock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); +- trans = btrfs_join_transaction(root, 1); +- if (!trans) { +- err = -ENOMEM; +- goto out_unlock; +- } +- btrfs_set_trans_block_group(trans, inode); +- hint_byte = 0; +- +- set_extent_uptodate(io_tree, start_pos, end_of_last_block, GFP_NOFS); +- +- /* check for reserved extents on each page, we don't want +- * to reset the delalloc bit on things that already have +- * extents reserved. +- */ + btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); + for (i = 0; i < num_pages; i++) { + struct page *p = pages[i]; +@@ -155,9 +137,6 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans, + * at this time. + */ + } +- err = btrfs_end_transaction(trans, root); +-out_unlock: +- unlock_extent(io_tree, start_pos, end_of_last_block, GFP_NOFS); + return err; + } + +@@ -189,18 +168,18 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, + if (!split2) + split2 = alloc_extent_map(GFP_NOFS); + +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, start, len); + if (!em) { +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + break; + } + flags = em->flags; + if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) { +- spin_unlock(&em_tree->lock); + if (em->start <= start && + (!testend || em->start + em->len >= start + len)) { + free_extent_map(em); ++ write_unlock(&em_tree->lock); + break; + } + if (start < em->start) { +@@ -210,6 +189,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, + start = em->start + em->len; + } + free_extent_map(em); ++ write_unlock(&em_tree->lock); + continue; + } + compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags); +@@ -260,7 +240,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, + free_extent_map(split); + split = NULL; + } +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + + /* once for us */ + free_extent_map(em); +@@ -289,7 +269,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, + noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, + struct btrfs_root *root, struct inode *inode, + u64 start, u64 end, u64 locked_end, +- u64 inline_limit, u64 *hint_byte) ++ u64 inline_limit, u64 *hint_byte, int drop_cache) + { + u64 extent_end = 0; + u64 search_start = start; +@@ -314,7 +294,8 @@ noinline int btrfs_drop_extents(struct btrfs_trans_handle *trans, + int ret; + + inline_limit = 0; +- btrfs_drop_extent_cache(inode, start, end - 1, 0); ++ if (drop_cache) ++ btrfs_drop_extent_cache(inode, start, end - 1, 0); + + path = btrfs_alloc_path(); + if (!path) +diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c +index 5edcee3..5c2caad 100644 +--- a/fs/btrfs/free-space-cache.c ++++ b/fs/btrfs/free-space-cache.c +@@ -259,7 +259,9 @@ static int link_free_space(struct btrfs_block_group_cache *block_group, + + static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) + { +- u64 max_bytes, possible_bytes; ++ u64 max_bytes; ++ u64 bitmap_bytes; ++ u64 extent_bytes; + + /* + * The goal is to keep the total amount of memory used per 1gb of space +@@ -269,22 +271,27 @@ static void recalculate_thresholds(struct btrfs_block_group_cache *block_group) + max_bytes = MAX_CACHE_BYTES_PER_GIG * + (div64_u64(block_group->key.offset, 1024 * 1024 * 1024)); + +- possible_bytes = (block_group->total_bitmaps * PAGE_CACHE_SIZE) + +- (sizeof(struct btrfs_free_space) * +- block_group->extents_thresh); ++ /* ++ * we want to account for 1 more bitmap than what we have so we can make ++ * sure we don't go over our overall goal of MAX_CACHE_BYTES_PER_GIG as ++ * we add more bitmaps. ++ */ ++ bitmap_bytes = (block_group->total_bitmaps + 1) * PAGE_CACHE_SIZE; + +- if (possible_bytes > max_bytes) { +- int extent_bytes = max_bytes - +- (block_group->total_bitmaps * PAGE_CACHE_SIZE); ++ if (bitmap_bytes >= max_bytes) { ++ block_group->extents_thresh = 0; ++ return; ++ } + +- if (extent_bytes <= 0) { +- block_group->extents_thresh = 0; +- return; +- } ++ /* ++ * we want the extent entry threshold to always be at most 1/2 the maxw ++ * bytes we can have, or whatever is less than that. ++ */ ++ extent_bytes = max_bytes - bitmap_bytes; ++ extent_bytes = min_t(u64, extent_bytes, div64_u64(max_bytes, 2)); + +- block_group->extents_thresh = extent_bytes / +- (sizeof(struct btrfs_free_space)); +- } ++ block_group->extents_thresh = ++ div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); + } + + static void bitmap_clear_bits(struct btrfs_block_group_cache *block_group, +@@ -403,6 +410,7 @@ static void add_new_bitmap(struct btrfs_block_group_cache *block_group, + BUG_ON(block_group->total_bitmaps >= max_bitmaps); + + info->offset = offset_to_bitmap(block_group, offset); ++ info->bytes = 0; + link_free_space(block_group, info); + block_group->total_bitmaps++; + +diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c +index 6b627c6..72ce3c1 100644 +--- a/fs/btrfs/inode-item.c ++++ b/fs/btrfs/inode-item.c +@@ -149,6 +149,8 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans, + ptr = (unsigned long)(ref + 1); + ret = 0; + } else if (ret < 0) { ++ if (ret == -EOVERFLOW) ++ ret = -EMLINK; + goto out; + } else { + ref = btrfs_item_ptr(path->nodes[0], path->slots[0], +@@ -177,8 +179,6 @@ int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, + + ret = btrfs_insert_empty_item(trans, root, path, &key, + sizeof(struct btrfs_inode_item)); +- if (ret == 0 && objectid > root->highest_inode) +- root->highest_inode = objectid; + return ret; + } + +diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c +index 9abbced..c56eb59 100644 +--- a/fs/btrfs/inode-map.c ++++ b/fs/btrfs/inode-map.c +@@ -43,9 +43,10 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid) + slot = path->slots[0] - 1; + l = path->nodes[0]; + btrfs_item_key_to_cpu(l, &found_key, slot); +- *objectid = found_key.objectid; ++ *objectid = max_t(u64, found_key.objectid, ++ BTRFS_FIRST_FREE_OBJECTID - 1); + } else { +- *objectid = BTRFS_FIRST_FREE_OBJECTID; ++ *objectid = BTRFS_FIRST_FREE_OBJECTID - 1; + } + ret = 0; + error: +@@ -53,91 +54,27 @@ error: + return ret; + } + +-/* +- * walks the btree of allocated inodes and find a hole. +- */ + int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 dirid, u64 *objectid) + { +- struct btrfs_path *path; +- struct btrfs_key key; + int ret; +- int slot = 0; +- u64 last_ino = 0; +- int start_found; +- struct extent_buffer *l; +- struct btrfs_key search_key; +- u64 search_start = dirid; +- + mutex_lock(&root->objectid_mutex); +- if (root->last_inode_alloc >= BTRFS_FIRST_FREE_OBJECTID && +- root->last_inode_alloc < BTRFS_LAST_FREE_OBJECTID) { +- *objectid = ++root->last_inode_alloc; +- mutex_unlock(&root->objectid_mutex); +- return 0; +- } +- path = btrfs_alloc_path(); +- BUG_ON(!path); +- search_start = max(search_start, (u64)BTRFS_FIRST_FREE_OBJECTID); +- search_key.objectid = search_start; +- search_key.type = 0; +- search_key.offset = 0; +- +- start_found = 0; +- ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0); +- if (ret < 0) +- goto error; + +- while (1) { +- l = path->nodes[0]; +- slot = path->slots[0]; +- if (slot >= btrfs_header_nritems(l)) { +- ret = btrfs_next_leaf(root, path); +- if (ret == 0) +- continue; +- if (ret < 0) +- goto error; +- if (!start_found) { +- *objectid = search_start; +- start_found = 1; +- goto found; +- } +- *objectid = last_ino > search_start ? +- last_ino : search_start; +- goto found; +- } +- btrfs_item_key_to_cpu(l, &key, slot); +- if (key.objectid >= search_start) { +- if (start_found) { +- if (last_ino < search_start) +- last_ino = search_start; +- if (key.objectid > last_ino) { +- *objectid = last_ino; +- goto found; +- } +- } else if (key.objectid > search_start) { +- *objectid = search_start; +- goto found; +- } +- } +- if (key.objectid >= BTRFS_LAST_FREE_OBJECTID) +- break; ++ if (unlikely(root->highest_objectid < BTRFS_FIRST_FREE_OBJECTID)) { ++ ret = btrfs_find_highest_inode(root, &root->highest_objectid); ++ if (ret) ++ goto out; ++ } + +- start_found = 1; +- last_ino = key.objectid + 1; +- path->slots[0]++; ++ if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) { ++ ret = -ENOSPC; ++ goto out; + } +- BUG_ON(1); +-found: +- btrfs_release_path(root, path); +- btrfs_free_path(path); +- BUG_ON(*objectid < search_start); +- mutex_unlock(&root->objectid_mutex); +- return 0; +-error: +- btrfs_release_path(root, path); +- btrfs_free_path(path); ++ ++ *objectid = ++root->highest_objectid; ++ ret = 0; ++out: + mutex_unlock(&root->objectid_mutex); + return ret; + } diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c -index 59cba18..d154a3f 100644 +index 59cba18..e9b76bc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -55,13 +55,13 @@ struct btrfs_iget_args { @@ -1605702,7 +1678987,1120 @@ index 59cba18..d154a3f 100644 static struct file_operations btrfs_dir_file_operations; static struct extent_io_ops btrfs_extent_io_ops; -@@ -5201,7 +5201,7 @@ static int btrfs_permission(struct inode *inode, int mask) +@@ -231,7 +231,8 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, + } + + ret = btrfs_drop_extents(trans, root, inode, start, +- aligned_end, aligned_end, start, &hint_byte); ++ aligned_end, aligned_end, start, ++ &hint_byte, 1); + BUG_ON(ret); + + if (isize > actual_end) +@@ -240,7 +241,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, + inline_len, compressed_size, + compressed_pages); + BUG_ON(ret); +- btrfs_drop_extent_cache(inode, start, aligned_end, 0); ++ btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); + return 0; + } + +@@ -425,7 +426,7 @@ again: + extent_clear_unlock_delalloc(inode, + &BTRFS_I(inode)->io_tree, + start, end, NULL, 1, 0, +- 0, 1, 1, 1); ++ 0, 1, 1, 1, 0); + ret = 0; + goto free_pages_out; + } +@@ -611,9 +612,9 @@ static noinline int submit_compressed_extents(struct inode *inode, + set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); + + while (1) { +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + if (ret != -EEXIST) { + free_extent_map(em); + break; +@@ -640,7 +641,7 @@ static noinline int submit_compressed_extents(struct inode *inode, + async_extent->start, + async_extent->start + + async_extent->ram_size - 1, +- NULL, 1, 1, 0, 1, 1, 0); ++ NULL, 1, 1, 0, 1, 1, 0, 0); + + ret = btrfs_submit_compressed_write(inode, + async_extent->start, +@@ -713,7 +714,7 @@ static noinline int cow_file_range(struct inode *inode, + extent_clear_unlock_delalloc(inode, + &BTRFS_I(inode)->io_tree, + start, end, NULL, 1, 1, +- 1, 1, 1, 1); ++ 1, 1, 1, 1, 0); + *nr_written = *nr_written + + (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; + *page_started = 1; +@@ -725,6 +726,15 @@ static noinline int cow_file_range(struct inode *inode, + BUG_ON(disk_num_bytes > + btrfs_super_total_bytes(&root->fs_info->super_copy)); + ++ ++ read_lock(&BTRFS_I(inode)->extent_tree.lock); ++ em = search_extent_mapping(&BTRFS_I(inode)->extent_tree, ++ start, num_bytes); ++ if (em) { ++ alloc_hint = em->block_start; ++ free_extent_map(em); ++ } ++ read_unlock(&BTRFS_I(inode)->extent_tree.lock); + btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); + + while (disk_num_bytes > 0) { +@@ -737,7 +747,6 @@ static noinline int cow_file_range(struct inode *inode, + em = alloc_extent_map(GFP_NOFS); + em->start = start; + em->orig_start = em->start; +- + ram_size = ins.offset; + em->len = ins.offset; + +@@ -747,9 +756,9 @@ static noinline int cow_file_range(struct inode *inode, + set_bit(EXTENT_FLAG_PINNED, &em->flags); + + while (1) { +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + if (ret != -EEXIST) { + free_extent_map(em); + break; +@@ -776,11 +785,14 @@ static noinline int cow_file_range(struct inode *inode, + /* we're not doing compressed IO, don't unlock the first + * page (which the caller expects to stay locked), don't + * clear any dirty bits and don't set any writeback bits ++ * ++ * Do set the Private2 bit so we know this page was properly ++ * setup for writepage + */ + extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, + start, start + ram_size - 1, + locked_page, unlock, 1, +- 1, 0, 0, 0); ++ 1, 0, 0, 0, 1); + disk_num_bytes -= cur_alloc_size; + num_bytes -= cur_alloc_size; + alloc_hint = ins.objectid + ins.offset; +@@ -853,7 +865,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, + int limit = 10 * 1024 * 1042; + + clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED | +- EXTENT_DELALLOC, 1, 0, GFP_NOFS); ++ EXTENT_DELALLOC, 1, 0, NULL, GFP_NOFS); + while (start < end) { + async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); + async_cow->inode = inode; +@@ -1080,9 +1092,9 @@ out_check: + em->bdev = root->fs_info->fs_devices->latest_bdev; + set_bit(EXTENT_FLAG_PINNED, &em->flags); + while (1) { +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + if (ret != -EEXIST) { + free_extent_map(em); + break; +@@ -1101,7 +1113,7 @@ out_check: + + extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, + cur_offset, cur_offset + num_bytes - 1, +- locked_page, 1, 1, 1, 0, 0, 0); ++ locked_page, 1, 1, 1, 0, 0, 0, 1); + cur_offset = extent_end; + if (cur_offset > end) + break; +@@ -1374,10 +1386,8 @@ again: + lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); + + /* already ordered? We're done */ +- if (test_range_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, +- EXTENT_ORDERED, 0)) { ++ if (PagePrivate2(page)) + goto out; +- } + + ordered = btrfs_lookup_ordered_extent(inode, page_start); + if (ordered) { +@@ -1413,11 +1423,9 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end) + struct inode *inode = page->mapping->host; + struct btrfs_writepage_fixup *fixup; + struct btrfs_root *root = BTRFS_I(inode)->root; +- int ret; + +- ret = test_range_bit(&BTRFS_I(inode)->io_tree, start, end, +- EXTENT_ORDERED, 0); +- if (ret) ++ /* this page is properly in the ordered list */ ++ if (TestClearPagePrivate2(page)) + return 0; + + if (PageChecked(page)) +@@ -1455,9 +1463,19 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, + BUG_ON(!path); + + path->leave_spinning = 1; ++ ++ /* ++ * we may be replacing one extent in the tree with another. ++ * The new extent is pinned in the extent map, and we don't want ++ * to drop it from the cache until it is completely in the btree. ++ * ++ * So, tell btrfs_drop_extents to leave this extent in the cache. ++ * the caller is expected to unpin it and allow it to be merged ++ * with the others. ++ */ + ret = btrfs_drop_extents(trans, root, inode, file_pos, + file_pos + num_bytes, locked_end, +- file_pos, &hint); ++ file_pos, &hint, 0); + BUG_ON(ret); + + ins.objectid = inode->i_ino; +@@ -1485,7 +1503,6 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, + btrfs_mark_buffer_dirty(leaf); + + inode_add_bytes(inode, num_bytes); +- btrfs_drop_extent_cache(inode, file_pos, file_pos + num_bytes - 1, 0); + + ins.objectid = disk_bytenr; + ins.offset = disk_num_bytes; +@@ -1596,6 +1613,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) + ordered_extent->len, + compressed, 0, 0, + BTRFS_FILE_EXTENT_REG); ++ unpin_extent_cache(&BTRFS_I(inode)->extent_tree, ++ ordered_extent->file_offset, ++ ordered_extent->len); + BUG_ON(ret); + } + unlock_extent(io_tree, ordered_extent->file_offset, +@@ -1623,6 +1643,7 @@ nocow: + static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, + struct extent_state *state, int uptodate) + { ++ ClearPagePrivate2(page); + return btrfs_finish_ordered_io(page->mapping->host, start, end); + } + +@@ -1669,13 +1690,13 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, + failrec->last_mirror = 0; + failrec->bio_flags = 0; + +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, start, failrec->len); + if (em->start > start || em->start + em->len < start) { + free_extent_map(em); + em = NULL; + } +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + if (!em || IS_ERR(em)) { + kfree(failrec); +@@ -1794,7 +1815,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, + return 0; + + if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && +- test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1)) { ++ test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) { + clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM, + GFP_NOFS); + return 0; +@@ -2352,6 +2373,69 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) + return ret; + } + ++int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, ++ struct btrfs_root *root, ++ struct inode *dir, u64 objectid, ++ const char *name, int name_len) ++{ ++ struct btrfs_path *path; ++ struct extent_buffer *leaf; ++ struct btrfs_dir_item *di; ++ struct btrfs_key key; ++ u64 index; ++ int ret; ++ ++ path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; ++ ++ di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, ++ name, name_len, -1); ++ BUG_ON(!di || IS_ERR(di)); ++ ++ leaf = path->nodes[0]; ++ btrfs_dir_item_key_to_cpu(leaf, di, &key); ++ WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); ++ ret = btrfs_delete_one_dir_name(trans, root, path, di); ++ BUG_ON(ret); ++ btrfs_release_path(root, path); ++ ++ ret = btrfs_del_root_ref(trans, root->fs_info->tree_root, ++ objectid, root->root_key.objectid, ++ dir->i_ino, &index, name, name_len); ++ if (ret < 0) { ++ BUG_ON(ret != -ENOENT); ++ di = btrfs_search_dir_index_item(root, path, dir->i_ino, ++ name, name_len); ++ BUG_ON(!di || IS_ERR(di)); ++ ++ leaf = path->nodes[0]; ++ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); ++ btrfs_release_path(root, path); ++ index = key.offset; ++ } ++ ++ di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, ++ index, name, name_len, -1); ++ BUG_ON(!di || IS_ERR(di)); ++ ++ leaf = path->nodes[0]; ++ btrfs_dir_item_key_to_cpu(leaf, di, &key); ++ WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); ++ ret = btrfs_delete_one_dir_name(trans, root, path, di); ++ BUG_ON(ret); ++ btrfs_release_path(root, path); ++ ++ btrfs_i_size_write(dir, dir->i_size - name_len * 2); ++ dir->i_mtime = dir->i_ctime = CURRENT_TIME; ++ ret = btrfs_update_inode(trans, root, dir); ++ BUG_ON(ret); ++ dir->i_sb->s_dirt = 1; ++ ++ btrfs_free_path(path); ++ return 0; ++} ++ + static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) + { + struct inode *inode = dentry->d_inode; +@@ -2361,29 +2445,31 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) + struct btrfs_trans_handle *trans; + unsigned long nr = 0; + +- /* +- * the FIRST_FREE_OBJECTID check makes sure we don't try to rmdir +- * the root of a subvolume or snapshot +- */ + if (inode->i_size > BTRFS_EMPTY_DIR_SIZE || +- inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { ++ inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) + return -ENOTEMPTY; +- } + + trans = btrfs_start_transaction(root, 1); + btrfs_set_trans_block_group(trans, dir); + ++ if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { ++ err = btrfs_unlink_subvol(trans, root, dir, ++ BTRFS_I(inode)->location.objectid, ++ dentry->d_name.name, ++ dentry->d_name.len); ++ goto out; ++ } ++ + err = btrfs_orphan_add(trans, inode); + if (err) +- goto fail_trans; ++ goto out; + + /* now the directory is empty */ + err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, + dentry->d_name.name, dentry->d_name.len); + if (!err) + btrfs_i_size_write(inode, 0); +- +-fail_trans: ++out: + nr = trans->blocks_used; + ret = btrfs_end_transaction_throttle(trans, root); + btrfs_btree_balance_dirty(root, nr); +@@ -2935,7 +3021,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) + cur_offset, + cur_offset + hole_size, + block_end, +- cur_offset, &hint_byte); ++ cur_offset, &hint_byte, 1); + if (err) + break; + err = btrfs_insert_file_extent(trans, root, +@@ -3003,6 +3089,11 @@ void btrfs_delete_inode(struct inode *inode) + } + btrfs_wait_ordered_range(inode, 0, (u64)-1); + ++ if (inode->i_nlink > 0) { ++ BUG_ON(btrfs_root_refs(&root->root_item) != 0); ++ goto no_delete; ++ } ++ + btrfs_i_size_write(inode, 0); + trans = btrfs_join_transaction(root, 1); + +@@ -3070,29 +3161,67 @@ out_err: + * is kind of like crossing a mount point. + */ + static int fixup_tree_root_location(struct btrfs_root *root, +- struct btrfs_key *location, +- struct btrfs_root **sub_root, +- struct dentry *dentry) ++ struct inode *dir, ++ struct dentry *dentry, ++ struct btrfs_key *location, ++ struct btrfs_root **sub_root) + { +- struct btrfs_root_item *ri; ++ struct btrfs_path *path; ++ struct btrfs_root *new_root; ++ struct btrfs_root_ref *ref; ++ struct extent_buffer *leaf; ++ int ret; ++ int err = 0; + +- if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) +- return 0; +- if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) +- return 0; ++ path = btrfs_alloc_path(); ++ if (!path) { ++ err = -ENOMEM; ++ goto out; ++ } + +- *sub_root = btrfs_read_fs_root(root->fs_info, location, +- dentry->d_name.name, +- dentry->d_name.len); +- if (IS_ERR(*sub_root)) +- return PTR_ERR(*sub_root); ++ err = -ENOENT; ++ ret = btrfs_find_root_ref(root->fs_info->tree_root, path, ++ BTRFS_I(dir)->root->root_key.objectid, ++ location->objectid); ++ if (ret) { ++ if (ret < 0) ++ err = ret; ++ goto out; ++ } + +- ri = &(*sub_root)->root_item; +- location->objectid = btrfs_root_dirid(ri); +- btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); +- location->offset = 0; ++ leaf = path->nodes[0]; ++ ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); ++ if (btrfs_root_ref_dirid(leaf, ref) != dir->i_ino || ++ btrfs_root_ref_name_len(leaf, ref) != dentry->d_name.len) ++ goto out; + +- return 0; ++ ret = memcmp_extent_buffer(leaf, dentry->d_name.name, ++ (unsigned long)(ref + 1), ++ dentry->d_name.len); ++ if (ret) ++ goto out; ++ ++ btrfs_release_path(root->fs_info->tree_root, path); ++ ++ new_root = btrfs_read_fs_root_no_name(root->fs_info, location); ++ if (IS_ERR(new_root)) { ++ err = PTR_ERR(new_root); ++ goto out; ++ } ++ ++ if (btrfs_root_refs(&new_root->root_item) == 0) { ++ err = -ENOENT; ++ goto out; ++ } ++ ++ *sub_root = new_root; ++ location->objectid = btrfs_root_dirid(&new_root->root_item); ++ location->type = BTRFS_INODE_ITEM_KEY; ++ location->offset = 0; ++ err = 0; ++out: ++ btrfs_free_path(path); ++ return err; + } + + static void inode_tree_add(struct inode *inode) +@@ -3101,11 +3230,13 @@ static void inode_tree_add(struct inode *inode) + struct btrfs_inode *entry; + struct rb_node **p; + struct rb_node *parent; +- + again: + p = &root->inode_tree.rb_node; + parent = NULL; + ++ if (hlist_unhashed(&inode->i_hash)) ++ return; ++ + spin_lock(&root->inode_lock); + while (*p) { + parent = *p; +@@ -3132,13 +3263,87 @@ again: + static void inode_tree_del(struct inode *inode) + { + struct btrfs_root *root = BTRFS_I(inode)->root; ++ int empty = 0; + + spin_lock(&root->inode_lock); + if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { + rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); + RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); ++ empty = RB_EMPTY_ROOT(&root->inode_tree); + } + spin_unlock(&root->inode_lock); ++ ++ if (empty && btrfs_root_refs(&root->root_item) == 0) { ++ synchronize_srcu(&root->fs_info->subvol_srcu); ++ spin_lock(&root->inode_lock); ++ empty = RB_EMPTY_ROOT(&root->inode_tree); ++ spin_unlock(&root->inode_lock); ++ if (empty) ++ btrfs_add_dead_root(root); ++ } ++} ++ ++int btrfs_invalidate_inodes(struct btrfs_root *root) ++{ ++ struct rb_node *node; ++ struct rb_node *prev; ++ struct btrfs_inode *entry; ++ struct inode *inode; ++ u64 objectid = 0; ++ ++ WARN_ON(btrfs_root_refs(&root->root_item) != 0); ++ ++ spin_lock(&root->inode_lock); ++again: ++ node = root->inode_tree.rb_node; ++ prev = NULL; ++ while (node) { ++ prev = node; ++ entry = rb_entry(node, struct btrfs_inode, rb_node); ++ ++ if (objectid < entry->vfs_inode.i_ino) ++ node = node->rb_left; ++ else if (objectid > entry->vfs_inode.i_ino) ++ node = node->rb_right; ++ else ++ break; ++ } ++ if (!node) { ++ while (prev) { ++ entry = rb_entry(prev, struct btrfs_inode, rb_node); ++ if (objectid <= entry->vfs_inode.i_ino) { ++ node = prev; ++ break; ++ } ++ prev = rb_next(prev); ++ } ++ } ++ while (node) { ++ entry = rb_entry(node, struct btrfs_inode, rb_node); ++ objectid = entry->vfs_inode.i_ino + 1; ++ inode = igrab(&entry->vfs_inode); ++ if (inode) { ++ spin_unlock(&root->inode_lock); ++ if (atomic_read(&inode->i_count) > 1) ++ d_prune_aliases(inode); ++ /* ++ * btrfs_drop_inode will remove it from ++ * the inode cache when its usage count ++ * hits zero. ++ */ ++ iput(inode); ++ cond_resched(); ++ spin_lock(&root->inode_lock); ++ goto again; ++ } ++ ++ if (cond_resched_lock(&root->inode_lock)) ++ goto again; ++ ++ node = rb_next(node); ++ } ++ spin_unlock(&root->inode_lock); ++ return 0; + } + + static noinline void init_btrfs_i(struct inode *inode) +@@ -3225,15 +3430,41 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, + return inode; + } + ++static struct inode *new_simple_dir(struct super_block *s, ++ struct btrfs_key *key, ++ struct btrfs_root *root) ++{ ++ struct inode *inode = new_inode(s); ++ ++ if (!inode) ++ return ERR_PTR(-ENOMEM); ++ ++ init_btrfs_i(inode); ++ ++ BTRFS_I(inode)->root = root; ++ memcpy(&BTRFS_I(inode)->location, key, sizeof(*key)); ++ BTRFS_I(inode)->dummy_inode = 1; ++ ++ inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; ++ inode->i_op = &simple_dir_inode_operations; ++ inode->i_fop = &simple_dir_operations; ++ inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; ++ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; ++ ++ return inode; ++} ++ + struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) + { + struct inode *inode; +- struct btrfs_inode *bi = BTRFS_I(dir); +- struct btrfs_root *root = bi->root; ++ struct btrfs_root *root = BTRFS_I(dir)->root; + struct btrfs_root *sub_root = root; + struct btrfs_key location; ++ int index; + int ret; + ++ dentry->d_op = &btrfs_dentry_operations; ++ + if (dentry->d_name.len > BTRFS_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + +@@ -3242,29 +3473,50 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) + if (ret < 0) + return ERR_PTR(ret); + +- inode = NULL; +- if (location.objectid) { +- ret = fixup_tree_root_location(root, &location, &sub_root, +- dentry); +- if (ret < 0) +- return ERR_PTR(ret); +- if (ret > 0) +- return ERR_PTR(-ENOENT); ++ if (location.objectid == 0) ++ return NULL; ++ ++ if (location.type == BTRFS_INODE_ITEM_KEY) { ++ inode = btrfs_iget(dir->i_sb, &location, root); ++ return inode; ++ } ++ ++ BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); ++ ++ index = srcu_read_lock(&root->fs_info->subvol_srcu); ++ ret = fixup_tree_root_location(root, dir, dentry, ++ &location, &sub_root); ++ if (ret < 0) { ++ if (ret != -ENOENT) ++ inode = ERR_PTR(ret); ++ else ++ inode = new_simple_dir(dir->i_sb, &location, sub_root); ++ } else { + inode = btrfs_iget(dir->i_sb, &location, sub_root); +- if (IS_ERR(inode)) +- return ERR_CAST(inode); + } ++ srcu_read_unlock(&root->fs_info->subvol_srcu, index); ++ + return inode; + } + ++static int btrfs_dentry_delete(struct dentry *dentry) ++{ ++ struct btrfs_root *root; ++ ++ if (!dentry->d_inode) ++ return 0; ++ ++ root = BTRFS_I(dentry->d_inode)->root; ++ if (btrfs_root_refs(&root->root_item) == 0) ++ return 1; ++ return 0; ++} ++ + static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) + { + struct inode *inode; + +- if (dentry->d_name.len > BTRFS_NAME_LEN) +- return ERR_PTR(-ENAMETOOLONG); +- + inode = btrfs_lookup_dentry(dir, dentry); + if (IS_ERR(inode)) + return ERR_CAST(inode); +@@ -3603,9 +3855,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, + if (ret != 0) + goto fail; + +- if (objectid > root->highest_inode) +- root->highest_inode = objectid; +- + inode->i_uid = current_fsuid(); + + if (dir && (dir->i_mode & S_ISGID)) { +@@ -3673,26 +3922,35 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, + struct inode *parent_inode, struct inode *inode, + const char *name, int name_len, int add_backref, u64 index) + { +- int ret; ++ int ret = 0; + struct btrfs_key key; + struct btrfs_root *root = BTRFS_I(parent_inode)->root; + +- key.objectid = inode->i_ino; +- btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); +- key.offset = 0; ++ if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { ++ memcpy(&key, &BTRFS_I(inode)->root->root_key, sizeof(key)); ++ } else { ++ key.objectid = inode->i_ino; ++ btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); ++ key.offset = 0; ++ } ++ ++ if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { ++ ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, ++ key.objectid, root->root_key.objectid, ++ parent_inode->i_ino, ++ index, name, name_len); ++ } else if (add_backref) { ++ ret = btrfs_insert_inode_ref(trans, root, ++ name, name_len, inode->i_ino, ++ parent_inode->i_ino, index); ++ } + +- ret = btrfs_insert_dir_item(trans, root, name, name_len, +- parent_inode->i_ino, +- &key, btrfs_inode_type(inode), +- index); + if (ret == 0) { +- if (add_backref) { +- ret = btrfs_insert_inode_ref(trans, root, +- name, name_len, +- inode->i_ino, +- parent_inode->i_ino, +- index); +- } ++ ret = btrfs_insert_dir_item(trans, root, name, name_len, ++ parent_inode->i_ino, &key, ++ btrfs_inode_type(inode), index); ++ BUG_ON(ret); ++ + btrfs_i_size_write(parent_inode, parent_inode->i_size + + name_len * 2); + parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; +@@ -3875,18 +4133,16 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, + + err = btrfs_add_nondir(trans, dentry, inode, 1, index); + +- if (err) +- drop_inode = 1; +- +- btrfs_update_inode_block_group(trans, dir); +- err = btrfs_update_inode(trans, root, inode); +- +- if (err) ++ if (err) { + drop_inode = 1; ++ } else { ++ btrfs_update_inode_block_group(trans, dir); ++ err = btrfs_update_inode(trans, root, inode); ++ BUG_ON(err); ++ btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); ++ } + + nr = trans->blocks_used; +- +- btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); + btrfs_end_transaction_throttle(trans, root); + fail: + if (drop_inode) { +@@ -4064,11 +4320,11 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, + int compressed; + + again: +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, start, len); + if (em) + em->bdev = root->fs_info->fs_devices->latest_bdev; +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + if (em) { + if (em->start > start || em->start + em->len <= start) +@@ -4215,6 +4471,11 @@ again: + map = kmap(page); + read_extent_buffer(leaf, map + pg_offset, ptr, + copy_size); ++ if (pg_offset + copy_size < PAGE_CACHE_SIZE) { ++ memset(map + pg_offset + copy_size, 0, ++ PAGE_CACHE_SIZE - pg_offset - ++ copy_size); ++ } + kunmap(page); + } + flush_dcache_page(page); +@@ -4259,7 +4520,7 @@ insert: + } + + err = 0; +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); + /* it is possible that someone inserted the extent into the tree + * while we had the lock dropped. It is also possible that +@@ -4299,7 +4560,7 @@ insert: + err = 0; + } + } +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + out: + if (path) + btrfs_free_path(path); +@@ -4398,13 +4659,21 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) + u64 page_start = page_offset(page); + u64 page_end = page_start + PAGE_CACHE_SIZE - 1; + ++ ++ /* ++ * we have the page locked, so new writeback can't start, ++ * and the dirty bit won't be cleared while we are here. ++ * ++ * Wait for IO on this page so that we can safely clear ++ * the PagePrivate2 bit and do ordered accounting ++ */ + wait_on_page_writeback(page); ++ + tree = &BTRFS_I(page->mapping->host)->io_tree; + if (offset) { + btrfs_releasepage(page, GFP_NOFS); + return; + } +- + lock_extent(tree, page_start, page_end, GFP_NOFS); + ordered = btrfs_lookup_ordered_extent(page->mapping->host, + page_offset(page)); +@@ -4415,16 +4684,21 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) + */ + clear_extent_bit(tree, page_start, page_end, + EXTENT_DIRTY | EXTENT_DELALLOC | +- EXTENT_LOCKED, 1, 0, GFP_NOFS); +- btrfs_finish_ordered_io(page->mapping->host, +- page_start, page_end); ++ EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); ++ /* ++ * whoever cleared the private bit is responsible ++ * for the finish_ordered_io ++ */ ++ if (TestClearPagePrivate2(page)) { ++ btrfs_finish_ordered_io(page->mapping->host, ++ page_start, page_end); ++ } + btrfs_put_ordered_extent(ordered); + lock_extent(tree, page_start, page_end, GFP_NOFS); + } + clear_extent_bit(tree, page_start, page_end, +- EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | +- EXTENT_ORDERED, +- 1, 1, GFP_NOFS); ++ EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, ++ 1, 1, NULL, GFP_NOFS); + __btrfs_releasepage(page, GFP_NOFS); + + ClearPageChecked(page); +@@ -4521,11 +4795,14 @@ again: + } + ClearPageChecked(page); + set_page_dirty(page); ++ SetPageUptodate(page); + + BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; + unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + + out_unlock: ++ if (!ret) ++ return VM_FAULT_LOCKED; + unlock_page(page); + out: + return ret; +@@ -4594,11 +4871,11 @@ out: + * create a new subvolume directory/inode (helper for the ioctl). + */ + int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, +- struct btrfs_root *new_root, struct dentry *dentry, ++ struct btrfs_root *new_root, + u64 new_dirid, u64 alloc_hint) + { + struct inode *inode; +- int error; ++ int err; + u64 index = 0; + + inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, +@@ -4611,11 +4888,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, + inode->i_nlink = 1; + btrfs_i_size_write(inode, 0); + +- error = btrfs_update_inode(trans, new_root, inode); +- if (error) +- return error; ++ err = btrfs_update_inode(trans, new_root, inode); ++ BUG_ON(err); + +- d_instantiate(dentry, inode); ++ iput(inode); + return 0; + } + +@@ -4693,6 +4969,16 @@ void btrfs_destroy_inode(struct inode *inode) + kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); + } + ++void btrfs_drop_inode(struct inode *inode) ++{ ++ struct btrfs_root *root = BTRFS_I(inode)->root; ++ ++ if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) ++ generic_delete_inode(inode); ++ else ++ generic_drop_inode(inode); ++} ++ + static void init_once(void *foo) + { + struct btrfs_inode *ei = (struct btrfs_inode *) foo; +@@ -4761,31 +5047,32 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, + { + struct btrfs_trans_handle *trans; + struct btrfs_root *root = BTRFS_I(old_dir)->root; ++ struct btrfs_root *dest = BTRFS_I(new_dir)->root; + struct inode *new_inode = new_dentry->d_inode; + struct inode *old_inode = old_dentry->d_inode; + struct timespec ctime = CURRENT_TIME; + u64 index = 0; ++ u64 root_objectid; + int ret; + +- /* we're not allowed to rename between subvolumes */ +- if (BTRFS_I(old_inode)->root->root_key.objectid != +- BTRFS_I(new_dir)->root->root_key.objectid) ++ if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) ++ return -EPERM; ++ ++ /* we only allow rename subvolume link between subvolumes */ ++ if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest) + return -EXDEV; + +- if (S_ISDIR(old_inode->i_mode) && new_inode && +- new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { ++ if (old_inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID || ++ (new_inode && new_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) + return -ENOTEMPTY; +- } + +- /* to rename a snapshot or subvolume, we need to juggle the +- * backrefs. This isn't coded yet +- */ +- if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) +- return -EXDEV; ++ if (S_ISDIR(old_inode->i_mode) && new_inode && ++ new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) ++ return -ENOTEMPTY; + + ret = btrfs_check_metadata_free_space(root); + if (ret) +- goto out_unlock; ++ return ret; + + /* + * we're using rename to replace one file with another. +@@ -4796,8 +5083,40 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, + old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) + filemap_flush(old_inode->i_mapping); + ++ /* close the racy window with snapshot create/destroy ioctl */ ++ if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) ++ down_read(&root->fs_info->subvol_sem); ++ + trans = btrfs_start_transaction(root, 1); ++ btrfs_set_trans_block_group(trans, new_dir); ++ ++ if (dest != root) ++ btrfs_record_root_in_trans(trans, dest); + ++ ret = btrfs_set_inode_index(new_dir, &index); ++ if (ret) ++ goto out_fail; ++ ++ if (unlikely(old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { ++ /* force full log commit if subvolume involved. */ ++ root->fs_info->last_trans_log_full_commit = trans->transid; ++ } else { ++ ret = btrfs_insert_inode_ref(trans, dest, ++ new_dentry->d_name.name, ++ new_dentry->d_name.len, ++ old_inode->i_ino, ++ new_dir->i_ino, index); ++ if (ret) ++ goto out_fail; ++ /* ++ * this is an ugly little race, but the rename is required ++ * to make sure that if we crash, the inode is either at the ++ * old name or the new one. pinning the log transaction lets ++ * us make sure we don't allow a log commit to come in after ++ * we unlink the name but before we add the new name back in. ++ */ ++ btrfs_pin_log_trans(root); ++ } + /* + * make sure the inode gets flushed if it is replacing + * something. +@@ -4807,18 +5126,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, + btrfs_add_ordered_operation(trans, root, old_inode); + } + +- /* +- * this is an ugly little race, but the rename is required to make +- * sure that if we crash, the inode is either at the old name +- * or the new one. pinning the log transaction lets us make sure +- * we don't allow a log commit to come in after we unlink the +- * name but before we add the new name back in. +- */ +- btrfs_pin_log_trans(root); +- +- btrfs_set_trans_block_group(trans, new_dir); +- +- btrfs_inc_nlink(old_dentry->d_inode); + old_dir->i_ctime = old_dir->i_mtime = ctime; + new_dir->i_ctime = new_dir->i_mtime = ctime; + old_inode->i_ctime = ctime; +@@ -4826,47 +5133,58 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, + if (old_dentry->d_parent != new_dentry->d_parent) + btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); + +- ret = btrfs_unlink_inode(trans, root, old_dir, old_dentry->d_inode, +- old_dentry->d_name.name, +- old_dentry->d_name.len); +- if (ret) +- goto out_fail; ++ if (unlikely(old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { ++ root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; ++ ret = btrfs_unlink_subvol(trans, root, old_dir, root_objectid, ++ old_dentry->d_name.name, ++ old_dentry->d_name.len); ++ } else { ++ btrfs_inc_nlink(old_dentry->d_inode); ++ ret = btrfs_unlink_inode(trans, root, old_dir, ++ old_dentry->d_inode, ++ old_dentry->d_name.name, ++ old_dentry->d_name.len); ++ } ++ BUG_ON(ret); + + if (new_inode) { + new_inode->i_ctime = CURRENT_TIME; +- ret = btrfs_unlink_inode(trans, root, new_dir, +- new_dentry->d_inode, +- new_dentry->d_name.name, +- new_dentry->d_name.len); +- if (ret) +- goto out_fail; ++ if (unlikely(new_inode->i_ino == ++ BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { ++ root_objectid = BTRFS_I(new_inode)->location.objectid; ++ ret = btrfs_unlink_subvol(trans, dest, new_dir, ++ root_objectid, ++ new_dentry->d_name.name, ++ new_dentry->d_name.len); ++ BUG_ON(new_inode->i_nlink == 0); ++ } else { ++ ret = btrfs_unlink_inode(trans, dest, new_dir, ++ new_dentry->d_inode, ++ new_dentry->d_name.name, ++ new_dentry->d_name.len); ++ } ++ BUG_ON(ret); + if (new_inode->i_nlink == 0) { + ret = btrfs_orphan_add(trans, new_dentry->d_inode); +- if (ret) +- goto out_fail; ++ BUG_ON(ret); + } +- + } +- ret = btrfs_set_inode_index(new_dir, &index); +- if (ret) +- goto out_fail; + +- ret = btrfs_add_link(trans, new_dentry->d_parent->d_inode, +- old_inode, new_dentry->d_name.name, +- new_dentry->d_name.len, 1, index); +- if (ret) +- goto out_fail; ++ ret = btrfs_add_link(trans, new_dir, old_inode, ++ new_dentry->d_name.name, ++ new_dentry->d_name.len, 0, index); ++ BUG_ON(ret); + +- btrfs_log_new_name(trans, old_inode, old_dir, +- new_dentry->d_parent); ++ if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { ++ btrfs_log_new_name(trans, old_inode, old_dir, ++ new_dentry->d_parent); ++ btrfs_end_log_trans(root); ++ } + out_fail: +- +- /* this btrfs_end_log_trans just allows the current +- * log-sub transaction to complete +- */ +- btrfs_end_log_trans(root); + btrfs_end_transaction_throttle(trans, root); +-out_unlock: ++ ++ if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) ++ up_read(&root->fs_info->subvol_sem); + return ret; + } + +@@ -5058,6 +5376,8 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans, + 0, 0, 0, + BTRFS_FILE_EXTENT_PREALLOC); + BUG_ON(ret); ++ btrfs_drop_extent_cache(inode, cur_offset, ++ cur_offset + ins.offset -1, 0); + num_bytes -= ins.offset; + cur_offset += ins.offset; + alloc_hint = ins.objectid + ins.offset; +@@ -5201,7 +5521,7 @@ static int btrfs_permission(struct inode *inode, int mask) return generic_permission(inode, mask, btrfs_check_acl); } @@ -1605711,7 +1680109,7 @@ index 59cba18..d154a3f 100644 .getattr = btrfs_getattr, .lookup = btrfs_lookup, .create = btrfs_create, -@@ -5219,7 +5219,7 @@ static struct inode_operations btrfs_dir_inode_operations = { +@@ -5219,10 +5539,11 @@ static struct inode_operations btrfs_dir_inode_operations = { .removexattr = btrfs_removexattr, .permission = btrfs_permission, }; @@ -1605720,7 +1680118,11 @@ index 59cba18..d154a3f 100644 .lookup = btrfs_lookup, .permission = btrfs_permission, }; -@@ -5259,7 +5259,7 @@ static struct extent_io_ops btrfs_extent_io_ops = { ++ + static struct file_operations btrfs_dir_file_operations = { + .llseek = generic_file_llseek, + .read = generic_read_dir, +@@ -5259,7 +5580,7 @@ static struct extent_io_ops btrfs_extent_io_ops = { * * For now we're avoiding this by dropping bmap. */ @@ -1605729,7 +1680131,7 @@ index 59cba18..d154a3f 100644 .readpage = btrfs_readpage, .writepage = btrfs_writepage, .writepages = btrfs_writepages, -@@ -5269,16 +5269,17 @@ static struct address_space_operations btrfs_aops = { +@@ -5269,16 +5590,17 @@ static struct address_space_operations btrfs_aops = { .invalidatepage = btrfs_invalidatepage, .releasepage = btrfs_releasepage, .set_page_dirty = btrfs_set_page_dirty, @@ -1605749,7 +1680151,7 @@ index 59cba18..d154a3f 100644 .truncate = btrfs_truncate, .getattr = btrfs_getattr, .setattr = btrfs_setattr, -@@ -5290,7 +5291,7 @@ static struct inode_operations btrfs_file_inode_operations = { +@@ -5290,7 +5612,7 @@ static struct inode_operations btrfs_file_inode_operations = { .fallocate = btrfs_fallocate, .fiemap = btrfs_fiemap, }; @@ -1605758,7 +1680160,7 @@ index 59cba18..d154a3f 100644 .getattr = btrfs_getattr, .setattr = btrfs_setattr, .permission = btrfs_permission, -@@ -5299,7 +5300,7 @@ static struct inode_operations btrfs_special_inode_operations = { +@@ -5299,7 +5621,7 @@ static struct inode_operations btrfs_special_inode_operations = { .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, }; @@ -1605767,11 +1680169,639 @@ index 59cba18..d154a3f 100644 .readlink = generic_readlink, .follow_link = page_follow_link_light, .put_link = page_put_link, +@@ -5309,3 +5631,7 @@ static struct inode_operations btrfs_symlink_inode_operations = { + .listxattr = btrfs_listxattr, + .removexattr = btrfs_removexattr, + }; ++ ++struct dentry_operations btrfs_dentry_operations = { ++ .d_delete = btrfs_dentry_delete, ++}; +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index bd88f25..a8577a7 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -230,8 +230,8 @@ static noinline int create_subvol(struct btrfs_root *root, + struct btrfs_root_item root_item; + struct btrfs_inode_item *inode_item; + struct extent_buffer *leaf; +- struct btrfs_root *new_root = root; +- struct inode *dir; ++ struct btrfs_root *new_root; ++ struct inode *dir = dentry->d_parent->d_inode; + int ret; + int err; + u64 objectid; +@@ -241,7 +241,7 @@ static noinline int create_subvol(struct btrfs_root *root, + + ret = btrfs_check_metadata_free_space(root); + if (ret) +- goto fail_commit; ++ return ret; + + trans = btrfs_start_transaction(root, 1); + BUG_ON(!trans); +@@ -304,11 +304,17 @@ static noinline int create_subvol(struct btrfs_root *root, + if (ret) + goto fail; + ++ key.offset = (u64)-1; ++ new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); ++ BUG_ON(IS_ERR(new_root)); ++ ++ btrfs_record_root_in_trans(trans, new_root); ++ ++ ret = btrfs_create_subvol_root(trans, new_root, new_dirid, ++ BTRFS_I(dir)->block_group); + /* + * insert the directory item + */ +- key.offset = (u64)-1; +- dir = dentry->d_parent->d_inode; + ret = btrfs_set_inode_index(dir, &index); + BUG_ON(ret); + +@@ -322,44 +328,18 @@ static noinline int create_subvol(struct btrfs_root *root, + ret = btrfs_update_inode(trans, root, dir); + BUG_ON(ret); + +- /* add the backref first */ + ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, +- objectid, BTRFS_ROOT_BACKREF_KEY, +- root->root_key.objectid, ++ objectid, root->root_key.objectid, + dir->i_ino, index, name, namelen); + + BUG_ON(ret); + +- /* now add the forward ref */ +- ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, +- root->root_key.objectid, BTRFS_ROOT_REF_KEY, +- objectid, +- dir->i_ino, index, name, namelen); +- +- BUG_ON(ret); +- +- ret = btrfs_commit_transaction(trans, root); +- if (ret) +- goto fail_commit; +- +- new_root = btrfs_read_fs_root_no_name(root->fs_info, &key); +- BUG_ON(!new_root); +- +- trans = btrfs_start_transaction(new_root, 1); +- BUG_ON(!trans); +- +- ret = btrfs_create_subvol_root(trans, new_root, dentry, new_dirid, +- BTRFS_I(dir)->block_group); +- if (ret) +- goto fail; +- ++ d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); + fail: + nr = trans->blocks_used; +- err = btrfs_commit_transaction(trans, new_root); ++ err = btrfs_commit_transaction(trans, root); + if (err && !ret) + ret = err; +-fail_commit: +- btrfs_btree_balance_dirty(root, nr); + return ret; + } + +@@ -420,14 +400,15 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child) + * sys_mkdirat and vfs_mkdir, but we only do a single component lookup + * inside this filesystem so it's quite a bit simpler. + */ +-static noinline int btrfs_mksubvol(struct path *parent, char *name, +- int mode, int namelen, ++static noinline int btrfs_mksubvol(struct path *parent, ++ char *name, int namelen, + struct btrfs_root *snap_src) + { ++ struct inode *dir = parent->dentry->d_inode; + struct dentry *dentry; + int error; + +- mutex_lock_nested(&parent->dentry->d_inode->i_mutex, I_MUTEX_PARENT); ++ mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); + + dentry = lookup_one_len(name, parent->dentry, namelen); + error = PTR_ERR(dentry); +@@ -438,99 +419,39 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name, + if (dentry->d_inode) + goto out_dput; + +- if (!IS_POSIXACL(parent->dentry->d_inode)) +- mode &= ~current_umask(); +- + error = mnt_want_write(parent->mnt); + if (error) + goto out_dput; + +- error = btrfs_may_create(parent->dentry->d_inode, dentry); ++ error = btrfs_may_create(dir, dentry); + if (error) + goto out_drop_write; + +- /* +- * Actually perform the low-level subvolume creation after all +- * this VFS fuzz. +- * +- * Eventually we want to pass in an inode under which we create this +- * subvolume, but for now all are under the filesystem root. +- * +- * Also we should pass on the mode eventually to allow creating new +- * subvolume with specific mode bits. +- */ ++ down_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); ++ ++ if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0) ++ goto out_up_read; ++ + if (snap_src) { +- struct dentry *dir = dentry->d_parent; +- struct dentry *test = dir->d_parent; +- struct btrfs_path *path = btrfs_alloc_path(); +- int ret; +- u64 test_oid; +- u64 parent_oid = BTRFS_I(dir->d_inode)->root->root_key.objectid; +- +- test_oid = snap_src->root_key.objectid; +- +- ret = btrfs_find_root_ref(snap_src->fs_info->tree_root, +- path, parent_oid, test_oid); +- if (ret == 0) +- goto create; +- btrfs_release_path(snap_src->fs_info->tree_root, path); +- +- /* we need to make sure we aren't creating a directory loop +- * by taking a snapshot of something that has our current +- * subvol in its directory tree. So, this loops through +- * the dentries and checks the forward refs for each subvolume +- * to see if is references the subvolume where we are +- * placing this new snapshot. +- */ +- while (1) { +- if (!test || +- dir == snap_src->fs_info->sb->s_root || +- test == snap_src->fs_info->sb->s_root || +- test->d_inode->i_sb != snap_src->fs_info->sb) { +- break; +- } +- if (S_ISLNK(test->d_inode->i_mode)) { +- printk(KERN_INFO "Btrfs symlink in snapshot " +- "path, failed\n"); +- error = -EMLINK; +- btrfs_free_path(path); +- goto out_drop_write; +- } +- test_oid = +- BTRFS_I(test->d_inode)->root->root_key.objectid; +- ret = btrfs_find_root_ref(snap_src->fs_info->tree_root, +- path, test_oid, parent_oid); +- if (ret == 0) { +- printk(KERN_INFO "Btrfs snapshot creation " +- "failed, looping\n"); +- error = -EMLINK; +- btrfs_free_path(path); +- goto out_drop_write; +- } +- btrfs_release_path(snap_src->fs_info->tree_root, path); +- test = test->d_parent; +- } +-create: +- btrfs_free_path(path); +- error = create_snapshot(snap_src, dentry, name, namelen); ++ error = create_snapshot(snap_src, dentry, ++ name, namelen); + } else { +- error = create_subvol(BTRFS_I(parent->dentry->d_inode)->root, +- dentry, name, namelen); ++ error = create_subvol(BTRFS_I(dir)->root, dentry, ++ name, namelen); + } +- if (error) +- goto out_drop_write; +- +- fsnotify_mkdir(parent->dentry->d_inode, dentry); ++ if (!error) ++ fsnotify_mkdir(dir, dentry); ++out_up_read: ++ up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); + out_drop_write: + mnt_drop_write(parent->mnt); + out_dput: + dput(dentry); + out_unlock: +- mutex_unlock(&parent->dentry->d_inode->i_mutex); ++ mutex_unlock(&dir->i_mutex); + return error; + } + +- + static int btrfs_defrag_file(struct file *file) + { + struct inode *inode = fdentry(file)->d_inode; +@@ -596,9 +517,8 @@ again: + clear_page_dirty_for_io(page); + + btrfs_set_extent_delalloc(inode, page_start, page_end); +- +- unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + set_page_dirty(page); ++ unlock_extent(io_tree, page_start, page_end, GFP_NOFS); + unlock_page(page); + page_cache_release(page); + balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1); +@@ -609,7 +529,8 @@ out_unlock: + return 0; + } + +-static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) ++static noinline int btrfs_ioctl_resize(struct btrfs_root *root, ++ void __user *arg) + { + u64 new_size; + u64 old_size; +@@ -718,10 +639,7 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, + { + struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; + struct btrfs_ioctl_vol_args *vol_args; +- struct btrfs_dir_item *di; +- struct btrfs_path *path; + struct file *src_file; +- u64 root_dirid; + int namelen; + int ret = 0; + +@@ -739,32 +657,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, + goto out; + } + +- path = btrfs_alloc_path(); +- if (!path) { +- ret = -ENOMEM; +- goto out; +- } +- +- root_dirid = root->fs_info->sb->s_root->d_inode->i_ino, +- di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, +- path, root_dirid, +- vol_args->name, namelen, 0); +- btrfs_free_path(path); +- +- if (di && !IS_ERR(di)) { +- ret = -EEXIST; +- goto out; +- } +- +- if (IS_ERR(di)) { +- ret = PTR_ERR(di); +- goto out; +- } +- + if (subvol) { +- ret = btrfs_mksubvol(&file->f_path, vol_args->name, +- file->f_path.dentry->d_inode->i_mode, +- namelen, NULL); ++ ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, ++ NULL); + } else { + struct inode *src_inode; + src_file = fget(vol_args->fd); +@@ -781,17 +676,156 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, + fput(src_file); + goto out; + } +- ret = btrfs_mksubvol(&file->f_path, vol_args->name, +- file->f_path.dentry->d_inode->i_mode, +- namelen, BTRFS_I(src_inode)->root); ++ ret = btrfs_mksubvol(&file->f_path, vol_args->name, namelen, ++ BTRFS_I(src_inode)->root); + fput(src_file); + } +- + out: + kfree(vol_args); + return ret; + } + ++/* ++ * helper to check if the subvolume references other subvolumes ++ */ ++static noinline int may_destroy_subvol(struct btrfs_root *root) ++{ ++ struct btrfs_path *path; ++ struct btrfs_key key; ++ int ret; ++ ++ path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; ++ ++ key.objectid = root->root_key.objectid; ++ key.type = BTRFS_ROOT_REF_KEY; ++ key.offset = (u64)-1; ++ ++ ret = btrfs_search_slot(NULL, root->fs_info->tree_root, ++ &key, path, 0, 0); ++ if (ret < 0) ++ goto out; ++ BUG_ON(ret == 0); ++ ++ ret = 0; ++ if (path->slots[0] > 0) { ++ path->slots[0]--; ++ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); ++ if (key.objectid == root->root_key.objectid && ++ key.type == BTRFS_ROOT_REF_KEY) ++ ret = -ENOTEMPTY; ++ } ++out: ++ btrfs_free_path(path); ++ return ret; ++} ++ ++static noinline int btrfs_ioctl_snap_destroy(struct file *file, ++ void __user *arg) ++{ ++ struct dentry *parent = fdentry(file); ++ struct dentry *dentry; ++ struct inode *dir = parent->d_inode; ++ struct inode *inode; ++ struct btrfs_root *root = BTRFS_I(dir)->root; ++ struct btrfs_root *dest = NULL; ++ struct btrfs_ioctl_vol_args *vol_args; ++ struct btrfs_trans_handle *trans; ++ int namelen; ++ int ret; ++ int err = 0; ++ ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EPERM; ++ ++ vol_args = memdup_user(arg, sizeof(*vol_args)); ++ if (IS_ERR(vol_args)) ++ return PTR_ERR(vol_args); ++ ++ vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; ++ namelen = strlen(vol_args->name); ++ if (strchr(vol_args->name, '/') || ++ strncmp(vol_args->name, "..", namelen) == 0) { ++ err = -EINVAL; ++ goto out; ++ } ++ ++ err = mnt_want_write(file->f_path.mnt); ++ if (err) ++ goto out; ++ ++ mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); ++ dentry = lookup_one_len(vol_args->name, parent, namelen); ++ if (IS_ERR(dentry)) { ++ err = PTR_ERR(dentry); ++ goto out_unlock_dir; ++ } ++ ++ if (!dentry->d_inode) { ++ err = -ENOENT; ++ goto out_dput; ++ } ++ ++ inode = dentry->d_inode; ++ if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { ++ err = -EINVAL; ++ goto out_dput; ++ } ++ ++ dest = BTRFS_I(inode)->root; ++ ++ mutex_lock(&inode->i_mutex); ++ err = d_invalidate(dentry); ++ if (err) ++ goto out_unlock; ++ ++ down_write(&root->fs_info->subvol_sem); ++ ++ err = may_destroy_subvol(dest); ++ if (err) ++ goto out_up_write; ++ ++ trans = btrfs_start_transaction(root, 1); ++ ret = btrfs_unlink_subvol(trans, root, dir, ++ dest->root_key.objectid, ++ dentry->d_name.name, ++ dentry->d_name.len); ++ BUG_ON(ret); ++ ++ btrfs_record_root_in_trans(trans, dest); ++ ++ memset(&dest->root_item.drop_progress, 0, ++ sizeof(dest->root_item.drop_progress)); ++ dest->root_item.drop_level = 0; ++ btrfs_set_root_refs(&dest->root_item, 0); ++ ++ ret = btrfs_insert_orphan_item(trans, ++ root->fs_info->tree_root, ++ dest->root_key.objectid); ++ BUG_ON(ret); ++ ++ ret = btrfs_commit_transaction(trans, root); ++ BUG_ON(ret); ++ inode->i_flags |= S_DEAD; ++out_up_write: ++ up_write(&root->fs_info->subvol_sem); ++out_unlock: ++ mutex_unlock(&inode->i_mutex); ++ if (!err) { ++ btrfs_invalidate_inodes(dest); ++ d_delete(dentry); ++ } ++out_dput: ++ dput(dentry); ++out_unlock_dir: ++ mutex_unlock(&dir->i_mutex); ++ mnt_drop_write(file->f_path.mnt); ++out: ++ kfree(vol_args); ++ return err; ++} ++ + static int btrfs_ioctl_defrag(struct file *file) + { + struct inode *inode = fdentry(file)->d_inode; +@@ -865,8 +899,8 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) + return ret; + } + +-static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, +- u64 off, u64 olen, u64 destoff) ++static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, ++ u64 off, u64 olen, u64 destoff) + { + struct inode *inode = fdentry(file)->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; +@@ -976,7 +1010,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, + + /* punch hole in destination first */ + btrfs_drop_extents(trans, root, inode, off, off + len, +- off + len, 0, &hint_byte); ++ off + len, 0, &hint_byte, 1); + + /* clone data */ + key.objectid = src->i_ino; +@@ -1071,8 +1105,7 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, + datao += off - key.offset; + datal -= off - key.offset; + } +- if (key.offset + datao + datal + key.offset > +- off + len) ++ if (key.offset + datao + datal > off + len) + datal = off + len - key.offset - datao; + /* disko == 0 means it's a hole */ + if (!disko) +@@ -1258,6 +1291,8 @@ long btrfs_ioctl(struct file *file, unsigned int + return btrfs_ioctl_snap_create(file, argp, 0); + case BTRFS_IOC_SUBVOL_CREATE: + return btrfs_ioctl_snap_create(file, argp, 1); ++ case BTRFS_IOC_SNAP_DESTROY: ++ return btrfs_ioctl_snap_destroy(file, argp); + case BTRFS_IOC_DEFRAG: + return btrfs_ioctl_defrag(file); + case BTRFS_IOC_RESIZE: +diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h +index b320b10..bc49914 100644 +--- a/fs/btrfs/ioctl.h ++++ b/fs/btrfs/ioctl.h +@@ -65,5 +65,6 @@ struct btrfs_ioctl_clone_range_args { + + #define BTRFS_IOC_SUBVOL_CREATE _IOW(BTRFS_IOCTL_MAGIC, 14, \ + struct btrfs_ioctl_vol_args) +- ++#define BTRFS_IOC_SNAP_DESTROY _IOW(BTRFS_IOCTL_MAGIC, 15, \ ++ struct btrfs_ioctl_vol_args) + #endif diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c -index d6f0806..7b2f401 100644 +index d6f0806..b5d6d24 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c -@@ -740,7 +740,6 @@ int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start, +@@ -159,8 +159,6 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, + * + * len is the length of the extent + * +- * This also sets the EXTENT_ORDERED bit on the range in the inode. +- * + * The tree is given a single reference on the ordered extent that was + * inserted. + */ +@@ -181,6 +179,7 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, + entry->start = start; + entry->len = len; + entry->disk_len = disk_len; ++ entry->bytes_left = len; + entry->inode = inode; + if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) + set_bit(type, &entry->flags); +@@ -195,9 +194,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, + &entry->rb_node); + BUG_ON(node); + +- set_extent_ordered(&BTRFS_I(inode)->io_tree, file_offset, +- entry_end(entry) - 1, GFP_NOFS); +- + spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); + list_add_tail(&entry->root_extent_list, + &BTRFS_I(inode)->root->fs_info->ordered_extents); +@@ -241,13 +237,10 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, + struct btrfs_ordered_inode_tree *tree; + struct rb_node *node; + struct btrfs_ordered_extent *entry; +- struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; + int ret; + + tree = &BTRFS_I(inode)->ordered_tree; + mutex_lock(&tree->mutex); +- clear_extent_ordered(io_tree, file_offset, file_offset + io_size - 1, +- GFP_NOFS); + node = tree_search(tree, file_offset); + if (!node) { + ret = 1; +@@ -260,11 +253,16 @@ int btrfs_dec_test_ordered_pending(struct inode *inode, + goto out; + } + +- ret = test_range_bit(io_tree, entry->file_offset, +- entry->file_offset + entry->len - 1, +- EXTENT_ORDERED, 0); +- if (ret == 0) ++ if (io_size > entry->bytes_left) { ++ printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", ++ (unsigned long long)entry->bytes_left, ++ (unsigned long long)io_size); ++ } ++ entry->bytes_left -= io_size; ++ if (entry->bytes_left == 0) + ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); ++ else ++ ret = 1; + out: + mutex_unlock(&tree->mutex); + return ret == 0; +@@ -476,6 +474,7 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) + u64 orig_end; + u64 wait_end; + struct btrfs_ordered_extent *ordered; ++ int found; + + if (start + len < start) { + orig_end = INT_LIMIT(loff_t); +@@ -502,6 +501,7 @@ again: + orig_end >> PAGE_CACHE_SHIFT); + + end = orig_end; ++ found = 0; + while (1) { + ordered = btrfs_lookup_first_ordered_extent(inode, end); + if (!ordered) +@@ -514,6 +514,7 @@ again: + btrfs_put_ordered_extent(ordered); + break; + } ++ found++; + btrfs_start_ordered_extent(inode, ordered, 1); + end = ordered->file_offset; + btrfs_put_ordered_extent(ordered); +@@ -521,8 +522,8 @@ again: + break; + end--; + } +- if (test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end, +- EXTENT_ORDERED | EXTENT_DELALLOC, 0)) { ++ if (found || test_range_bit(&BTRFS_I(inode)->io_tree, start, orig_end, ++ EXTENT_DELALLOC, 0, NULL)) { + schedule_timeout(1); + goto again; + } +@@ -613,7 +614,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, + */ + if (test_range_bit(io_tree, disk_i_size, + ordered->file_offset + ordered->len - 1, +- EXTENT_DELALLOC, 0)) { ++ EXTENT_DELALLOC, 0, NULL)) { + goto out; + } + /* +@@ -664,7 +665,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, + */ + if (i_size_test > entry_end(ordered) && + !test_range_bit(io_tree, entry_end(ordered), i_size_test - 1, +- EXTENT_DELALLOC, 0)) { ++ EXTENT_DELALLOC, 0, NULL)) { + new_i_size = min_t(u64, i_size_test, i_size_read(inode)); + } + BTRFS_I(inode)->disk_i_size = new_i_size; +@@ -740,7 +741,6 @@ int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start, .nr_to_write = mapping->nrpages * 2, .range_start = start, .range_end = end, @@ -1605779,8 +1680809,716 @@ index d6f0806..7b2f401 100644 }; return btrfs_writepages(mapping, &wbc); } +diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h +index 3d31c88..993a7ea 100644 +--- a/fs/btrfs/ordered-data.h ++++ b/fs/btrfs/ordered-data.h +@@ -85,6 +85,9 @@ struct btrfs_ordered_extent { + /* extent length on disk */ + u64 disk_len; + ++ /* number of bytes that still need writing */ ++ u64 bytes_left; ++ + /* flags (described above) */ + unsigned long flags; + +diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c +index 3c0d52a..79cba5f 100644 +--- a/fs/btrfs/orphan.c ++++ b/fs/btrfs/orphan.c +@@ -65,3 +65,23 @@ out: + btrfs_free_path(path); + return ret; + } ++ ++int btrfs_find_orphan_item(struct btrfs_root *root, u64 offset) ++{ ++ struct btrfs_path *path; ++ struct btrfs_key key; ++ int ret; ++ ++ key.objectid = BTRFS_ORPHAN_OBJECTID; ++ key.type = BTRFS_ORPHAN_ITEM_KEY; ++ key.offset = offset; ++ ++ path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; ++ ++ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); ++ ++ btrfs_free_path(path); ++ return ret; ++} +diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c +index c04f7f2..361ad32 100644 +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -121,6 +121,15 @@ struct inodevec { + int nr; + }; + ++#define MAX_EXTENTS 128 ++ ++struct file_extent_cluster { ++ u64 start; ++ u64 end; ++ u64 boundary[MAX_EXTENTS]; ++ unsigned int nr; ++}; ++ + struct reloc_control { + /* block group to relocate */ + struct btrfs_block_group_cache *block_group; +@@ -2180,7 +2189,7 @@ static int tree_block_processed(u64 bytenr, u32 blocksize, + struct reloc_control *rc) + { + if (test_range_bit(&rc->processed_blocks, bytenr, +- bytenr + blocksize - 1, EXTENT_DIRTY, 1)) ++ bytenr + blocksize - 1, EXTENT_DIRTY, 1, NULL)) + return 1; + return 0; + } +@@ -2529,56 +2538,94 @@ out: + } + + static noinline_for_stack +-int relocate_inode_pages(struct inode *inode, u64 start, u64 len) ++int setup_extent_mapping(struct inode *inode, u64 start, u64 end, ++ u64 block_start) ++{ ++ struct btrfs_root *root = BTRFS_I(inode)->root; ++ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; ++ struct extent_map *em; ++ int ret = 0; ++ ++ em = alloc_extent_map(GFP_NOFS); ++ if (!em) ++ return -ENOMEM; ++ ++ em->start = start; ++ em->len = end + 1 - start; ++ em->block_len = em->len; ++ em->block_start = block_start; ++ em->bdev = root->fs_info->fs_devices->latest_bdev; ++ set_bit(EXTENT_FLAG_PINNED, &em->flags); ++ ++ lock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); ++ while (1) { ++ write_lock(&em_tree->lock); ++ ret = add_extent_mapping(em_tree, em); ++ write_unlock(&em_tree->lock); ++ if (ret != -EEXIST) { ++ free_extent_map(em); ++ break; ++ } ++ btrfs_drop_extent_cache(inode, start, end, 0); ++ } ++ unlock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); ++ return ret; ++} ++ ++static int relocate_file_extent_cluster(struct inode *inode, ++ struct file_extent_cluster *cluster) + { + u64 page_start; + u64 page_end; +- unsigned long i; +- unsigned long first_index; ++ u64 offset = BTRFS_I(inode)->index_cnt; ++ unsigned long index; + unsigned long last_index; +- unsigned int total_read = 0; +- unsigned int total_dirty = 0; ++ unsigned int dirty_page = 0; + struct page *page; + struct file_ra_state *ra; +- struct btrfs_ordered_extent *ordered; +- struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; ++ int nr = 0; + int ret = 0; + ++ if (!cluster->nr) ++ return 0; ++ + ra = kzalloc(sizeof(*ra), GFP_NOFS); + if (!ra) + return -ENOMEM; + ++ index = (cluster->start - offset) >> PAGE_CACHE_SHIFT; ++ last_index = (cluster->end - offset) >> PAGE_CACHE_SHIFT; ++ + mutex_lock(&inode->i_mutex); +- first_index = start >> PAGE_CACHE_SHIFT; +- last_index = (start + len - 1) >> PAGE_CACHE_SHIFT; + +- /* make sure the dirty trick played by the caller work */ +- while (1) { +- ret = invalidate_inode_pages2_range(inode->i_mapping, +- first_index, last_index); +- if (ret != -EBUSY) +- break; +- schedule_timeout(HZ/10); +- } ++ i_size_write(inode, cluster->end + 1 - offset); ++ ret = setup_extent_mapping(inode, cluster->start - offset, ++ cluster->end - offset, cluster->start); + if (ret) + goto out_unlock; + + file_ra_state_init(ra, inode->i_mapping); + +- for (i = first_index ; i <= last_index; i++) { +- if (total_read % ra->ra_pages == 0) { +- btrfs_force_ra(inode->i_mapping, ra, NULL, i, +- min(last_index, ra->ra_pages + i - 1)); +- } +- total_read++; +-again: +- if (((u64)i << PAGE_CACHE_SHIFT) > i_size_read(inode)) +- BUG_ON(1); +- page = grab_cache_page(inode->i_mapping, i); ++ WARN_ON(cluster->start != cluster->boundary[0]); ++ while (index <= last_index) { ++ page = find_lock_page(inode->i_mapping, index); + if (!page) { +- ret = -ENOMEM; +- goto out_unlock; ++ page_cache_sync_readahead(inode->i_mapping, ++ ra, NULL, index, ++ last_index + 1 - index); ++ page = grab_cache_page(inode->i_mapping, index); ++ if (!page) { ++ ret = -ENOMEM; ++ goto out_unlock; ++ } ++ } ++ ++ if (PageReadahead(page)) { ++ page_cache_async_readahead(inode->i_mapping, ++ ra, NULL, page, index, ++ last_index + 1 - index); + } ++ + if (!PageUptodate(page)) { + btrfs_readpage(NULL, page); + lock_page(page); +@@ -2589,75 +2636,79 @@ again: + goto out_unlock; + } + } +- wait_on_page_writeback(page); + + page_start = (u64)page->index << PAGE_CACHE_SHIFT; + page_end = page_start + PAGE_CACHE_SIZE - 1; +- lock_extent(io_tree, page_start, page_end, GFP_NOFS); +- +- ordered = btrfs_lookup_ordered_extent(inode, page_start); +- if (ordered) { +- unlock_extent(io_tree, page_start, page_end, GFP_NOFS); +- unlock_page(page); +- page_cache_release(page); +- btrfs_start_ordered_extent(inode, ordered, 1); +- btrfs_put_ordered_extent(ordered); +- goto again; +- } ++ ++ lock_extent(&BTRFS_I(inode)->io_tree, ++ page_start, page_end, GFP_NOFS); ++ + set_page_extent_mapped(page); + +- if (i == first_index) +- set_extent_bits(io_tree, page_start, page_end, ++ if (nr < cluster->nr && ++ page_start + offset == cluster->boundary[nr]) { ++ set_extent_bits(&BTRFS_I(inode)->io_tree, ++ page_start, page_end, + EXTENT_BOUNDARY, GFP_NOFS); ++ nr++; ++ } + btrfs_set_extent_delalloc(inode, page_start, page_end); + + set_page_dirty(page); +- total_dirty++; ++ dirty_page++; + +- unlock_extent(io_tree, page_start, page_end, GFP_NOFS); ++ unlock_extent(&BTRFS_I(inode)->io_tree, ++ page_start, page_end, GFP_NOFS); + unlock_page(page); + page_cache_release(page); ++ ++ index++; ++ if (nr < cluster->nr && ++ page_end + 1 + offset == cluster->boundary[nr]) { ++ balance_dirty_pages_ratelimited_nr(inode->i_mapping, ++ dirty_page); ++ dirty_page = 0; ++ } ++ } ++ if (dirty_page) { ++ balance_dirty_pages_ratelimited_nr(inode->i_mapping, ++ dirty_page); + } ++ WARN_ON(nr != cluster->nr); + out_unlock: + mutex_unlock(&inode->i_mutex); + kfree(ra); +- balance_dirty_pages_ratelimited_nr(inode->i_mapping, total_dirty); + return ret; + } + + static noinline_for_stack +-int relocate_data_extent(struct inode *inode, struct btrfs_key *extent_key) ++int relocate_data_extent(struct inode *inode, struct btrfs_key *extent_key, ++ struct file_extent_cluster *cluster) + { +- struct btrfs_root *root = BTRFS_I(inode)->root; +- struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; +- struct extent_map *em; +- u64 start = extent_key->objectid - BTRFS_I(inode)->index_cnt; +- u64 end = start + extent_key->offset - 1; +- +- em = alloc_extent_map(GFP_NOFS); +- em->start = start; +- em->len = extent_key->offset; +- em->block_len = extent_key->offset; +- em->block_start = extent_key->objectid; +- em->bdev = root->fs_info->fs_devices->latest_bdev; +- set_bit(EXTENT_FLAG_PINNED, &em->flags); ++ int ret; + +- /* setup extent map to cheat btrfs_readpage */ +- lock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); +- while (1) { +- int ret; +- spin_lock(&em_tree->lock); +- ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); +- if (ret != -EEXIST) { +- free_extent_map(em); +- break; +- } +- btrfs_drop_extent_cache(inode, start, end, 0); ++ if (cluster->nr > 0 && extent_key->objectid != cluster->end + 1) { ++ ret = relocate_file_extent_cluster(inode, cluster); ++ if (ret) ++ return ret; ++ cluster->nr = 0; + } +- unlock_extent(&BTRFS_I(inode)->io_tree, start, end, GFP_NOFS); + +- return relocate_inode_pages(inode, start, extent_key->offset); ++ if (!cluster->nr) ++ cluster->start = extent_key->objectid; ++ else ++ BUG_ON(cluster->nr >= MAX_EXTENTS); ++ cluster->end = extent_key->objectid + extent_key->offset - 1; ++ cluster->boundary[cluster->nr] = extent_key->objectid; ++ cluster->nr++; ++ ++ if (cluster->nr >= MAX_EXTENTS) { ++ ret = relocate_file_extent_cluster(inode, cluster); ++ if (ret) ++ return ret; ++ cluster->nr = 0; ++ } ++ return 0; + } + + #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 +@@ -3203,10 +3254,12 @@ static int check_extent_flags(u64 flags) + return 0; + } + ++ + static noinline_for_stack int relocate_block_group(struct reloc_control *rc) + { + struct rb_root blocks = RB_ROOT; + struct btrfs_key key; ++ struct file_extent_cluster *cluster; + struct btrfs_trans_handle *trans = NULL; + struct btrfs_path *path; + struct btrfs_extent_item *ei; +@@ -3216,10 +3269,17 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) + int ret; + int err = 0; + ++ cluster = kzalloc(sizeof(*cluster), GFP_NOFS); ++ if (!cluster) ++ return -ENOMEM; ++ + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + ++ rc->extents_found = 0; ++ rc->extents_skipped = 0; ++ + rc->search_start = rc->block_group->key.objectid; + clear_extent_bits(&rc->processed_blocks, 0, (u64)-1, EXTENT_DIRTY, + GFP_NOFS); +@@ -3306,14 +3366,15 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) + } + + nr = trans->blocks_used; +- btrfs_end_transaction_throttle(trans, rc->extent_root); ++ btrfs_end_transaction(trans, rc->extent_root); + trans = NULL; + btrfs_btree_balance_dirty(rc->extent_root, nr); + + if (rc->stage == MOVE_DATA_EXTENTS && + (flags & BTRFS_EXTENT_FLAG_DATA)) { + rc->found_file_extent = 1; +- ret = relocate_data_extent(rc->data_inode, &key); ++ ret = relocate_data_extent(rc->data_inode, ++ &key, cluster); + if (ret < 0) { + err = ret; + break; +@@ -3328,6 +3389,14 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) + btrfs_btree_balance_dirty(rc->extent_root, nr); + } + ++ if (!err) { ++ ret = relocate_file_extent_cluster(rc->data_inode, cluster); ++ if (ret < 0) ++ err = ret; ++ } ++ ++ kfree(cluster); ++ + rc->create_reloc_root = 0; + smp_mb(); + +@@ -3348,8 +3417,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) + } + + static int __insert_orphan_inode(struct btrfs_trans_handle *trans, +- struct btrfs_root *root, +- u64 objectid, u64 size) ++ struct btrfs_root *root, u64 objectid) + { + struct btrfs_path *path; + struct btrfs_inode_item *item; +@@ -3368,7 +3436,7 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans, + item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_inode_item); + memset_extent_buffer(leaf, 0, (unsigned long)item, sizeof(*item)); + btrfs_set_inode_generation(leaf, item, 1); +- btrfs_set_inode_size(leaf, item, size); ++ btrfs_set_inode_size(leaf, item, 0); + btrfs_set_inode_mode(leaf, item, S_IFREG | 0600); + btrfs_set_inode_flags(leaf, item, BTRFS_INODE_NOCOMPRESS); + btrfs_mark_buffer_dirty(leaf); +@@ -3404,12 +3472,7 @@ static struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info, + if (err) + goto out; + +- err = __insert_orphan_inode(trans, root, objectid, group->key.offset); +- BUG_ON(err); +- +- err = btrfs_insert_file_extent(trans, root, objectid, 0, 0, 0, +- group->key.offset, 0, group->key.offset, +- 0, 0, 0); ++ err = __insert_orphan_inode(trans, root, objectid); + BUG_ON(err); + + key.objectid = objectid; +@@ -3475,14 +3538,15 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) + btrfs_wait_ordered_extents(fs_info->tree_root, 0); + + while (1) { +- mutex_lock(&fs_info->cleaner_mutex); +- btrfs_clean_old_snapshots(fs_info->tree_root); +- mutex_unlock(&fs_info->cleaner_mutex); +- + rc->extents_found = 0; + rc->extents_skipped = 0; + ++ mutex_lock(&fs_info->cleaner_mutex); ++ ++ btrfs_clean_old_snapshots(fs_info->tree_root); + ret = relocate_block_group(rc); ++ ++ mutex_unlock(&fs_info->cleaner_mutex); + if (ret < 0) { + err = ret; + break; +@@ -3514,10 +3578,10 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start) + } + } + +- filemap_fdatawrite_range(fs_info->btree_inode->i_mapping, +- rc->block_group->key.objectid, +- rc->block_group->key.objectid + +- rc->block_group->key.offset - 1); ++ filemap_write_and_wait_range(fs_info->btree_inode->i_mapping, ++ rc->block_group->key.objectid, ++ rc->block_group->key.objectid + ++ rc->block_group->key.offset - 1); + + WARN_ON(rc->block_group->pinned > 0); + WARN_ON(rc->block_group->reserved > 0); +@@ -3530,6 +3594,26 @@ out: + return err; + } + ++static noinline_for_stack int mark_garbage_root(struct btrfs_root *root) ++{ ++ struct btrfs_trans_handle *trans; ++ int ret; ++ ++ trans = btrfs_start_transaction(root->fs_info->tree_root, 1); ++ ++ memset(&root->root_item.drop_progress, 0, ++ sizeof(root->root_item.drop_progress)); ++ root->root_item.drop_level = 0; ++ btrfs_set_root_refs(&root->root_item, 0); ++ ret = btrfs_update_root(trans, root->fs_info->tree_root, ++ &root->root_key, &root->root_item); ++ BUG_ON(ret); ++ ++ ret = btrfs_end_transaction(trans, root->fs_info->tree_root); ++ BUG_ON(ret); ++ return 0; ++} ++ + /* + * recover relocation interrupted by system crash. + * +@@ -3589,8 +3673,12 @@ int btrfs_recover_relocation(struct btrfs_root *root) + fs_root = read_fs_root(root->fs_info, + reloc_root->root_key.offset); + if (IS_ERR(fs_root)) { +- err = PTR_ERR(fs_root); +- goto out; ++ ret = PTR_ERR(fs_root); ++ if (ret != -ENOENT) { ++ err = ret; ++ goto out; ++ } ++ mark_garbage_root(reloc_root); + } + } + +diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c +index 0ddc6d6..9351428 100644 +--- a/fs/btrfs/root-tree.c ++++ b/fs/btrfs/root-tree.c +@@ -94,17 +94,23 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, + goto out; + + BUG_ON(ret == 0); ++ if (path->slots[0] == 0) { ++ ret = 1; ++ goto out; ++ } + l = path->nodes[0]; +- BUG_ON(path->slots[0] == 0); + slot = path->slots[0] - 1; + btrfs_item_key_to_cpu(l, &found_key, slot); +- if (found_key.objectid != objectid) { ++ if (found_key.objectid != objectid || ++ found_key.type != BTRFS_ROOT_ITEM_KEY) { + ret = 1; + goto out; + } +- read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), +- sizeof(*item)); +- memcpy(key, &found_key, sizeof(found_key)); ++ if (item) ++ read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), ++ sizeof(*item)); ++ if (key) ++ memcpy(key, &found_key, sizeof(found_key)); + ret = 0; + out: + btrfs_free_path(path); +@@ -249,6 +255,59 @@ err: + return ret; + } + ++int btrfs_find_orphan_roots(struct btrfs_root *tree_root) ++{ ++ struct extent_buffer *leaf; ++ struct btrfs_path *path; ++ struct btrfs_key key; ++ int err = 0; ++ int ret; ++ ++ path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; ++ ++ key.objectid = BTRFS_ORPHAN_OBJECTID; ++ key.type = BTRFS_ORPHAN_ITEM_KEY; ++ key.offset = 0; ++ ++ while (1) { ++ ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0); ++ if (ret < 0) { ++ err = ret; ++ break; ++ } ++ ++ leaf = path->nodes[0]; ++ if (path->slots[0] >= btrfs_header_nritems(leaf)) { ++ ret = btrfs_next_leaf(tree_root, path); ++ if (ret < 0) ++ err = ret; ++ if (ret != 0) ++ break; ++ leaf = path->nodes[0]; ++ } ++ ++ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); ++ btrfs_release_path(tree_root, path); ++ ++ if (key.objectid != BTRFS_ORPHAN_OBJECTID || ++ key.type != BTRFS_ORPHAN_ITEM_KEY) ++ break; ++ ++ ret = btrfs_find_dead_roots(tree_root, key.offset); ++ if (ret) { ++ err = ret; ++ break; ++ } ++ ++ key.offset++; ++ } ++ ++ btrfs_free_path(path); ++ return err; ++} ++ + /* drop the root item for 'key' from 'root' */ + int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct btrfs_key *key) +@@ -278,31 +337,57 @@ out: + return ret; + } + +-#if 0 /* this will get used when snapshot deletion is implemented */ + int btrfs_del_root_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *tree_root, +- u64 root_id, u8 type, u64 ref_id) ++ u64 root_id, u64 ref_id, u64 dirid, u64 *sequence, ++ const char *name, int name_len) ++ + { ++ struct btrfs_path *path; ++ struct btrfs_root_ref *ref; ++ struct extent_buffer *leaf; + struct btrfs_key key; ++ unsigned long ptr; ++ int err = 0; + int ret; +- struct btrfs_path *path; + + path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; + + key.objectid = root_id; +- key.type = type; ++ key.type = BTRFS_ROOT_BACKREF_KEY; + key.offset = ref_id; +- ++again: + ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); +- BUG_ON(ret); +- +- ret = btrfs_del_item(trans, tree_root, path); +- BUG_ON(ret); ++ BUG_ON(ret < 0); ++ if (ret == 0) { ++ leaf = path->nodes[0]; ++ ref = btrfs_item_ptr(leaf, path->slots[0], ++ struct btrfs_root_ref); ++ ++ WARN_ON(btrfs_root_ref_dirid(leaf, ref) != dirid); ++ WARN_ON(btrfs_root_ref_name_len(leaf, ref) != name_len); ++ ptr = (unsigned long)(ref + 1); ++ WARN_ON(memcmp_extent_buffer(leaf, name, ptr, name_len)); ++ *sequence = btrfs_root_ref_sequence(leaf, ref); ++ ++ ret = btrfs_del_item(trans, tree_root, path); ++ BUG_ON(ret); ++ } else ++ err = -ENOENT; ++ ++ if (key.type == BTRFS_ROOT_BACKREF_KEY) { ++ btrfs_release_path(tree_root, path); ++ key.objectid = ref_id; ++ key.type = BTRFS_ROOT_REF_KEY; ++ key.offset = root_id; ++ goto again; ++ } + + btrfs_free_path(path); +- return ret; ++ return err; + } +-#endif + + int btrfs_find_root_ref(struct btrfs_root *tree_root, + struct btrfs_path *path, +@@ -319,7 +404,6 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root, + return ret; + } + +- + /* + * add a btrfs_root_ref item. type is either BTRFS_ROOT_REF_KEY + * or BTRFS_ROOT_BACKREF_KEY. +@@ -335,8 +419,7 @@ int btrfs_find_root_ref(struct btrfs_root *tree_root, + */ + int btrfs_add_root_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *tree_root, +- u64 root_id, u8 type, u64 ref_id, +- u64 dirid, u64 sequence, ++ u64 root_id, u64 ref_id, u64 dirid, u64 sequence, + const char *name, int name_len) + { + struct btrfs_key key; +@@ -346,13 +429,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, + struct extent_buffer *leaf; + unsigned long ptr; + +- + path = btrfs_alloc_path(); ++ if (!path) ++ return -ENOMEM; + + key.objectid = root_id; +- key.type = type; ++ key.type = BTRFS_ROOT_BACKREF_KEY; + key.offset = ref_id; +- ++again: + ret = btrfs_insert_empty_item(trans, tree_root, path, &key, + sizeof(*ref) + name_len); + BUG_ON(ret); +@@ -366,6 +450,14 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans, + write_extent_buffer(leaf, name, ptr, name_len); + btrfs_mark_buffer_dirty(leaf); + ++ if (key.type == BTRFS_ROOT_BACKREF_KEY) { ++ btrfs_release_path(tree_root, path); ++ key.objectid = ref_id; ++ key.type = BTRFS_ROOT_REF_KEY; ++ key.offset = root_id; ++ goto again; ++ } ++ + btrfs_free_path(path); +- return ret; ++ return 0; + } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c -index 6d6d06c..2db17cd 100644 +index 6d6d06c..6703538 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -51,7 +51,7 @@ @@ -1605792,19 +1681530,153 @@ index 6d6d06c..2db17cd 100644 static void btrfs_put_super(struct super_block *sb) { -@@ -675,7 +675,7 @@ static int btrfs_unfreeze(struct super_block *sb) +@@ -675,7 +675,8 @@ static int btrfs_unfreeze(struct super_block *sb) return 0; } -static struct super_operations btrfs_super_ops = { +static const struct super_operations btrfs_super_ops = { ++ .drop_inode = btrfs_drop_inode, .delete_inode = btrfs_delete_inode, .put_super = btrfs_put_super, .sync_fs = btrfs_sync_fs, +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index cdbb502..88f866f 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -104,7 +104,6 @@ static noinline int record_root_in_trans(struct btrfs_trans_handle *trans, + { + if (root->ref_cows && root->last_trans < trans->transid) { + WARN_ON(root == root->fs_info->extent_root); +- WARN_ON(root->root_item.refs == 0); + WARN_ON(root->commit_root != root->node); + + radix_tree_tag_set(&root->fs_info->fs_roots_radix, +@@ -720,7 +719,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, + memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); + + key.objectid = objectid; +- key.offset = 0; ++ /* record when the snapshot was created in key.offset */ ++ key.offset = trans->transid; + btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + + old = btrfs_lock_root_node(root); +@@ -778,24 +778,14 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, + ret = btrfs_update_inode(trans, parent_root, parent_inode); + BUG_ON(ret); + +- /* add the backref first */ + ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, + pending->root_key.objectid, +- BTRFS_ROOT_BACKREF_KEY, + parent_root->root_key.objectid, + parent_inode->i_ino, index, pending->name, + namelen); + + BUG_ON(ret); + +- /* now add the forward ref */ +- ret = btrfs_add_root_ref(trans, parent_root->fs_info->tree_root, +- parent_root->root_key.objectid, +- BTRFS_ROOT_REF_KEY, +- pending->root_key.objectid, +- parent_inode->i_ino, index, pending->name, +- namelen); +- + inode = btrfs_lookup_dentry(parent_inode, pending->dentry); + d_instantiate(pending->dentry, inode); + fail: +@@ -874,7 +864,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + unsigned long timeout = 1; + struct btrfs_transaction *cur_trans; + struct btrfs_transaction *prev_trans = NULL; +- struct extent_io_tree *pinned_copy; + DEFINE_WAIT(wait); + int ret; + int should_grow = 0; +@@ -915,13 +904,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + return 0; + } + +- pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS); +- if (!pinned_copy) +- return -ENOMEM; +- +- extent_io_tree_init(pinned_copy, +- root->fs_info->btree_inode->i_mapping, GFP_NOFS); +- + trans->transaction->in_commit = 1; + trans->transaction->blocked = 1; + if (cur_trans->list.prev != &root->fs_info->trans_list) { +@@ -1019,6 +1001,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + ret = commit_cowonly_roots(trans, root); + BUG_ON(ret); + ++ btrfs_prepare_extent_commit(trans, root); ++ + cur_trans = root->fs_info->running_transaction; + spin_lock(&root->fs_info->new_trans_lock); + root->fs_info->running_transaction = NULL; +@@ -1042,8 +1026,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy, + sizeof(root->fs_info->super_copy)); + +- btrfs_copy_pinned(root, pinned_copy); +- + trans->transaction->blocked = 0; + + wake_up(&root->fs_info->transaction_wait); +@@ -1059,8 +1041,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, + */ + mutex_unlock(&root->fs_info->tree_log_mutex); + +- btrfs_finish_extent_commit(trans, root, pinned_copy); +- kfree(pinned_copy); ++ btrfs_finish_extent_commit(trans, root); + + /* do the directory inserts of any pending snapshot creations */ + finish_pending_snapshots(trans, root->fs_info); +@@ -1096,8 +1077,13 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) + + while (!list_empty(&list)) { + root = list_entry(list.next, struct btrfs_root, root_list); +- list_del_init(&root->root_list); +- btrfs_drop_snapshot(root, 0); ++ list_del(&root->root_list); ++ ++ if (btrfs_header_backref_rev(root->node) < ++ BTRFS_MIXED_BACKREF_REV) ++ btrfs_drop_snapshot(root, 0); ++ else ++ btrfs_drop_snapshot(root, 1); + } + return 0; + } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c -index d91b0de..30c0d45 100644 +index d91b0de..7827841 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c +@@ -263,8 +263,8 @@ static int process_one_buffer(struct btrfs_root *log, + struct walk_control *wc, u64 gen) + { + if (wc->pin) +- btrfs_update_pinned_extents(log->fs_info->extent_root, +- eb->start, eb->len, 1); ++ btrfs_pin_extent(log->fs_info->extent_root, ++ eb->start, eb->len, 0); + + if (btrfs_buffer_uptodate(eb, gen)) { + if (wc->write) +@@ -534,7 +534,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, + saved_nbytes = inode_get_bytes(inode); + /* drop any overlapping extents */ + ret = btrfs_drop_extents(trans, root, inode, +- start, extent_end, extent_end, start, &alloc_hint); ++ start, extent_end, extent_end, start, &alloc_hint, 1); + BUG_ON(ret); + + if (found_type == BTRFS_FILE_EXTENT_REG || @@ -2605,7 +2605,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans, extent); cs = btrfs_file_extent_offset(src, extent); @@ -1605814,8 +1681686,67 @@ index d91b0de..30c0d45 100644 if (btrfs_file_extent_compression(src, extent)) { cs = 0; +@@ -2841,7 +2841,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, + if (!parent || !parent->d_inode || sb != parent->d_inode->i_sb) + break; + +- if (parent == sb->s_root) ++ if (IS_ROOT(parent)) + break; + + parent = parent->d_parent; +@@ -2880,6 +2880,12 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, + goto end_no_trans; + } + ++ if (root != BTRFS_I(inode)->root || ++ btrfs_root_refs(&root->root_item) == 0) { ++ ret = 1; ++ goto end_no_trans; ++ } ++ + ret = check_parent_dirs_for_sync(trans, inode, parent, + sb, last_committed); + if (ret) +@@ -2907,12 +2913,15 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, + break; + + inode = parent->d_inode; ++ if (root != BTRFS_I(inode)->root) ++ break; ++ + if (BTRFS_I(inode)->generation > + root->fs_info->last_trans_committed) { + ret = btrfs_log_inode(trans, root, inode, inode_only); + BUG_ON(ret); + } +- if (parent == sb->s_root) ++ if (IS_ROOT(parent)) + break; + + parent = parent->d_parent; +@@ -2951,7 +2960,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) + struct btrfs_key tmp_key; + struct btrfs_root *log; + struct btrfs_fs_info *fs_info = log_root_tree->fs_info; +- u64 highest_inode; + struct walk_control wc = { + .process_func = process_one_buffer, + .stage = 0, +@@ -3010,11 +3018,6 @@ again: + path); + BUG_ON(ret); + } +- ret = btrfs_find_highest_inode(wc.replay_dest, &highest_inode); +- if (ret == 0) { +- wc.replay_dest->highest_inode = highest_inode; +- wc.replay_dest->last_inode_alloc = highest_inode; +- } + + key.offset = found_key.offset - 1; + wc.replay_dest->log_root = NULL; diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c -index 5dbefd1..5cf405b 100644 +index 5dbefd1..23e7d36 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -260,7 +260,7 @@ loop_lock: @@ -1605827,7 +1681758,306 @@ index 5dbefd1..5cf405b 100644 num_sync_run++; if (need_resched()) { -@@ -2903,7 +2903,7 @@ static noinline int schedule_bio(struct btrfs_root *root, +@@ -276,7 +276,7 @@ loop_lock: + * is now congested. Back off and let other work structs + * run instead + */ +- if (pending && bdi_write_congested(bdi) && batch_run > 32 && ++ if (pending && bdi_write_congested(bdi) && batch_run > 8 && + fs_info->fs_devices->open_devices > 1) { + struct io_context *ioc; + +@@ -719,10 +719,9 @@ error: + * called very infrequently and that a given device has a small number + * of extents + */ +-static noinline int find_free_dev_extent(struct btrfs_trans_handle *trans, +- struct btrfs_device *device, +- u64 num_bytes, u64 *start, +- u64 *max_avail) ++int find_free_dev_extent(struct btrfs_trans_handle *trans, ++ struct btrfs_device *device, u64 num_bytes, ++ u64 *start, u64 *max_avail) + { + struct btrfs_key key; + struct btrfs_root *root = device->dev_root; +@@ -1736,6 +1735,10 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, + extent_root = root->fs_info->extent_root; + em_tree = &root->fs_info->mapping_tree.map_tree; + ++ ret = btrfs_can_relocate(extent_root, chunk_offset); ++ if (ret) ++ return -ENOSPC; ++ + /* step one, relocate all the extents inside this chunk */ + ret = btrfs_relocate_block_group(extent_root, chunk_offset); + BUG_ON(ret); +@@ -1749,9 +1752,9 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, + * step two, delete the device extents and the + * chunk tree entries + */ +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, chunk_offset, 1); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + BUG_ON(em->start > chunk_offset || + em->start + em->len < chunk_offset); +@@ -1780,9 +1783,9 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, + ret = btrfs_remove_block_group(trans, extent_root, chunk_offset); + BUG_ON(ret); + +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + remove_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + + kfree(map); + em->bdev = NULL; +@@ -1807,12 +1810,15 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root) + struct btrfs_key found_key; + u64 chunk_tree = chunk_root->root_key.objectid; + u64 chunk_type; ++ bool retried = false; ++ int failed = 0; + int ret; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + ++again: + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; + key.offset = (u64)-1; + key.type = BTRFS_CHUNK_ITEM_KEY; +@@ -1842,7 +1848,10 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root) + ret = btrfs_relocate_chunk(chunk_root, chunk_tree, + found_key.objectid, + found_key.offset); +- BUG_ON(ret); ++ if (ret == -ENOSPC) ++ failed++; ++ else if (ret) ++ BUG(); + } + + if (found_key.offset == 0) +@@ -1850,6 +1859,14 @@ static int btrfs_relocate_sys_chunks(struct btrfs_root *root) + key.offset = found_key.offset - 1; + } + ret = 0; ++ if (failed && !retried) { ++ failed = 0; ++ retried = true; ++ goto again; ++ } else if (failed && retried) { ++ WARN_ON(1); ++ ret = -ENOSPC; ++ } + error: + btrfs_free_path(path); + return ret; +@@ -1894,6 +1911,8 @@ int btrfs_balance(struct btrfs_root *dev_root) + continue; + + ret = btrfs_shrink_device(device, old_size - size_to_free); ++ if (ret == -ENOSPC) ++ break; + BUG_ON(ret); + + trans = btrfs_start_transaction(dev_root, 1); +@@ -1938,9 +1957,8 @@ int btrfs_balance(struct btrfs_root *dev_root) + chunk = btrfs_item_ptr(path->nodes[0], + path->slots[0], + struct btrfs_chunk); +- key.offset = found_key.offset; + /* chunk zero is special */ +- if (key.offset == 0) ++ if (found_key.offset == 0) + break; + + btrfs_release_path(chunk_root, path); +@@ -1948,7 +1966,8 @@ int btrfs_balance(struct btrfs_root *dev_root) + chunk_root->root_key.objectid, + found_key.objectid, + found_key.offset); +- BUG_ON(ret); ++ BUG_ON(ret && ret != -ENOSPC); ++ key.offset = found_key.offset - 1; + } + ret = 0; + error: +@@ -1974,10 +1993,13 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + u64 chunk_offset; + int ret; + int slot; ++ int failed = 0; ++ bool retried = false; + struct extent_buffer *l; + struct btrfs_key key; + struct btrfs_super_block *super_copy = &root->fs_info->super_copy; + u64 old_total = btrfs_super_total_bytes(super_copy); ++ u64 old_size = device->total_bytes; + u64 diff = device->total_bytes - new_size; + + if (new_size >= device->total_bytes) +@@ -1987,12 +2009,6 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + if (!path) + return -ENOMEM; + +- trans = btrfs_start_transaction(root, 1); +- if (!trans) { +- ret = -ENOMEM; +- goto done; +- } +- + path->reada = 2; + + lock_chunks(root); +@@ -2001,8 +2017,8 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + if (device->writeable) + device->fs_devices->total_rw_bytes -= diff; + unlock_chunks(root); +- btrfs_end_transaction(trans, root); + ++again: + key.objectid = device->devid; + key.offset = (u64)-1; + key.type = BTRFS_DEV_EXTENT_KEY; +@@ -2017,6 +2033,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + goto done; + if (ret) { + ret = 0; ++ btrfs_release_path(root, path); + break; + } + +@@ -2024,14 +2041,18 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + slot = path->slots[0]; + btrfs_item_key_to_cpu(l, &key, path->slots[0]); + +- if (key.objectid != device->devid) ++ if (key.objectid != device->devid) { ++ btrfs_release_path(root, path); + break; ++ } + + dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent); + length = btrfs_dev_extent_length(l, dev_extent); + +- if (key.offset + length <= new_size) ++ if (key.offset + length <= new_size) { ++ btrfs_release_path(root, path); + break; ++ } + + chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); + chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); +@@ -2040,8 +2061,26 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) + + ret = btrfs_relocate_chunk(root, chunk_tree, chunk_objectid, + chunk_offset); +- if (ret) ++ if (ret && ret != -ENOSPC) + goto done; ++ if (ret == -ENOSPC) ++ failed++; ++ key.offset -= 1; ++ } ++ ++ if (failed && !retried) { ++ failed = 0; ++ retried = true; ++ goto again; ++ } else if (failed && retried) { ++ ret = -ENOSPC; ++ lock_chunks(root); ++ ++ device->total_bytes = old_size; ++ if (device->writeable) ++ device->fs_devices->total_rw_bytes += diff; ++ unlock_chunks(root); ++ goto done; + } + + /* Shrinking succeeded, else we would be at "done". */ +@@ -2294,9 +2333,9 @@ again: + em->block_len = em->len; + + em_tree = &extent_root->fs_info->mapping_tree.map_tree; +- spin_lock(&em_tree->lock); ++ write_lock(&em_tree->lock); + ret = add_extent_mapping(em_tree, em); +- spin_unlock(&em_tree->lock); ++ write_unlock(&em_tree->lock); + BUG_ON(ret); + free_extent_map(em); + +@@ -2491,9 +2530,9 @@ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset) + int readonly = 0; + int i; + +- spin_lock(&map_tree->map_tree.lock); ++ read_lock(&map_tree->map_tree.lock); + em = lookup_extent_mapping(&map_tree->map_tree, chunk_offset, 1); +- spin_unlock(&map_tree->map_tree.lock); ++ read_unlock(&map_tree->map_tree.lock); + if (!em) + return 1; + +@@ -2518,11 +2557,11 @@ void btrfs_mapping_tree_free(struct btrfs_mapping_tree *tree) + struct extent_map *em; + + while (1) { +- spin_lock(&tree->map_tree.lock); ++ write_lock(&tree->map_tree.lock); + em = lookup_extent_mapping(&tree->map_tree, 0, (u64)-1); + if (em) + remove_extent_mapping(&tree->map_tree, em); +- spin_unlock(&tree->map_tree.lock); ++ write_unlock(&tree->map_tree.lock); + if (!em) + break; + kfree(em->bdev); +@@ -2540,9 +2579,9 @@ int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len) + struct extent_map_tree *em_tree = &map_tree->map_tree; + int ret; + +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, logical, len); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + BUG_ON(!em); + + BUG_ON(em->start > logical || em->start + em->len < logical); +@@ -2604,9 +2643,9 @@ again: + atomic_set(&multi->error, 0); + } + +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, logical, *length); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + if (!em && unplug_page) + return 0; +@@ -2763,9 +2802,9 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, + u64 stripe_nr; + int i, j, nr = 0; + +- spin_lock(&em_tree->lock); ++ read_lock(&em_tree->lock); + em = lookup_extent_mapping(em_tree, chunk_start, 1); +- spin_unlock(&em_tree->lock); ++ read_unlock(&em_tree->lock); + + BUG_ON(!em || em->start != chunk_start); + map = (struct map_lookup *)em->bdev; +@@ -2903,7 +2942,7 @@ static noinline int schedule_bio(struct btrfs_root *root, bio->bi_rw |= rw; spin_lock(&device->io_lock); @@ -1605836,8 +1682066,44 @@ index 5dbefd1..5cf405b 100644 pending_bios = &device->pending_sync_bios; else pending_bios = &device->pending_bios; +@@ -3053,9 +3092,9 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + logical = key->offset; + length = btrfs_chunk_length(leaf, chunk); + +- spin_lock(&map_tree->map_tree.lock); ++ read_lock(&map_tree->map_tree.lock); + em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); +- spin_unlock(&map_tree->map_tree.lock); ++ read_unlock(&map_tree->map_tree.lock); + + /* already mapped? */ + if (em && em->start <= logical && em->start + em->len > logical) { +@@ -3114,9 +3153,9 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, + map->stripes[i].dev->in_fs_metadata = 1; + } + +- spin_lock(&map_tree->map_tree.lock); ++ write_lock(&map_tree->map_tree.lock); + ret = add_extent_mapping(&map_tree->map_tree, em); +- spin_unlock(&map_tree->map_tree.lock); ++ write_unlock(&map_tree->map_tree.lock); + BUG_ON(ret); + free_extent_map(em); + +diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h +index 5139a83..31b0fab 100644 +--- a/fs/btrfs/volumes.h ++++ b/fs/btrfs/volumes.h +@@ -181,4 +181,7 @@ int btrfs_balance(struct btrfs_root *dev_root); + void btrfs_unlock_volumes(void); + void btrfs_lock_volumes(void); + int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset); ++int find_free_dev_extent(struct btrfs_trans_handle *trans, ++ struct btrfs_device *device, u64 num_bytes, ++ u64 *start, u64 *max_avail); + #endif diff --git a/fs/buffer.c b/fs/buffer.c -index 28f320f..58cf4ad 100644 +index 28f320f..6fa5302 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -52,6 +52,7 @@ init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private) @@ -1605973,7 +1682239,26 @@ index 28f320f..58cf4ad 100644 /* utility function for filesystems that need to do work on expanding * truncates. Uses filesystem pagecache writes to allow the filesystem to -@@ -2252,6 +2263,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) +@@ -2228,16 +2239,10 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) + struct address_space *mapping = inode->i_mapping; + struct page *page; + void *fsdata; +- unsigned long limit; + int err; + +- err = -EFBIG; +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && size > (loff_t)limit) { +- send_sig(SIGXFSZ, current, 0); +- goto out; +- } +- if (size > inode->i_sb->s_maxbytes) ++ err = inode_newsize_ok(inode, size); ++ if (err) + goto out; + + err = pagecache_write_begin(NULL, mapping, size, 0, +@@ -2252,6 +2257,7 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) out: return err; } @@ -1605981,7 +1682266,7 @@ index 28f320f..58cf4ad 100644 static int cont_expand_zero(struct file *file, struct address_space *mapping, loff_t pos, loff_t *bytes) -@@ -2352,6 +2364,7 @@ int cont_write_begin(struct file *file, struct address_space *mapping, +@@ -2352,6 +2358,7 @@ int cont_write_begin(struct file *file, struct address_space *mapping, out: return err; } @@ -1605989,7 +1682274,7 @@ index 28f320f..58cf4ad 100644 int block_prepare_write(struct page *page, unsigned from, unsigned to, get_block_t *get_block) -@@ -2362,6 +2375,7 @@ int block_prepare_write(struct page *page, unsigned from, unsigned to, +@@ -2362,6 +2369,7 @@ int block_prepare_write(struct page *page, unsigned from, unsigned to, ClearPageUptodate(page); return err; } @@ -1605997,7 +1682282,7 @@ index 28f320f..58cf4ad 100644 int block_commit_write(struct page *page, unsigned from, unsigned to) { -@@ -2369,6 +2383,7 @@ int block_commit_write(struct page *page, unsigned from, unsigned to) +@@ -2369,6 +2377,7 @@ int block_commit_write(struct page *page, unsigned from, unsigned to) __block_commit_write(inode,page,from,to); return 0; } @@ -1606005,7 +1682290,7 @@ index 28f320f..58cf4ad 100644 /* * block_page_mkwrite() is not allowed to change the file size as it gets -@@ -2426,6 +2441,7 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, +@@ -2426,6 +2435,7 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, out: return ret; } @@ -1606013,7 +1682298,7 @@ index 28f320f..58cf4ad 100644 /* * nobh_write_begin()'s prereads are special: the buffer_heads are freed -@@ -2849,6 +2865,7 @@ unlock: +@@ -2849,6 +2859,7 @@ unlock: out: return err; } @@ -1606021,7 +1682306,7 @@ index 28f320f..58cf4ad 100644 /* * The generic ->writepage function for buffer-backed address_spaces -@@ -2890,6 +2907,7 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block, +@@ -2890,6 +2901,7 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block, zero_user_segment(page, offset, PAGE_CACHE_SIZE); return __block_write_full_page(inode, page, get_block, wbc, handler); } @@ -1606029,7 +1682314,7 @@ index 28f320f..58cf4ad 100644 /* * The generic ->writepage function for buffer-backed address_spaces -@@ -2900,7 +2918,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block, +@@ -2900,7 +2912,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block, return block_write_full_page_endio(page, get_block, wbc, end_buffer_async_write); } @@ -1606038,7 +1682323,7 @@ index 28f320f..58cf4ad 100644 sector_t generic_block_bmap(struct address_space *mapping, sector_t block, get_block_t *get_block) -@@ -2913,6 +2931,7 @@ sector_t generic_block_bmap(struct address_space *mapping, sector_t block, +@@ -2913,6 +2925,7 @@ sector_t generic_block_bmap(struct address_space *mapping, sector_t block, get_block(inode, block, &tmp, 0); return tmp.b_blocknr; } @@ -1606046,7 +1682331,7 @@ index 28f320f..58cf4ad 100644 static void end_bio_bh_io_sync(struct bio *bio, int err) { -@@ -2982,6 +3001,7 @@ int submit_bh(int rw, struct buffer_head * bh) +@@ -2982,6 +2995,7 @@ int submit_bh(int rw, struct buffer_head * bh) bio_put(bio); return ret; } @@ -1606054,7 +1682339,7 @@ index 28f320f..58cf4ad 100644 /** * ll_rw_block: low-level access to block devices (DEPRECATED) -@@ -3043,6 +3063,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) +@@ -3043,6 +3057,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) unlock_buffer(bh); } } @@ -1606062,7 +1682347,7 @@ index 28f320f..58cf4ad 100644 /* * For a data-integrity writeout, we need to wait upon any in-progress I/O -@@ -3071,6 +3092,7 @@ int sync_dirty_buffer(struct buffer_head *bh) +@@ -3071,6 +3086,7 @@ int sync_dirty_buffer(struct buffer_head *bh) } return ret; } @@ -1606070,7 +1682355,7 @@ index 28f320f..58cf4ad 100644 /* * try_to_free_buffers() checks if all the buffers on this particular page -@@ -3185,13 +3207,14 @@ void block_sync_page(struct page *page) +@@ -3185,13 +3201,14 @@ void block_sync_page(struct page *page) if (mapping) blk_run_backing_dev(mapping->backing_dev_info, page); } @@ -1606086,7 +1682371,7 @@ index 28f320f..58cf4ad 100644 */ SYSCALL_DEFINE2(bdflush, int, func, long, data) { -@@ -3361,29 +3384,3 @@ void __init buffer_init(void) +@@ -3361,29 +3378,3 @@ void __init buffer_init(void) max_buffer_heads = nrpages * (PAGE_SIZE / sizeof(struct buffer_head)); hotcpu_notifier(buffer_cpu_notify, 0); } @@ -1606117,7 +1682402,7 @@ index 28f320f..58cf4ad 100644 -EXPORT_SYMBOL(sync_dirty_buffer); -EXPORT_SYMBOL(unlock_buffer); diff --git a/fs/char_dev.c b/fs/char_dev.c -index a173551..3cbc57f 100644 +index a173551..d6db933 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -31,6 +31,7 @@ @@ -1606140,7 +1682425,7 @@ index a173551..3cbc57f 100644 * @name: name of this range of devices * @fops: file operations associated with this devices * -@@ -254,19 +257,17 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, +@@ -254,19 +257,16 @@ int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, * /dev. It only helps to keep track of the different owners of devices. If * your module name has only one type of devices it's ok to use e.g. the name * of the module here. @@ -1606156,7 +1682441,7 @@ index a173551..3cbc57f 100644 { struct char_device_struct *cd; struct cdev *cdev; - char *s; +- char *s; int err = -ENOMEM; - cd = __register_chrdev_region(major, 0, 256, name); @@ -1606164,16 +1682449,19 @@ index a173551..3cbc57f 100644 if (IS_ERR(cd)) return PTR_ERR(cd); -@@ -280,7 +281,7 @@ int register_chrdev(unsigned int major, const char *name, - for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) - *s = '!'; +@@ -277,10 +277,8 @@ int register_chrdev(unsigned int major, const char *name, + cdev->owner = fops->owner; + cdev->ops = fops; + kobject_set_name(&cdev->kobj, "%s", name); +- for (s = strchr(kobject_name(&cdev->kobj),'/'); s; s = strchr(s, '/')) +- *s = '!'; - err = cdev_add(cdev, MKDEV(cd->major, 0), 256); + err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); if (err) goto out; -@@ -290,7 +291,7 @@ int register_chrdev(unsigned int major, const char *name, +@@ -290,7 +288,7 @@ int register_chrdev(unsigned int major, const char *name, out: kobject_put(&cdev->kobj); out2: @@ -1606182,7 +1682470,7 @@ index a173551..3cbc57f 100644 return err; } -@@ -316,10 +317,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) +@@ -316,10 +314,23 @@ void unregister_chrdev_region(dev_t from, unsigned count) } } @@ -1606208,7 +1682496,7 @@ index a173551..3cbc57f 100644 if (cd && cd->cdev) cdev_del(cd->cdev); kfree(cd); -@@ -568,6 +582,6 @@ EXPORT_SYMBOL(cdev_alloc); +@@ -568,6 +579,6 @@ EXPORT_SYMBOL(cdev_alloc); EXPORT_SYMBOL(cdev_del); EXPORT_SYMBOL(cdev_add); EXPORT_SYMBOL(cdev_index); @@ -1606303,7 +1682591,7 @@ index 7c98095..7efe174 100644 } diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c -index 84b7525..d79ce2e 100644 +index 84b7525..90c5b39 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -50,7 +50,7 @@ @@ -1606315,7 +1682603,17 @@ index 84b7525..d79ce2e 100644 #endif /* QUOTA */ int cifsFYI = 0; -@@ -361,13 +361,10 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) +@@ -185,8 +185,7 @@ out_mount_failed: + cifs_sb->mountdata = NULL; + } + #endif +- if (cifs_sb->local_nls) +- unload_nls(cifs_sb->local_nls); ++ unload_nls(cifs_sb->local_nls); + kfree(cifs_sb); + } + return rc; +@@ -361,13 +360,10 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) static int cifs_show_options(struct seq_file *s, struct vfsmount *m) { @@ -1606332,7 +1682630,7 @@ index 84b7525..d79ce2e 100644 if (tcon->ses->userName) seq_printf(s, ",username=%s", tcon->ses->userName); if (tcon->ses->domainName) -@@ -520,7 +517,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) +@@ -520,7 +516,7 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) return rc; } @@ -1606341,7 +1682639,7 @@ index 84b7525..d79ce2e 100644 .set_xquota = cifs_xquota_set, .get_xquota = cifs_xquota_get, .set_xstate = cifs_xstate_set, -@@ -989,19 +986,19 @@ static int cifs_oplock_thread(void *dummyarg) +@@ -989,19 +985,19 @@ static int cifs_oplock_thread(void *dummyarg) if (try_to_freeze()) continue; @@ -1606366,7 +1682664,7 @@ index 84b7525..d79ce2e 100644 DeleteOplockQEntry(oplock_item); /* can not grab inode sem here since it would deadlock when oplock received on delete -@@ -1058,7 +1055,7 @@ init_cifs(void) +@@ -1058,7 +1054,7 @@ init_cifs(void) int rc = 0; cifs_proc_init(); INIT_LIST_HEAD(&cifs_tcp_ses_list); @@ -1606375,7 +1682673,7 @@ index 84b7525..d79ce2e 100644 #ifdef CONFIG_CIFS_EXPERIMENTAL INIT_LIST_HEAD(&GlobalDnotifyReqList); INIT_LIST_HEAD(&GlobalDnotifyRsp_Q); -@@ -1087,6 +1084,7 @@ init_cifs(void) +@@ -1087,6 +1083,7 @@ init_cifs(void) rwlock_init(&GlobalSMBSeslock); rwlock_init(&cifs_tcp_ses_lock); spin_lock_init(&GlobalMid_Lock); @@ -1607130,7 +1683428,7 @@ index c34b7f8..b976cea 100644 if (rc || bytes_written < bytes_to_write) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c -index 82d8383..1f09c76 100644 +index 82d8383..5e24925 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -800,7 +800,7 @@ set_via_filehandle: @@ -1607142,7 +1683440,75 @@ index 82d8383..1f09c76 100644 out: return rc; } -@@ -1635,7 +1635,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, +@@ -1557,57 +1557,24 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from) + + static int cifs_vmtruncate(struct inode *inode, loff_t offset) + { +- struct address_space *mapping = inode->i_mapping; +- unsigned long limit; ++ loff_t oldsize; ++ int err; + + spin_lock(&inode->i_lock); +- if (inode->i_size < offset) +- goto do_expand; +- /* +- * truncation of in-use swapfiles is disallowed - it would cause +- * subsequent swapout to scribble on the now-freed blocks. +- */ +- if (IS_SWAPFILE(inode)) { +- spin_unlock(&inode->i_lock); +- goto out_busy; +- } +- i_size_write(inode, offset); +- spin_unlock(&inode->i_lock); +- /* +- * unmap_mapping_range is called twice, first simply for efficiency +- * so that truncate_inode_pages does fewer single-page unmaps. However +- * after this first call, and before truncate_inode_pages finishes, +- * it is possible for private pages to be COWed, which remain after +- * truncate_inode_pages finishes, hence the second unmap_mapping_range +- * call must be made for correctness. +- */ +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- truncate_inode_pages(mapping, offset); +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- goto out_truncate; +- +-do_expand: +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && offset > limit) { ++ err = inode_newsize_ok(inode, offset); ++ if (err) { + spin_unlock(&inode->i_lock); +- goto out_sig; +- } +- if (offset > inode->i_sb->s_maxbytes) { +- spin_unlock(&inode->i_lock); +- goto out_big; ++ goto out; + } ++ ++ oldsize = inode->i_size; + i_size_write(inode, offset); + spin_unlock(&inode->i_lock); +-out_truncate: ++ truncate_pagecache(inode, oldsize, offset); + if (inode->i_op->truncate) + inode->i_op->truncate(inode); +- return 0; +-out_sig: +- send_sig(SIGXFSZ, current, 0); +-out_big: +- return -EFBIG; +-out_busy: +- return -ETXTBSY; ++out: ++ return err; + } + + static int +@@ -1635,7 +1602,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, __u32 npid = open_file->pid; rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, npid, false); @@ -1607151,7 +1683517,7 @@ index 82d8383..1f09c76 100644 cFYI(1, ("SetFSize for attrs rc = %d", rc)); if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { unsigned int bytes_written; -@@ -1790,7 +1790,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) +@@ -1790,7 +1757,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) u16 nfid = open_file->netfid; u32 npid = open_file->pid; rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); @@ -1607245,8 +1683611,20 @@ index 0ad3e2d..1da4ab2 100644 } static int +diff --git a/fs/coda/coda_int.h b/fs/coda/coda_int.h +index 8ccd5ed..d99860a 100644 +--- a/fs/coda/coda_int.h ++++ b/fs/coda/coda_int.h +@@ -2,6 +2,7 @@ + #define _CODA_INT_ + + struct dentry; ++struct file; + + extern struct file_system_type coda_fs_type; + extern unsigned long coda_timeout; diff --git a/fs/compat.c b/fs/compat.c -index 6d6f98f..932408f 100644 +index 6d6f98f..441ef91 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -100,13 +100,6 @@ asmlinkage long compat_sys_utimensat(unsigned int dfd, char __user *filename, st @@ -1607263,6 +1683641,71 @@ index 6d6f98f..932408f 100644 if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT) return 0; } +@@ -775,13 +768,13 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, + char __user * type, unsigned long flags, + void __user * data) + { +- unsigned long type_page; ++ char *kernel_type; + unsigned long data_page; +- unsigned long dev_page; ++ char *kernel_dev; + char *dir_page; + int retval; + +- retval = copy_mount_options (type, &type_page); ++ retval = copy_mount_string(type, &kernel_type); + if (retval < 0) + goto out; + +@@ -790,38 +783,38 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, + if (IS_ERR(dir_page)) + goto out1; + +- retval = copy_mount_options (dev_name, &dev_page); ++ retval = copy_mount_string(dev_name, &kernel_dev); + if (retval < 0) + goto out2; + +- retval = copy_mount_options (data, &data_page); ++ retval = copy_mount_options(data, &data_page); + if (retval < 0) + goto out3; + + retval = -EINVAL; + +- if (type_page && data_page) { +- if (!strcmp((char *)type_page, SMBFS_NAME)) { ++ if (kernel_type && data_page) { ++ if (!strcmp(kernel_type, SMBFS_NAME)) { + do_smb_super_data_conv((void *)data_page); +- } else if (!strcmp((char *)type_page, NCPFS_NAME)) { ++ } else if (!strcmp(kernel_type, NCPFS_NAME)) { + do_ncp_super_data_conv((void *)data_page); +- } else if (!strcmp((char *)type_page, NFS4_NAME)) { ++ } else if (!strcmp(kernel_type, NFS4_NAME)) { + if (do_nfs4_super_data_conv((void *) data_page)) + goto out4; + } + } + +- retval = do_mount((char*)dev_page, dir_page, (char*)type_page, ++ retval = do_mount(kernel_dev, dir_page, kernel_type, + flags, (void*)data_page); + + out4: + free_page(data_page); + out3: +- free_page(dev_page); ++ kfree(kernel_dev); + out2: + putname(dir_page); + out1: +- free_page(type_page); ++ kfree(kernel_type); + out: + return retval; + } @@ -1177,11 +1170,10 @@ out: if (iov != iovstack) kfree(iov); @@ -1607464,6 +1683907,22 @@ index ccc9d62..55ea369 100644 } static int user_cmd(struct sk_buff *skb, struct genl_info *info) +diff --git a/fs/drop_caches.c b/fs/drop_caches.c +index a2edb79..31f4b0e 100644 +--- a/fs/drop_caches.c ++++ b/fs/drop_caches.c +@@ -63,9 +63,9 @@ static void drop_slab(void) + } + + int drop_caches_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { +- proc_dointvec_minmax(table, write, file, buffer, length, ppos); ++ proc_dointvec_minmax(table, write, buffer, length, ppos); + if (write) { + if (sysctl_drop_caches & 1) + drop_pagecache(); diff --git a/fs/ecryptfs/Kconfig b/fs/ecryptfs/Kconfig index 0c754e6..8aadb99 100644 --- a/fs/ecryptfs/Kconfig @@ -1608076,7 +1684535,7 @@ index 31d12de..8b47e42 100644 SYSCALL_DEFINE1(eventfd, unsigned int, count) diff --git a/fs/exec.c b/fs/exec.c -index 172ceb6..ac602e5 100644 +index 172ceb6..3253f4a 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -33,7 +33,7 @@ @@ -1608088,7 +1684547,23 @@ index 172ceb6..ac602e5 100644 #include #include #include -@@ -128,7 +128,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -63,6 +64,7 @@ + + int core_uses_pid; + char core_pattern[CORENAME_MAX_SIZE] = "core"; ++unsigned int core_pipe_limit; + int suid_dumpable = 0; + + /* The maximal length of core_pattern is also specified in sysctl.c */ +@@ -128,7 +130,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) goto exit; @@ -1608097,7 +1684572,7 @@ index 172ceb6..ac602e5 100644 error = -ENOEXEC; if(file->f_op) { -@@ -663,7 +663,7 @@ struct file *open_exec(const char *name) +@@ -663,7 +665,7 @@ struct file *open_exec(const char *name) if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) goto exit; @@ -1608106,7 +1684581,7 @@ index 172ceb6..ac602e5 100644 err = deny_write_access(file); if (err) -@@ -845,6 +845,9 @@ static int de_thread(struct task_struct *tsk) +@@ -845,6 +847,9 @@ static int de_thread(struct task_struct *tsk) sig->notify_count = 0; no_thread_group: @@ -1608116,7 +1684591,7 @@ index 172ceb6..ac602e5 100644 exit_itimers(sig); flush_itimer_signals(); -@@ -923,7 +926,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) +@@ -923,7 +928,7 @@ void set_task_comm(struct task_struct *tsk, char *buf) task_lock(tsk); strlcpy(tsk->comm, buf, sizeof(tsk->comm)); task_unlock(tsk); @@ -1608125,7 +1684600,7 @@ index 172ceb6..ac602e5 100644 } int flush_old_exec(struct linux_binprm * bprm) -@@ -997,7 +1000,7 @@ int flush_old_exec(struct linux_binprm * bprm) +@@ -997,7 +1002,7 @@ int flush_old_exec(struct linux_binprm * bprm) * security domain: */ if (!get_dumpable(current->mm)) @@ -1608134,7 +1684609,7 @@ index 172ceb6..ac602e5 100644 /* An exec changes our domain. We are no longer part of the thread group */ -@@ -1354,6 +1357,8 @@ int do_execve(char * filename, +@@ -1354,6 +1359,8 @@ int do_execve(char * filename, if (retval < 0) goto out; @@ -1608143,6 +1684618,181 @@ index 172ceb6..ac602e5 100644 /* execve succeeded */ current->fs->in_exec = 0; current->in_execve = 0; +@@ -1388,18 +1395,16 @@ out_ret: + return retval; + } + +-int set_binfmt(struct linux_binfmt *new) ++void set_binfmt(struct linux_binfmt *new) + { +- struct linux_binfmt *old = current->binfmt; ++ struct mm_struct *mm = current->mm; + +- if (new) { +- if (!try_module_get(new->module)) +- return -1; +- } +- current->binfmt = new; +- if (old) +- module_put(old->module); +- return 0; ++ if (mm->binfmt) ++ module_put(mm->binfmt->module); ++ ++ mm->binfmt = new; ++ if (new) ++ __module_get(new->module); + } + + EXPORT_SYMBOL(set_binfmt); +@@ -1723,6 +1728,29 @@ int get_dumpable(struct mm_struct *mm) + return (ret >= 2) ? 2 : ret; + } + ++static void wait_for_dump_helpers(struct file *file) ++{ ++ struct pipe_inode_info *pipe; ++ ++ pipe = file->f_path.dentry->d_inode->i_pipe; ++ ++ pipe_lock(pipe); ++ pipe->readers++; ++ pipe->writers--; ++ ++ while ((pipe->readers > 1) && (!signal_pending(current))) { ++ wake_up_interruptible_sync(&pipe->wait); ++ kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); ++ pipe_wait(pipe); ++ } ++ ++ pipe->readers--; ++ pipe->writers++; ++ pipe_unlock(pipe); ++ ++} ++ ++ + void do_coredump(long signr, int exit_code, struct pt_regs *regs) + { + struct core_state core_state; +@@ -1739,11 +1767,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) + unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; + char **helper_argv = NULL; + int helper_argc = 0; +- char *delimit; ++ int dump_count = 0; ++ static atomic_t core_dump_count = ATOMIC_INIT(0); + + audit_core_dumps(signr); + +- binfmt = current->binfmt; ++ binfmt = mm->binfmt; + if (!binfmt || !binfmt->core_dump) + goto fail; + +@@ -1794,54 +1823,63 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) + lock_kernel(); + ispipe = format_corename(corename, signr); + unlock_kernel(); +- /* +- * Don't bother to check the RLIMIT_CORE value if core_pattern points +- * to a pipe. Since we're not writing directly to the filesystem +- * RLIMIT_CORE doesn't really apply, as no actual core file will be +- * created unless the pipe reader choses to write out the core file +- * at which point file size limits and permissions will be imposed +- * as it does with any other process +- */ ++ + if ((!ispipe) && (core_limit < binfmt->min_coredump)) + goto fail_unlock; + + if (ispipe) { ++ if (core_limit == 0) { ++ /* ++ * Normally core limits are irrelevant to pipes, since ++ * we're not writing to the file system, but we use ++ * core_limit of 0 here as a speacial value. Any ++ * non-zero limit gets set to RLIM_INFINITY below, but ++ * a limit of 0 skips the dump. This is a consistent ++ * way to catch recursive crashes. We can still crash ++ * if the core_pattern binary sets RLIM_CORE = !0 ++ * but it runs as root, and can do lots of stupid things ++ * Note that we use task_tgid_vnr here to grab the pid ++ * of the process group leader. That way we get the ++ * right pid if a thread in a multi-threaded ++ * core_pattern process dies. ++ */ ++ printk(KERN_WARNING ++ "Process %d(%s) has RLIMIT_CORE set to 0\n", ++ task_tgid_vnr(current), current->comm); ++ printk(KERN_WARNING "Aborting core\n"); ++ goto fail_unlock; ++ } ++ ++ dump_count = atomic_inc_return(&core_dump_count); ++ if (core_pipe_limit && (core_pipe_limit < dump_count)) { ++ printk(KERN_WARNING "Pid %d(%s) over core_pipe_limit\n", ++ task_tgid_vnr(current), current->comm); ++ printk(KERN_WARNING "Skipping core dump\n"); ++ goto fail_dropcount; ++ } ++ + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc); + if (!helper_argv) { + printk(KERN_WARNING "%s failed to allocate memory\n", + __func__); +- goto fail_unlock; +- } +- /* Terminate the string before the first option */ +- delimit = strchr(corename, ' '); +- if (delimit) +- *delimit = '\0'; +- delimit = strrchr(helper_argv[0], '/'); +- if (delimit) +- delimit++; +- else +- delimit = helper_argv[0]; +- if (!strcmp(delimit, current->comm)) { +- printk(KERN_NOTICE "Recursive core dump detected, " +- "aborting\n"); +- goto fail_unlock; ++ goto fail_dropcount; + } + + core_limit = RLIM_INFINITY; + + /* SIGPIPE can happen, but it's just never processed */ +- if (call_usermodehelper_pipe(corename+1, helper_argv, NULL, ++ if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, + &file)) { + printk(KERN_INFO "Core dump to %s pipe failed\n", + corename); +- goto fail_unlock; ++ goto fail_dropcount; + } + } else + file = filp_open(corename, + O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, + 0600); + if (IS_ERR(file)) +- goto fail_unlock; ++ goto fail_dropcount; + inode = file->f_path.dentry->d_inode; + if (inode->i_nlink > 1) + goto close_fail; /* multiple links - don't dump */ +@@ -1870,7 +1908,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) + if (retval) + current->signal->group_exit_code |= 0x80; + close_fail: ++ if (ispipe && core_pipe_limit) ++ wait_for_dump_helpers(file); + filp_close(file, NULL); ++fail_dropcount: ++ if (dump_count) ++ atomic_dec(&core_dump_count); + fail_unlock: + if (helper_argv) + argv_free(helper_argv); diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 6c10f74..cd034e6 100644 --- a/fs/exofs/inode.c @@ -1612042,7 +1688692,7 @@ index f042b96..e8c159d 100644 return err; } diff --git a/fs/fat/inode.c b/fs/fat/inode.c -index 8970d8c..a8a3afe 100644 +index 8970d8c..76b7961 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -451,12 +451,16 @@ static void fat_write_super(struct super_block *sb) @@ -1612067,7 +1688717,31 @@ index 8970d8c..a8a3afe 100644 } static void fat_put_super(struct super_block *sb) -@@ -820,7 +824,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) +@@ -470,19 +474,11 @@ static void fat_put_super(struct super_block *sb) + + iput(sbi->fat_inode); + +- if (sbi->nls_disk) { +- unload_nls(sbi->nls_disk); +- sbi->nls_disk = NULL; +- sbi->options.codepage = fat_default_codepage; +- } +- if (sbi->nls_io) { +- unload_nls(sbi->nls_io); +- sbi->nls_io = NULL; +- } +- if (sbi->options.iocharset != fat_default_iocharset) { ++ unload_nls(sbi->nls_disk); ++ unload_nls(sbi->nls_io); ++ ++ if (sbi->options.iocharset != fat_default_iocharset) + kfree(sbi->options.iocharset); +- sbi->options.iocharset = fat_default_iocharset; +- } + + sb->s_fs_info = NULL; + kfree(sbi); +@@ -820,7 +816,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt) seq_puts(m, ",shortname=mixed"); break; case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95: @@ -1612076,7 +1688750,7 @@ index 8970d8c..a8a3afe 100644 break; default: seq_puts(m, ",shortname=unknown"); -@@ -971,7 +975,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, +@@ -971,7 +967,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, opts->codepage = fat_default_codepage; opts->iocharset = fat_default_iocharset; if (is_vfat) { @@ -1612158,8 +1688832,216 @@ index cb6e835..f565f24 100644 return -ENAMETOOLONG; op = &outname[*outlen * sizeof(wchar_t)]; +diff --git a/fs/fcntl.c b/fs/fcntl.c +index ae41308..fc089f2 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -263,6 +263,79 @@ pid_t f_getown(struct file *filp) + return pid; + } + ++static int f_setown_ex(struct file *filp, unsigned long arg) ++{ ++ struct f_owner_ex * __user owner_p = (void * __user)arg; ++ struct f_owner_ex owner; ++ struct pid *pid; ++ int type; ++ int ret; ++ ++ ret = copy_from_user(&owner, owner_p, sizeof(owner)); ++ if (ret) ++ return ret; ++ ++ switch (owner.type) { ++ case F_OWNER_TID: ++ type = PIDTYPE_MAX; ++ break; ++ ++ case F_OWNER_PID: ++ type = PIDTYPE_PID; ++ break; ++ ++ case F_OWNER_GID: ++ type = PIDTYPE_PGID; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ rcu_read_lock(); ++ pid = find_vpid(owner.pid); ++ if (owner.pid && !pid) ++ ret = -ESRCH; ++ else ++ ret = __f_setown(filp, pid, type, 1); ++ rcu_read_unlock(); ++ ++ return ret; ++} ++ ++static int f_getown_ex(struct file *filp, unsigned long arg) ++{ ++ struct f_owner_ex * __user owner_p = (void * __user)arg; ++ struct f_owner_ex owner; ++ int ret = 0; ++ ++ read_lock(&filp->f_owner.lock); ++ owner.pid = pid_vnr(filp->f_owner.pid); ++ switch (filp->f_owner.pid_type) { ++ case PIDTYPE_MAX: ++ owner.type = F_OWNER_TID; ++ break; ++ ++ case PIDTYPE_PID: ++ owner.type = F_OWNER_PID; ++ break; ++ ++ case PIDTYPE_PGID: ++ owner.type = F_OWNER_GID; ++ break; ++ ++ default: ++ WARN_ON(1); ++ ret = -EINVAL; ++ break; ++ } ++ read_unlock(&filp->f_owner.lock); ++ ++ if (!ret) ++ ret = copy_to_user(owner_p, &owner, sizeof(owner)); ++ return ret; ++} ++ + static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, + struct file *filp) + { +@@ -313,6 +386,12 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, + case F_SETOWN: + err = f_setown(filp, arg, 1); + break; ++ case F_GETOWN_EX: ++ err = f_getown_ex(filp, arg); ++ break; ++ case F_SETOWN_EX: ++ err = f_setown_ex(filp, arg); ++ break; + case F_GETSIG: + err = filp->f_owner.signum; + break; +@@ -428,8 +507,7 @@ static inline int sigio_perm(struct task_struct *p, + + static void send_sigio_to_task(struct task_struct *p, + struct fown_struct *fown, +- int fd, +- int reason) ++ int fd, int reason, int group) + { + /* + * F_SETSIG can change ->signum lockless in parallel, make +@@ -461,11 +539,11 @@ static void send_sigio_to_task(struct task_struct *p, + else + si.si_band = band_table[reason - POLL_IN]; + si.si_fd = fd; +- if (!group_send_sig_info(signum, &si, p)) ++ if (!do_send_sig_info(signum, &si, p, group)) + break; + /* fall-through: fall back on the old plain SIGIO signal */ + case 0: +- group_send_sig_info(SIGIO, SEND_SIG_PRIV, p); ++ do_send_sig_info(SIGIO, SEND_SIG_PRIV, p, group); + } + } + +@@ -474,16 +552,23 @@ void send_sigio(struct fown_struct *fown, int fd, int band) + struct task_struct *p; + enum pid_type type; + struct pid *pid; ++ int group = 1; + + read_lock(&fown->lock); ++ + type = fown->pid_type; ++ if (type == PIDTYPE_MAX) { ++ group = 0; ++ type = PIDTYPE_PID; ++ } ++ + pid = fown->pid; + if (!pid) + goto out_unlock_fown; + + read_lock(&tasklist_lock); + do_each_pid_task(pid, type, p) { +- send_sigio_to_task(p, fown, fd, band); ++ send_sigio_to_task(p, fown, fd, band, group); + } while_each_pid_task(pid, type, p); + read_unlock(&tasklist_lock); + out_unlock_fown: +@@ -491,10 +576,10 @@ void send_sigio(struct fown_struct *fown, int fd, int band) + } + + static void send_sigurg_to_task(struct task_struct *p, +- struct fown_struct *fown) ++ struct fown_struct *fown, int group) + { + if (sigio_perm(p, fown, SIGURG)) +- group_send_sig_info(SIGURG, SEND_SIG_PRIV, p); ++ do_send_sig_info(SIGURG, SEND_SIG_PRIV, p, group); + } + + int send_sigurg(struct fown_struct *fown) +@@ -502,10 +587,17 @@ int send_sigurg(struct fown_struct *fown) + struct task_struct *p; + enum pid_type type; + struct pid *pid; ++ int group = 1; + int ret = 0; + + read_lock(&fown->lock); ++ + type = fown->pid_type; ++ if (type == PIDTYPE_MAX) { ++ group = 0; ++ type = PIDTYPE_PID; ++ } ++ + pid = fown->pid; + if (!pid) + goto out_unlock_fown; +@@ -514,7 +606,7 @@ int send_sigurg(struct fown_struct *fown) + + read_lock(&tasklist_lock); + do_each_pid_task(pid, type, p) { +- send_sigurg_to_task(p, fown); ++ send_sigurg_to_task(p, fown, group); + } while_each_pid_task(pid, type, p); + read_unlock(&tasklist_lock); + out_unlock_fown: +diff --git a/fs/file_table.c b/fs/file_table.c +index 334ce39..8eb4404 100644 +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -74,14 +74,14 @@ EXPORT_SYMBOL_GPL(get_max_files); + * Handle nr_files sysctl + */ + #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) +-int proc_nr_files(ctl_table *table, int write, struct file *filp, ++int proc_nr_files(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + files_stat.nr_files = get_nr_files(); +- return proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ return proc_dointvec(table, write, buffer, lenp, ppos); + } + #else +-int proc_nr_files(ctl_table *table, int write, struct file *filp, ++int proc_nr_files(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c -index c54226b..15076ee 100644 +index c54226b..c6bf775 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -19,171 +19,255 @@ @@ -1612589,7 +1689471,48 @@ index c54226b..15076ee 100644 */ ret = ret && time_before_eq(inode->dirtied_when, jiffies); #endif -@@ -262,20 +347,18 @@ static void move_expired_inodes(struct list_head *delaying_queue, +@@ -249,33 +334,56 @@ static void move_expired_inodes(struct list_head *delaying_queue, + struct list_head *dispatch_queue, + unsigned long *older_than_this) + { ++ LIST_HEAD(tmp); ++ struct list_head *pos, *node; ++ struct super_block *sb = NULL; ++ struct inode *inode; ++ int do_sb_sort = 0; ++ + while (!list_empty(delaying_queue)) { +- struct inode *inode = list_entry(delaying_queue->prev, +- struct inode, i_list); ++ inode = list_entry(delaying_queue->prev, struct inode, i_list); + if (older_than_this && + inode_dirtied_after(inode, *older_than_this)) + break; +- list_move(&inode->i_list, dispatch_queue); ++ if (sb && sb != inode->i_sb) ++ do_sb_sort = 1; ++ sb = inode->i_sb; ++ list_move(&inode->i_list, &tmp); ++ } ++ ++ /* just one sb in list, splice to dispatch_queue and we're done */ ++ if (!do_sb_sort) { ++ list_splice(&tmp, dispatch_queue); ++ return; ++ } ++ ++ /* Move inodes from one superblock together */ ++ while (!list_empty(&tmp)) { ++ inode = list_entry(tmp.prev, struct inode, i_list); ++ sb = inode->i_sb; ++ list_for_each_prev_safe(pos, node, &tmp) { ++ inode = list_entry(pos, struct inode, i_list); ++ if (inode->i_sb == sb) ++ list_move(&inode->i_list, dispatch_queue); ++ } + } + } + /* * Queue all expired dirty inodes for io, eldest first. */ @@ -1612617,15 +1689540,7 @@ index c54226b..15076ee 100644 /* * Wait for writeback on an inode to complete. -@@ -311,6 +394,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) - { - struct address_space *mapping = inode->i_mapping; - int wait = wbc->sync_mode == WB_SYNC_ALL; -+ pgoff_t start_index; - unsigned dirty; - int ret; - -@@ -322,11 +406,11 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) +@@ -322,11 +430,11 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) if (inode->i_state & I_SYNC) { /* * If this inode is locked for writeback and we are not doing @@ -1612639,29 +1689554,16 @@ index c54226b..15076ee 100644 */ if (!wait) { requeue_io(inode); -@@ -348,6 +432,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) - - spin_unlock(&inode_lock); - -+ start_index = mapping->writeback_index; - ret = do_writepages(mapping, wbc); - - /* Don't write the inode if only I_DIRTY_PAGES was set */ -@@ -366,16 +451,26 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) +@@ -366,16 +474,21 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) spin_lock(&inode_lock); inode->i_state &= ~I_SYNC; if (!(inode->i_state & (I_FREEING | I_CLEAR))) { - if (!(inode->i_state & I_DIRTY) && - mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { -+ if (inode->i_state & I_DIRTY_PAGES) { ++ if (inode->i_state & I_DIRTY) { + /* -+ * More pages get dirtied by a fast dirtier. -+ */ -+ goto select_queue; -+ } else if (inode->i_state & I_DIRTY) { -+ /* -+ * At least XFS will redirty the inode during the -+ * writeback (delalloc) and on io completion (isize). ++ * Someone redirtied the inode while were writing back ++ * the pages. + */ + redirty_tail(inode); + } else if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) { @@ -1612678,7 +1689580,7 @@ index c54226b..15076ee 100644 * consideration. Otherwise, move it to the tail, for * the reasons described there. I'm not really sure * how much sense this makes. Presumably I had a good -@@ -385,11 +480,13 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) +@@ -385,7 +498,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) if (wbc->for_kupdate) { /* * For the kupdate function we move the inode @@ -1612687,14 +1689589,7 @@ index c54226b..15076ee 100644 * soon as the queue becomes uncongested. */ inode->i_state |= I_DIRTY_PAGES; -- if (wbc->nr_to_write <= 0) { -+select_queue: -+ if (wbc->nr_to_write <= 0 && -+ start_index < mapping->writeback_index) { - /* - * slice used up: queue for next turn - */ -@@ -411,12 +508,6 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) +@@ -411,12 +524,6 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) inode->i_state |= I_DIRTY_PAGES; redirty_tail(inode); } @@ -1612707,19 +1689602,28 @@ index c54226b..15076ee 100644 } else if (atomic_read(&inode->i_count)) { /* * The inode is clean, inuse -@@ -434,50 +525,84 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) +@@ -433,51 +540,96 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc) + return ret; } ++static void unpin_sb_for_writeback(struct super_block **psb) ++{ ++ struct super_block *sb = *psb; ++ ++ if (sb) { ++ up_read(&sb->s_umount); ++ put_super(sb); ++ *psb = NULL; ++ } ++} ++ /* - * Write out a superblock's list of dirty inodes. A wait will be performed - * upon no inodes, all inodes or the final one, depending upon sync_mode. - * - * If older_than_this is non-NULL, then only write out inodes which - * had their first dirtying at a time earlier than *older_than_this. -+ * For WB_SYNC_NONE writeback, the caller does not have the sb pinned -+ * before calling writeback. So make sure that we do pin it, so it doesn't -+ * go away while we are writing inodes from it. - * +- * - * If we're a pdflush thread, then implement pdflush collision avoidance - * against the entire list. - * @@ -1612727,7 +1689631,10 @@ index c54226b..15076ee 100644 - * This function assumes that the blockdev superblock's inodes are backed by - * a variety of queues, so all inodes are searched. For other superblocks, - * assume that all inodes are backed by the same queue. -- * ++ * For WB_SYNC_NONE writeback, the caller does not have the sb pinned ++ * before calling writeback. So make sure that we do pin it, so it doesn't ++ * go away while we are writing inodes from it. + * - * FIXME: this linear search could get expensive with many fileystems. But - * how to fix? We need to go from an address_space to all inodes which share - * a queue with that address_space. (Easy: have a global "dirty superblocks" @@ -1612742,11 +1689649,20 @@ index c54226b..15076ee 100644 */ -void generic_sync_sb_inodes(struct super_block *sb, +static int pin_sb_for_writeback(struct writeback_control *wbc, -+ struct inode *inode) ++ struct inode *inode, struct super_block **psb) +{ + struct super_block *sb = inode->i_sb; + + /* ++ * If this sb is already pinned, nothing more to do. If not and ++ * *psb is non-NULL, unpin the old one first ++ */ ++ if (sb == *psb) ++ return 0; ++ else if (*psb) ++ unpin_sb_for_writeback(psb); ++ ++ /* + * Caller must already hold the ref for this + */ + if (wbc->sync_mode == WB_SYNC_ALL) { @@ -1612759,7 +1689675,7 @@ index c54226b..15076ee 100644 + if (down_read_trylock(&sb->s_umount)) { + if (sb->s_root) { + spin_unlock(&sb_lock); -+ return 0; ++ goto pinned; + } + /* + * umounted, drop rwsem again and fall through to failure @@ -1612770,24 +1689686,15 @@ index c54226b..15076ee 100644 + sb->s_count--; + spin_unlock(&sb_lock); + return 1; -+} -+ -+static void unpin_sb_for_writeback(struct writeback_control *wbc, -+ struct inode *inode) -+{ -+ struct super_block *sb = inode->i_sb; -+ -+ if (wbc->sync_mode == WB_SYNC_ALL) -+ return; -+ -+ up_read(&sb->s_umount); -+ put_super(sb); ++pinned: ++ *psb = sb; ++ return 0; +} + +static void writeback_inodes_wb(struct bdi_writeback *wb, struct writeback_control *wbc) { -+ struct super_block *sb = wbc->sb; ++ struct super_block *sb = wbc->sb, *pin_sb = NULL; + const int is_blkdev_sb = sb_is_blkdev_sb(sb); const unsigned long start = jiffies; /* livelock avoidance */ - int sync = wbc->sync_mode == WB_SYNC_ALL; @@ -1612824,7 +1689731,7 @@ index c54226b..15076ee 100644 /* * Dirty memory-backed blockdev: the ramdisk * driver does this. Skip just this inode -@@ -497,21 +622,14 @@ void generic_sync_sb_inodes(struct super_block *sb, +@@ -497,21 +649,14 @@ void generic_sync_sb_inodes(struct super_block *sb, continue; } @@ -1612848,14 +1689755,14 @@ index c54226b..15076ee 100644 /* * Was this inode dirtied after sync_sb_inodes was called? * This keeps sync from extra jobs and livelock. -@@ -519,16 +637,16 @@ void generic_sync_sb_inodes(struct super_block *sb, +@@ -519,16 +664,15 @@ void generic_sync_sb_inodes(struct super_block *sb, if (inode_dirtied_after(inode, start)) break; - /* Is another pdflush already flushing this queue? */ - if (current_is_pdflush() && !writeback_acquire(bdi)) - break; -+ if (pin_sb_for_writeback(wbc, inode)) { ++ if (pin_sb_for_writeback(wbc, inode, &pin_sb)) { + requeue_io(inode); + continue; + } @@ -1612866,11 +1689773,10 @@ index c54226b..15076ee 100644 writeback_single_inode(inode, wbc); - if (current_is_pdflush()) - writeback_release(bdi); -+ unpin_sb_for_writeback(wbc, inode); if (wbc->pages_skipped != pages_skipped) { /* * writeback is not making progress due to locked -@@ -544,144 +662,533 @@ void generic_sync_sb_inodes(struct super_block *sb, +@@ -544,144 +688,535 @@ void generic_sync_sb_inodes(struct super_block *sb, wbc->more_io = 1; break; } @@ -1612881,6 +1689787,8 @@ index c54226b..15076ee 100644 - if (sync) { - struct inode *inode, *old_inode = NULL; ++ unpin_sb_for_writeback(&pin_sb); + + spin_unlock(&inode_lock); + /* Leave any unwritten inodes on b_io */ +} @@ -1612888,7 +1689796,7 @@ index c54226b..15076ee 100644 +void writeback_inodes_wbc(struct writeback_control *wbc) +{ + struct backing_dev_info *bdi = wbc->bdi; - ++ + writeback_inodes_wb(&bdi->wb, wbc); +} + @@ -1613244,6 +1690152,13 @@ index c54226b..15076ee 100644 + * @flags: what kind of dirty (i.e. I_DIRTY_SYNC) + * Mark an inode as dirty. Callers should use mark_inode_dirty or + * mark_inode_dirty_sync. ++ * ++ * Put the inode on the super block's dirty list. ++ * ++ * CAREFUL! We mark it dirty unconditionally, but move it onto the ++ * dirty list only if it is hashed or if it refers to a blockdev. ++ * If it was not hashed, it will never be added to the dirty list ++ * even if it is later hashed, as it will have been marked dirty already. * - * Note: - * We don't need to grab a reference to superblock here. If it has non-empty @@ -1613251,18 +1690166,11 @@ index c54226b..15076ee 100644 - * past sync_inodes_sb() until the ->s_dirty/s_io/s_more_io lists are all - * empty. Since __sync_single_inode() regains inode_lock before it finally moves - * inode from superblock lists we are OK. -+ * Put the inode on the super block's dirty list. ++ * In short, make sure you hash any inodes _before_ you start marking ++ * them dirty. * - * If `older_than_this' is non-zero then only flush inodes which have a - * flushtime older than *older_than_this. -+ * CAREFUL! We mark it dirty unconditionally, but move it onto the -+ * dirty list only if it is hashed or if it refers to a blockdev. -+ * If it was not hashed, it will never be added to the dirty list -+ * even if it is later hashed, as it will have been marked dirty already. -+ * -+ * In short, make sure you hash any inodes _before_ you start marking -+ * them dirty. -+ * + * This function *must* be atomic for the I_DIRTY_PAGES case - + * set_page_dirty() is called under spinlock in several places. * @@ -1613384,19 +1690292,19 @@ index c54226b..15076ee 100644 - * do this in two passes - one to write, and one to wait. + * Write out a superblock's list of dirty inodes. A wait will be performed + * upon no inodes, all inodes or the final one, depending upon sync_mode. - * -- * A finite limit is set on the number of pages which will be written. -- * To prevent infinite livelock of sys_sync(). ++ * + * If older_than_this is non-NULL, then only write out inodes which + * had their first dirtying at a time earlier than *older_than_this. * -- * We add in the number of potentially dirty inodes, because each inode write -- * can dirty pagecache in the underlying blockdev. +- * A finite limit is set on the number of pages which will be written. +- * To prevent infinite livelock of sys_sync(). + * If `bdi' is non-zero then we're being asked to writeback a specific queue. + * This function assumes that the blockdev superblock's inodes are backed by + * a variety of queues, so all inodes are searched. For other superblocks, + * assume that all inodes are backed by the same queue. -+ * + * +- * We add in the number of potentially dirty inodes, because each inode write +- * can dirty pagecache in the underlying blockdev. + * The inodes to be written are parked on bdi->b_io. They are moved back onto + * bdi->b_dirty as they are selected for writing. This way, none can be missed + * on the writer throttling path, and we get decent balancing between many @@ -1613417,13 +1690325,12 @@ index c54226b..15076ee 100644 + * r/o to r/w or vice versa. + */ + WARN_ON(!rwsem_is_locked(&sb->s_umount)); ++ ++ spin_lock(&inode_lock); - if (!wait) { - unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); - unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); -+ spin_lock(&inode_lock); - -- wbc.nr_to_write = nr_dirty + nr_unstable + + /* + * Data integrity sync. Must wait for all pages under writeback, + * because there may have been pages dirtied before our sync @@ -1613433,7 +1690340,8 @@ index c54226b..15076ee 100644 + */ + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + struct address_space *mapping; -+ + +- wbc.nr_to_write = nr_dirty + nr_unstable + + if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) + continue; + mapping = inode->i_mapping; @@ -1613484,7 +1690392,7 @@ index c54226b..15076ee 100644 - sync_sb_inodes(sb, &wbc); + bdi_writeback_all(sb, nr_to_write); -+} + } +EXPORT_SYMBOL(writeback_inodes_sb); + +/** @@ -1613498,12 +1690406,12 @@ index c54226b..15076ee 100644 +{ + bdi_sync_writeback(sb->s_bdi, sb); + wait_sb_inodes(sb); - } ++} +EXPORT_SYMBOL(sync_inodes_sb); /** * write_inode_now - write an inode to disk -@@ -737,57 +1244,3 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc) +@@ -737,57 +1272,3 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc) return ret; } EXPORT_SYMBOL(sync_inode); @@ -1613771,8 +1690679,40 @@ index 6484eb7..51d9e33 100644 fc->bdi_initialized) { set_bdi_congested(&fc->bdi, BLK_RW_SYNC); set_bdi_congested(&fc->bdi, BLK_RW_ASYNC); +diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c +index e703654..992f6c9 100644 +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -1276,14 +1276,9 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + return 0; + + if (attr->ia_valid & ATTR_SIZE) { +- unsigned long limit; +- if (IS_SWAPFILE(inode)) +- return -ETXTBSY; +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { +- send_sig(SIGXFSZ, current, 0); +- return -EFBIG; +- } ++ err = inode_newsize_ok(inode, attr->ia_size); ++ if (err) ++ return err; + is_truncate = true; + } + +@@ -1350,8 +1345,7 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock. + */ + if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) { +- if (outarg.attr.size < oldsize) +- fuse_truncate(inode->i_mapping, outarg.attr.size); ++ truncate_pagecache(inode, oldsize, outarg.attr.size); + invalidate_inode_pages2(inode->i_mapping); + } + diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h -index 52b641f..fc9c79f 100644 +index 52b641f..01cc462 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -25,12 +25,6 @@ @@ -1613821,8 +1690761,17 @@ index 52b641f..fc9c79f 100644 /** Number of requests currently in the background */ unsigned num_background; +@@ -602,8 +606,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, + void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, + u64 attr_valid); + +-void fuse_truncate(struct address_space *mapping, loff_t offset); +- + /** + * Initialize the client device + */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c -index f91ccc4..6da947d 100644 +index f91ccc4..1a822ce 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -14,6 +14,7 @@ @@ -1613868,7 +1690817,32 @@ index f91ccc4..6da947d 100644 struct fuse_mount_data { int fd; unsigned rootmode; -@@ -517,6 +542,8 @@ void fuse_conn_init(struct fuse_conn *fc) +@@ -115,14 +140,6 @@ static int fuse_remount_fs(struct super_block *sb, int *flags, char *data) + return 0; + } + +-void fuse_truncate(struct address_space *mapping, loff_t offset) +-{ +- /* See vmtruncate() */ +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- truncate_inode_pages(mapping, offset); +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +-} +- + void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, + u64 attr_valid) + { +@@ -180,8 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, + spin_unlock(&fc->lock); + + if (S_ISREG(inode->i_mode) && oldsize != attr->size) { +- if (attr->size < oldsize) +- fuse_truncate(inode->i_mapping, attr->size); ++ truncate_pagecache(inode, oldsize, attr->size); + invalidate_inode_pages2(inode->i_mapping); + } + } +@@ -517,6 +533,8 @@ void fuse_conn_init(struct fuse_conn *fc) INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->entry); atomic_set(&fc->num_waiting, 0); @@ -1613877,7 +1690851,7 @@ index f91ccc4..6da947d 100644 fc->khctr = 0; fc->polled_files = RB_ROOT; fc->reqctr = 0; -@@ -727,6 +754,54 @@ static const struct super_operations fuse_super_operations = { +@@ -727,6 +745,54 @@ static const struct super_operations fuse_super_operations = { .show_options = fuse_show_options, }; @@ -1613932,7 +1690906,7 @@ index f91ccc4..6da947d 100644 static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) { struct fuse_init_out *arg = &req->misc.init_out; -@@ -736,6 +811,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) +@@ -736,6 +802,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) else { unsigned long ra_pages; @@ -1613941,7 +1690915,7 @@ index f91ccc4..6da947d 100644 if (arg->minor >= 6) { ra_pages = arg->max_readahead / PAGE_CACHE_SIZE; if (arg->flags & FUSE_ASYNC_READ) -@@ -801,6 +878,7 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) +@@ -801,6 +869,7 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb) { int err; @@ -1613949,7 +1690923,7 @@ index f91ccc4..6da947d 100644 fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; fc->bdi.unplug_io_fn = default_unplug_io_fn; /* fuse does it's own writeback accounting */ -@@ -893,6 +971,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) +@@ -893,6 +962,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) if (err) goto err_put_conn; @@ -1613958,7 +1690932,7 @@ index f91ccc4..6da947d 100644 /* Handle umasking inside the fuse code */ if (sb->s_flags & MS_POSIXACL) fc->dont_mask = 1; -@@ -1147,6 +1227,9 @@ static int __init fuse_init(void) +@@ -1147,6 +1218,9 @@ static int __init fuse_init(void) if (res) goto err_sysfs_cleanup; @@ -1616661,10 +1693635,18 @@ index 7bc3c45..fdd32ef 100644 fail_threads: diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c -index f8bd20b..c3ac180 100644 +index f8bd20b..247436c 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c -@@ -26,8 +26,7 @@ +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -26,8 +25,7 @@ #include "acl.h" #include "bmap.h" #include "dir.h" @@ -1616674,7 +1693656,7 @@ index f8bd20b..c3ac180 100644 #include "glock.h" #include "inode.h" #include "meta_io.h" -@@ -349,7 +348,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) +@@ -349,7 +347,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); if (error) @@ -1616683,7 +1693665,7 @@ index f8bd20b..c3ac180 100644 error = gfs2_dir_del(dip, &dentry->d_name); if (error) -@@ -1302,60 +1301,53 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, +@@ -1302,60 +1300,53 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, const void *data, size_t size, int flags) { struct inode *inode = dentry->d_inode; @@ -1619005,8 +1695987,49 @@ index 0000000..cbdfd77 + struct iattr *attr, char *data); + +#endif /* __EATTR_DOT_H__ */ +diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c +index 7b6165f..8bbe03c 100644 +--- a/fs/hfs/mdb.c ++++ b/fs/hfs/mdb.c +@@ -344,10 +344,8 @@ void hfs_mdb_put(struct super_block *sb) + brelse(HFS_SB(sb)->mdb_bh); + brelse(HFS_SB(sb)->alt_mdb_bh); + +- if (HFS_SB(sb)->nls_io) +- unload_nls(HFS_SB(sb)->nls_io); +- if (HFS_SB(sb)->nls_disk) +- unload_nls(HFS_SB(sb)->nls_disk); ++ unload_nls(HFS_SB(sb)->nls_io); ++ unload_nls(HFS_SB(sb)->nls_disk); + + free_pages((unsigned long)HFS_SB(sb)->bitmap, PAGE_SIZE < 8192 ? 1 : 0); + kfree(HFS_SB(sb)); +diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c +index c0759fe..43022f3 100644 +--- a/fs/hfsplus/super.c ++++ b/fs/hfsplus/super.c +@@ -229,8 +229,7 @@ static void hfsplus_put_super(struct super_block *sb) + iput(HFSPLUS_SB(sb).alloc_file); + iput(HFSPLUS_SB(sb).hidden_dir); + brelse(HFSPLUS_SB(sb).s_vhbh); +- if (HFSPLUS_SB(sb).nls) +- unload_nls(HFSPLUS_SB(sb).nls); ++ unload_nls(HFSPLUS_SB(sb).nls); + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + +@@ -464,8 +463,7 @@ out: + + cleanup: + hfsplus_put_super(sb); +- if (nls) +- unload_nls(nls); ++ unload_nls(nls); + return err; + } + diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c -index cb88dac..eba6d55 100644 +index cb88dac..87a1258 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -31,12 +31,10 @@ @@ -1619031,7 +1696054,48 @@ index cb88dac..eba6d55 100644 .ra_pages = 0, /* No readahead */ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, }; -@@ -506,6 +505,13 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, +@@ -381,36 +380,11 @@ static void hugetlbfs_delete_inode(struct inode *inode) + + static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) + { +- struct super_block *sb = inode->i_sb; +- +- if (!hlist_unhashed(&inode->i_hash)) { +- if (!(inode->i_state & (I_DIRTY|I_SYNC))) +- list_move(&inode->i_list, &inode_unused); +- inodes_stat.nr_unused++; +- if (!sb || (sb->s_flags & MS_ACTIVE)) { +- spin_unlock(&inode_lock); +- return; +- } +- inode->i_state |= I_WILL_FREE; +- spin_unlock(&inode_lock); +- /* +- * write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK +- * in our backing_dev_info. +- */ +- write_inode_now(inode, 1); +- spin_lock(&inode_lock); +- inode->i_state &= ~I_WILL_FREE; +- inodes_stat.nr_unused--; +- hlist_del_init(&inode->i_hash); ++ if (generic_detach_inode(inode)) { ++ truncate_hugepages(inode, 0); ++ clear_inode(inode); ++ destroy_inode(inode); + } +- list_del_init(&inode->i_list); +- list_del_init(&inode->i_sb_list); +- inode->i_state |= I_FREEING; +- inodes_stat.nr_inodes--; +- spin_unlock(&inode_lock); +- truncate_hugepages(inode, 0); +- clear_inode(inode); +- destroy_inode(inode); + } + + static void hugetlbfs_drop_inode(struct inode *inode) +@@ -506,6 +480,13 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid, inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; INIT_LIST_HEAD(&inode->i_mapping->private_list); info = HUGETLBFS_I(inode); @@ -1619045,21 +1696109,7 @@ index cb88dac..eba6d55 100644 mpol_shared_policy_init(&info->policy, NULL); switch (mode & S_IFMT) { default: -@@ -930,13 +936,19 @@ static struct file_system_type hugetlbfs_fs_type = { - - static struct vfsmount *hugetlbfs_vfsmount; - --static int can_do_hugetlb_shm(void) -+static int can_do_hugetlb_shm(int creat_flags) - { -- return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group); -+ if (creat_flags != HUGETLB_SHMFS_INODE) -+ return 0; -+ if (capable(CAP_IPC_LOCK)) -+ return 1; -+ if (in_group_p(sysctl_hugetlb_shm_group)) -+ return 1; -+ return 0; +@@ -936,7 +917,7 @@ static int can_do_hugetlb_shm(void) } struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, @@ -1619068,17 +1696118,17 @@ index cb88dac..eba6d55 100644 { int error = -ENOMEM; struct file *file; -@@ -948,7 +960,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, +@@ -948,7 +929,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag, if (!hugetlbfs_vfsmount) return ERR_PTR(-ENOENT); - if (!can_do_hugetlb_shm()) { -+ if (!can_do_hugetlb_shm(creat_flags)) { ++ if (creat_flags == HUGETLB_SHMFS_INODE && !can_do_hugetlb_shm()) { *user = current_user(); if (user_shm_lock(size, *user)) { WARN_ONCE(1, diff --git a/fs/inode.c b/fs/inode.c -index ae7b67e..76582b0 100644 +index ae7b67e..4d8e3be 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -14,6 +14,7 @@ @@ -1619197,6 +1696247,227 @@ index ae7b67e..76582b0 100644 WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); inode->i_state &= ~(I_LOCK|I_NEW); wake_up_inode(inode); +@@ -1236,7 +1241,16 @@ void generic_delete_inode(struct inode *inode) + } + EXPORT_SYMBOL(generic_delete_inode); + +-static void generic_forget_inode(struct inode *inode) ++/** ++ * generic_detach_inode - remove inode from inode lists ++ * @inode: inode to remove ++ * ++ * Remove inode from inode lists, write it if it's dirty. This is just an ++ * internal VFS helper exported for hugetlbfs. Do not use! ++ * ++ * Returns 1 if inode should be completely destroyed. ++ */ ++int generic_detach_inode(struct inode *inode) + { + struct super_block *sb = inode->i_sb; + +@@ -1246,7 +1260,7 @@ static void generic_forget_inode(struct inode *inode) + inodes_stat.nr_unused++; + if (sb->s_flags & MS_ACTIVE) { + spin_unlock(&inode_lock); +- return; ++ return 0; + } + WARN_ON(inode->i_state & I_NEW); + inode->i_state |= I_WILL_FREE; +@@ -1264,6 +1278,14 @@ static void generic_forget_inode(struct inode *inode) + inode->i_state |= I_FREEING; + inodes_stat.nr_inodes--; + spin_unlock(&inode_lock); ++ return 1; ++} ++EXPORT_SYMBOL_GPL(generic_detach_inode); ++ ++static void generic_forget_inode(struct inode *inode) ++{ ++ if (!generic_detach_inode(inode)) ++ return; + if (inode->i_data.nrpages) + truncate_inode_pages(&inode->i_data, 0); + clear_inode(inode); +@@ -1394,31 +1416,31 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry) + struct inode *inode = dentry->d_inode; + struct timespec now; + +- if (mnt_want_write(mnt)) +- return; + if (inode->i_flags & S_NOATIME) +- goto out; ++ return; + if (IS_NOATIME(inode)) +- goto out; ++ return; + if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) +- goto out; ++ return; + + if (mnt->mnt_flags & MNT_NOATIME) +- goto out; ++ return; + if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) +- goto out; ++ return; + + now = current_fs_time(inode->i_sb); + + if (!relatime_need_update(mnt, inode, now)) +- goto out; ++ return; + + if (timespec_equal(&inode->i_atime, &now)) +- goto out; ++ return; ++ ++ if (mnt_want_write(mnt)) ++ return; + + inode->i_atime = now; + mark_inode_dirty_sync(inode); +-out: + mnt_drop_write(mnt); + } + EXPORT_SYMBOL(touch_atime); +@@ -1439,34 +1461,37 @@ void file_update_time(struct file *file) + { + struct inode *inode = file->f_path.dentry->d_inode; + struct timespec now; +- int sync_it = 0; +- int err; ++ enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0; + ++ /* First try to exhaust all avenues to not sync */ + if (IS_NOCMTIME(inode)) + return; + +- err = mnt_want_write_file(file); +- if (err) +- return; +- + now = current_fs_time(inode->i_sb); +- if (!timespec_equal(&inode->i_mtime, &now)) { +- inode->i_mtime = now; +- sync_it = 1; +- } ++ if (!timespec_equal(&inode->i_mtime, &now)) ++ sync_it = S_MTIME; + +- if (!timespec_equal(&inode->i_ctime, &now)) { +- inode->i_ctime = now; +- sync_it = 1; +- } ++ if (!timespec_equal(&inode->i_ctime, &now)) ++ sync_it |= S_CTIME; + +- if (IS_I_VERSION(inode)) { +- inode_inc_iversion(inode); +- sync_it = 1; +- } ++ if (IS_I_VERSION(inode)) ++ sync_it |= S_VERSION; ++ ++ if (!sync_it) ++ return; + +- if (sync_it) +- mark_inode_dirty_sync(inode); ++ /* Finally allowed to write? Takes lock. */ ++ if (mnt_want_write_file(file)) ++ return; ++ ++ /* Only change inode inside the lock region */ ++ if (sync_it & S_VERSION) ++ inode_inc_iversion(inode); ++ if (sync_it & S_CTIME) ++ inode->i_ctime = now; ++ if (sync_it & S_MTIME) ++ inode->i_mtime = now; ++ mark_inode_dirty_sync(inode); + mnt_drop_write(file->f_path.mnt); + } + EXPORT_SYMBOL(file_update_time); +@@ -1594,7 +1619,8 @@ void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) + else if (S_ISSOCK(mode)) + inode->i_fop = &bad_sock_fops; + else +- printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n", +- mode); ++ printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for" ++ " inode %s:%lu\n", mode, inode->i_sb->s_id, ++ inode->i_ino); + } + EXPORT_SYMBOL(init_special_inode); +diff --git a/fs/internal.h b/fs/internal.h +index d55ef56..515175b 100644 +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -57,6 +57,7 @@ extern int check_unsafe_exec(struct linux_binprm *); + * namespace.c + */ + extern int copy_mount_options(const void __user *, unsigned long *); ++extern int copy_mount_string(const void __user *, char **); + + extern void free_vfsmnt(struct vfsmount *); + extern struct vfsmount *alloc_vfsmnt(const char *); +diff --git a/fs/ioctl.c b/fs/ioctl.c +index 5612880..7b17a14 100644 +--- a/fs/ioctl.c ++++ b/fs/ioctl.c +@@ -162,20 +162,21 @@ EXPORT_SYMBOL(fiemap_check_flags); + static int fiemap_check_ranges(struct super_block *sb, + u64 start, u64 len, u64 *new_len) + { ++ u64 maxbytes = (u64) sb->s_maxbytes; ++ + *new_len = len; + + if (len == 0) + return -EINVAL; + +- if (start > sb->s_maxbytes) ++ if (start > maxbytes) + return -EFBIG; + + /* + * Shrink request scope to what the fs can actually handle. + */ +- if ((len > sb->s_maxbytes) || +- (sb->s_maxbytes - len) < start) +- *new_len = sb->s_maxbytes - start; ++ if (len > maxbytes || (maxbytes - len) < start) ++ *new_len = maxbytes - start; + + return 0; + } +diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c +index 85f96bc..6b4dcd4 100644 +--- a/fs/isofs/inode.c ++++ b/fs/isofs/inode.c +@@ -46,10 +46,7 @@ static void isofs_put_super(struct super_block *sb) + #ifdef CONFIG_JOLIET + lock_kernel(); + +- if (sbi->s_nls_iocharset) { +- unload_nls(sbi->s_nls_iocharset); +- sbi->s_nls_iocharset = NULL; +- } ++ unload_nls(sbi->s_nls_iocharset); + + unlock_kernel(); + #endif +@@ -912,8 +909,7 @@ out_no_root: + printk(KERN_WARNING "%s: get root inode failed\n", __func__); + out_no_inode: + #ifdef CONFIG_JOLIET +- if (sbi->s_nls_iocharset) +- unload_nls(sbi->s_nls_iocharset); ++ unload_nls(sbi->s_nls_iocharset); + #endif + goto out_freesbi; + out_no_read: diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 61f32f3..b0435dd 100644 --- a/fs/jbd/checkpoint.c @@ -1619922,6 +1697193,75 @@ index 514ee2e..c79a427 100644 #endif }; +diff --git a/fs/jfs/super.c b/fs/jfs/super.c +index 37e6dcd..2234c73 100644 +--- a/fs/jfs/super.c ++++ b/fs/jfs/super.c +@@ -178,13 +178,11 @@ static void jfs_put_super(struct super_block *sb) + rc = jfs_umount(sb); + if (rc) + jfs_err("jfs_umount failed with return code %d", rc); +- if (sbi->nls_tab) +- unload_nls(sbi->nls_tab); +- sbi->nls_tab = NULL; ++ ++ unload_nls(sbi->nls_tab); + + truncate_inode_pages(sbi->direct_inode->i_mapping, 0); + iput(sbi->direct_inode); +- sbi->direct_inode = NULL; + + kfree(sbi); + +@@ -347,8 +345,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, + + if (nls_map != (void *) -1) { + /* Discard old (if remount) */ +- if (sbi->nls_tab) +- unload_nls(sbi->nls_tab); ++ unload_nls(sbi->nls_tab); + sbi->nls_tab = nls_map; + } + return 1; +diff --git a/fs/libfs.c b/fs/libfs.c +index dcec3d3..219576c 100644 +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -527,14 +527,18 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, + const void *from, size_t available) + { + loff_t pos = *ppos; ++ size_t ret; ++ + if (pos < 0) + return -EINVAL; +- if (pos >= available) ++ if (pos >= available || !count) + return 0; + if (count > available - pos) + count = available - pos; +- if (copy_to_user(to, from + pos, count)) ++ ret = copy_to_user(to, from + pos, count); ++ if (ret == count) + return -EFAULT; ++ count -= ret; + *ppos = pos + count; + return count; + } +@@ -735,10 +739,11 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, + if (copy_from_user(attr->set_buf, buf, size)) + goto out; + +- ret = len; /* claim we got the whole input */ + attr->set_buf[size] = '\0'; + val = simple_strtol(attr->set_buf, NULL, 0); +- attr->set(attr->data, val); ++ ret = attr->set(attr->data, val); ++ if (ret == 0) ++ ret = len; /* on success, claim we got the whole input */ + out: + mutex_unlock(&attr->mutex); + return ret; diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 1f3b0fc..fc9032d 100644 --- a/fs/lockd/clntlock.c @@ -1620095,6 +1697435,30 @@ index 9e4d6aa..ad478da 100644 } /** +diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c +index 0336f2b..b583ab0 100644 +--- a/fs/lockd/xdr.c ++++ b/fs/lockd/xdr.c +@@ -8,7 +8,6 @@ + + #include + #include +-#include + #include + + #include +diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c +index e1d5286..ad9dbbc 100644 +--- a/fs/lockd/xdr4.c ++++ b/fs/lockd/xdr4.c +@@ -9,7 +9,6 @@ + + #include + #include +-#include + #include + + #include diff --git a/fs/locks.c b/fs/locks.c index b6440f5..a8794f2 100644 --- a/fs/locks.c @@ -1620328,6 +1697692,122 @@ index 1f13751..d11f404 100644 if (error) return error; /* +diff --git a/fs/namespace.c b/fs/namespace.c +index 7230787..bdc3cb4 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1640,7 +1640,7 @@ static int do_new_mount(struct path *path, char *type, int flags, + { + struct vfsmount *mnt; + +- if (!type || !memchr(type, 0, PAGE_SIZE)) ++ if (!type) + return -EINVAL; + + /* we need capabilities... */ +@@ -1871,6 +1871,23 @@ int copy_mount_options(const void __user * data, unsigned long *where) + return 0; + } + ++int copy_mount_string(const void __user *data, char **where) ++{ ++ char *tmp; ++ ++ if (!data) { ++ *where = NULL; ++ return 0; ++ } ++ ++ tmp = strndup_user(data, PAGE_SIZE); ++ if (IS_ERR(tmp)) ++ return PTR_ERR(tmp); ++ ++ *where = tmp; ++ return 0; ++} ++ + /* + * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to + * be given to the mount() call (ie: read-only, no-dev, no-suid etc). +@@ -1900,8 +1917,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, + + if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE)) + return -EINVAL; +- if (dev_name && !memchr(dev_name, 0, PAGE_SIZE)) +- return -EINVAL; + + if (data_page) + ((char *)data_page)[PAGE_SIZE - 1] = 0; +@@ -2070,40 +2085,42 @@ EXPORT_SYMBOL(create_mnt_ns); + SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, + char __user *, type, unsigned long, flags, void __user *, data) + { +- int retval; ++ int ret; ++ char *kernel_type; ++ char *kernel_dir; ++ char *kernel_dev; + unsigned long data_page; +- unsigned long type_page; +- unsigned long dev_page; +- char *dir_page; + +- retval = copy_mount_options(type, &type_page); +- if (retval < 0) +- return retval; ++ ret = copy_mount_string(type, &kernel_type); ++ if (ret < 0) ++ goto out_type; + +- dir_page = getname(dir_name); +- retval = PTR_ERR(dir_page); +- if (IS_ERR(dir_page)) +- goto out1; ++ kernel_dir = getname(dir_name); ++ if (IS_ERR(kernel_dir)) { ++ ret = PTR_ERR(kernel_dir); ++ goto out_dir; ++ } + +- retval = copy_mount_options(dev_name, &dev_page); +- if (retval < 0) +- goto out2; ++ ret = copy_mount_string(dev_name, &kernel_dev); ++ if (ret < 0) ++ goto out_dev; + +- retval = copy_mount_options(data, &data_page); +- if (retval < 0) +- goto out3; ++ ret = copy_mount_options(data, &data_page); ++ if (ret < 0) ++ goto out_data; + +- retval = do_mount((char *)dev_page, dir_page, (char *)type_page, +- flags, (void *)data_page); +- free_page(data_page); ++ ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags, ++ (void *) data_page); + +-out3: +- free_page(dev_page); +-out2: +- putname(dir_page); +-out1: +- free_page(type_page); +- return retval; ++ free_page(data_page); ++out_data: ++ kfree(kernel_dev); ++out_dev: ++ putname(kernel_dir); ++out_dir: ++ kfree(kernel_type); ++out_type: ++ return ret; + } + + /* diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 9c59072..b8b5b30 100644 --- a/fs/ncpfs/dir.c @@ -1620341,11 +1697821,47 @@ index 9c59072..b8b5b30 100644 if (day_n[month] > nl_day) break; } +diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c +index b99ce20..cf98da1 100644 +--- a/fs/ncpfs/inode.c ++++ b/fs/ncpfs/inode.c +@@ -746,16 +746,8 @@ static void ncp_put_super(struct super_block *sb) + + #ifdef CONFIG_NCPFS_NLS + /* unload the NLS charsets */ +- if (server->nls_vol) +- { +- unload_nls(server->nls_vol); +- server->nls_vol = NULL; +- } +- if (server->nls_io) +- { +- unload_nls(server->nls_io); +- server->nls_io = NULL; +- } ++ unload_nls(server->nls_vol); ++ unload_nls(server->nls_io); + #endif /* CONFIG_NCPFS_NLS */ + + if (server->info_filp) diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c -index fa038df..53a7ed7 100644 +index fa038df..0d58caf 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c -@@ -442,7 +442,7 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, +@@ -223,10 +223,8 @@ ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) + oldset_io = server->nls_io; + server->nls_io = iocharset; + +- if (oldset_cp) +- unload_nls(oldset_cp); +- if (oldset_io) +- unload_nls(oldset_io); ++ unload_nls(oldset_cp); ++ unload_nls(oldset_io); + + return 0; + } +@@ -442,7 +440,7 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, if (dentry) { struct inode* s_inode = dentry->d_inode; @@ -1621305,7 +1698821,7 @@ index 86147b0..21a84d4 100644 error = PTR_ERR(idmap->idmap_dentry); kfree(idmap); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c -index bd7938e..060022b 100644 +index bd7938e..faa0918 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -46,6 +46,7 @@ @@ -1621375,7 +1698891,70 @@ index bd7938e..060022b 100644 if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED) inode->i_blocks = fattr->du.nfs2.blocks; if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { -@@ -1145,6 +1177,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -426,49 +458,21 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) + */ + static int nfs_vmtruncate(struct inode * inode, loff_t offset) + { +- if (i_size_read(inode) < offset) { +- unsigned long limit; +- +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && offset > limit) +- goto out_sig; +- if (offset > inode->i_sb->s_maxbytes) +- goto out_big; +- spin_lock(&inode->i_lock); +- i_size_write(inode, offset); +- spin_unlock(&inode->i_lock); +- } else { +- struct address_space *mapping = inode->i_mapping; ++ loff_t oldsize; ++ int err; + +- /* +- * truncation of in-use swapfiles is disallowed - it would +- * cause subsequent swapout to scribble on the now-freed +- * blocks. +- */ +- if (IS_SWAPFILE(inode)) +- return -ETXTBSY; +- spin_lock(&inode->i_lock); +- i_size_write(inode, offset); +- spin_unlock(&inode->i_lock); ++ err = inode_newsize_ok(inode, offset); ++ if (err) ++ goto out; + +- /* +- * unmap_mapping_range is called twice, first simply for +- * efficiency so that truncate_inode_pages does fewer +- * single-page unmaps. However after this first call, and +- * before truncate_inode_pages finishes, it is possible for +- * private pages to be COWed, which remain after +- * truncate_inode_pages finishes, hence the second +- * unmap_mapping_range call must be made for correctness. +- */ +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- truncate_inode_pages(mapping, offset); +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- } +- return 0; +-out_sig: +- send_sig(SIGXFSZ, current, 0); +-out_big: +- return -EFBIG; ++ spin_lock(&inode->i_lock); ++ oldsize = inode->i_size; ++ i_size_write(inode, offset); ++ spin_unlock(&inode->i_lock); ++ ++ truncate_pagecache(inode, oldsize, offset); ++out: ++ return err; + } + + /** +@@ -1145,6 +1149,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) loff_t cur_isize, new_isize; unsigned long invalid = 0; unsigned long now = jiffies; @@ -1621383,7 +1698962,7 @@ index bd7938e..060022b 100644 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", __func__, inode->i_sb->s_id, inode->i_ino, -@@ -1171,10 +1204,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1171,10 +1176,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) */ nfsi->read_cache_jiffies = fattr->time_start; @@ -1621399,7 +1698978,7 @@ index bd7938e..060022b 100644 /* Do atomic weak cache consistency updates */ nfs_wcc_update_inode(inode, fattr); -@@ -1189,7 +1223,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1189,7 +1195,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_force_lookup_revalidate(inode); nfsi->change_attr = fattr->change_attr; } @@ -1621409,7 +1698988,7 @@ index bd7938e..060022b 100644 if (fattr->valid & NFS_ATTR_FATTR_MTIME) { /* NFSv2/v3: Check if the mtime agrees */ -@@ -1201,7 +1236,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1201,7 +1208,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) nfs_force_lookup_revalidate(inode); memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); } @@ -1621423,7 +1699002,7 @@ index bd7938e..060022b 100644 if (fattr->valid & NFS_ATTR_FATTR_CTIME) { /* If ctime has changed we should definitely clear access+acl caches */ if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { -@@ -1215,7 +1255,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1215,7 +1227,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) } memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); } @@ -1621436,7 +1699015,7 @@ index bd7938e..060022b 100644 /* Check if our cached file size is stale */ if (fattr->valid & NFS_ATTR_FATTR_SIZE) { -@@ -1231,30 +1275,50 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1231,30 +1247,50 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) dprintk("NFS: isize change on server for file %s/%ld\n", inode->i_sb->s_id, inode->i_ino); } @@ -1621491,7 +1699070,7 @@ index bd7938e..060022b 100644 if (fattr->valid & NFS_ATTR_FATTR_NLINK) { if (inode->i_nlink != fattr->nlink) { -@@ -1263,7 +1327,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1263,7 +1299,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) invalid |= NFS_INO_INVALID_DATA; inode->i_nlink = fattr->nlink; } @@ -1621502,7 +1699081,7 @@ index bd7938e..060022b 100644 if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) { /* -@@ -1293,9 +1359,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) +@@ -1293,9 +1331,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) || S_ISLNK(inode->i_mode))) invalid &= ~NFS_INO_INVALID_DATA; if (!nfs_have_delegation(inode, FMODE_READ) || @@ -1621513,7 +1699092,7 @@ index bd7938e..060022b 100644 return 0; out_changed: -@@ -1442,6 +1507,10 @@ static int __init init_nfs_fs(void) +@@ -1442,6 +1479,10 @@ static int __init init_nfs_fs(void) { int err; @@ -1621524,7 +1699103,7 @@ index bd7938e..060022b 100644 err = nfs_fscache_register(); if (err < 0) goto out7; -@@ -1500,6 +1569,8 @@ out5: +@@ -1500,6 +1541,8 @@ out5: out6: nfs_fscache_unregister(); out7: @@ -1621533,7 +1699112,7 @@ index bd7938e..060022b 100644 return err; } -@@ -1511,6 +1582,7 @@ static void __exit exit_nfs_fs(void) +@@ -1511,6 +1554,7 @@ static void __exit exit_nfs_fs(void) nfs_destroy_inodecache(); nfs_destroy_nfspagecache(); nfs_fscache_unregister(); @@ -1621759,11 +1699338,31 @@ index 38ef9ea..0adefc4 100644 }; +diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c +index c862c93..5e078b2 100644 +--- a/fs/nfs/nfs2xdr.c ++++ b/fs/nfs/nfs2xdr.c +@@ -13,7 +13,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c -index d0cc5ce..ee6a13f 100644 +index d0cc5ce..3f8881d 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c -@@ -299,7 +299,6 @@ static void nfs3_free_createdata(struct nfs3_createdata *data) +@@ -7,7 +7,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -299,7 +298,6 @@ static void nfs3_free_createdata(struct nfs3_createdata *data) /* * Create a regular file. @@ -1621771,6 +1699370,18 @@ index d0cc5ce..ee6a13f 100644 */ static int nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, +diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c +index 35869a4..5fe5492 100644 +--- a/fs/nfs/nfs3xdr.c ++++ b/fs/nfs/nfs3xdr.c +@@ -10,7 +10,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 2a2a0a7..2636c26 100644 --- a/fs/nfs/nfs4namespace.c @@ -1621822,10 +1699433,18 @@ index 2a2a0a7..2636c26 100644 memcpy(page2, buf->data, buf->len); page2[buf->len] = '\0'; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c -index 6917311..be6544a 100644 +index 6917311..ed7c269 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c -@@ -61,6 +61,8 @@ +@@ -36,7 +36,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -61,6 +60,8 @@ #define NFS4_POLL_RETRY_MIN (HZ/10) #define NFS4_POLL_RETRY_MAX (15*HZ) @@ -1621834,7 +1699453,7 @@ index 6917311..be6544a 100644 struct nfs4_opendata; static int _nfs4_proc_open(struct nfs4_opendata *data); static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); -@@ -426,17 +428,19 @@ out: +@@ -426,17 +427,19 @@ out: static int nfs4_recover_session(struct nfs4_session *session) { struct nfs_client *clp = session->clp; @@ -1621857,7 +1699476,7 @@ index 6917311..be6544a 100644 } static int nfs41_setup_sequence(struct nfs4_session *session, -@@ -1444,18 +1448,20 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) +@@ -1444,18 +1447,20 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) static int nfs4_recover_expired_lease(struct nfs_server *server) { struct nfs_client *clp = server->nfs_client; @@ -1621881,7 +1699500,7 @@ index 6917311..be6544a 100644 } /* -@@ -1997,12 +2003,34 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f +@@ -1997,12 +2002,34 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f status = nfs4_call_sync(server, &msg, &args, &res, 0); if (status == 0) { memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); @@ -1621930,10 +1699549,18 @@ index 1434080..2ef4fec 100644 .fl_release_private = nfs4_fl_release_lock, }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c -index 617273e..cfc30d3 100644 +index 617273e..83ad47c 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c -@@ -702,29 +702,12 @@ struct compound_hdr { +@@ -39,7 +39,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -702,29 +701,12 @@ struct compound_hdr { u32 minorversion; }; @@ -1621969,7 +1699596,7 @@ index 617273e..cfc30d3 100644 static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) { -@@ -749,12 +732,11 @@ static void encode_compound_hdr(struct xdr_stream *xdr, +@@ -749,12 +731,11 @@ static void encode_compound_hdr(struct xdr_stream *xdr, dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag); BUG_ON(hdr->taglen > NFS4_MAXTAGLEN); @@ -1621986,7 +1699613,7 @@ index 617273e..cfc30d3 100644 } static void encode_nops(struct compound_hdr *hdr) -@@ -829,55 +811,53 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const +@@ -829,55 +810,53 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const len += 16; else if (iap->ia_valid & ATTR_MTIME) len += 4; @@ -1622058,7 +1699685,7 @@ index 617273e..cfc30d3 100644 } /* -@@ -891,7 +871,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const +@@ -891,7 +870,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const len = (char *)p - (char *)q - 12; *q++ = htonl(bmval0); *q++ = htonl(bmval1); @@ -1622067,7 +1699694,7 @@ index 617273e..cfc30d3 100644 /* out: */ } -@@ -900,9 +880,9 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd +@@ -900,9 +879,9 @@ static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hd { __be32 *p; @@ -1622080,7 +1699707,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_access_maxsz; } -@@ -911,10 +891,10 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg +@@ -911,10 +890,10 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg { __be32 *p; @@ -1622095,7 +1699722,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_close_maxsz; } -@@ -923,10 +903,10 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar +@@ -923,10 +902,10 @@ static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *ar { __be32 *p; @@ -1622110,7 +1699737,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_commit_maxsz; } -@@ -935,30 +915,28 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * +@@ -935,30 +914,28 @@ static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg * { __be32 *p; @@ -1622150,7 +1699777,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_create_maxsz; -@@ -969,10 +947,10 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c +@@ -969,10 +946,10 @@ static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct c { __be32 *p; @@ -1622165,7 +1699792,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_getattr_maxsz; } -@@ -981,11 +959,11 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm +@@ -981,11 +958,11 @@ static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm { __be32 *p; @@ -1622182,7 +1699809,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_getattr_maxsz; } -@@ -1012,8 +990,8 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr) +@@ -1012,8 +989,8 @@ static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; @@ -1622193,7 +1699820,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_getfh_maxsz; } -@@ -1022,10 +1000,9 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct +@@ -1022,10 +999,9 @@ static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct { __be32 *p; @@ -1622207,7 +1699834,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_link_maxsz; } -@@ -1052,27 +1029,27 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args +@@ -1052,27 +1028,27 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args { __be32 *p; @@ -1622253,7 +1699880,7 @@ index 617273e..cfc30d3 100644 } hdr->nops++; hdr->replen += decode_lock_maxsz; -@@ -1082,15 +1059,15 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar +@@ -1082,15 +1058,15 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar { __be32 *p; @@ -1622278,7 +1699905,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_lockt_maxsz; } -@@ -1099,13 +1076,13 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar +@@ -1099,13 +1075,13 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar { __be32 *p; @@ -1622299,7 +1699926,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_locku_maxsz; } -@@ -1115,10 +1092,9 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc +@@ -1115,10 +1091,9 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc int len = name->len; __be32 *p; @@ -1622313,7 +1699940,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_lookup_maxsz; } -@@ -1127,21 +1103,21 @@ static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode) +@@ -1127,21 +1102,21 @@ static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode) { __be32 *p; @@ -1622341,7 +1699968,7 @@ index 617273e..cfc30d3 100644 } static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg) -@@ -1151,29 +1127,29 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena +@@ -1151,29 +1126,29 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4, * owner 4 = 32 */ @@ -1622382,7 +1700009,7 @@ index 617273e..cfc30d3 100644 encode_nfs4_verifier(xdr, &arg->u.verifier); } } -@@ -1182,14 +1158,14 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a +@@ -1182,14 +1157,14 @@ static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *a { __be32 *p; @@ -1622400,7 +1700027,7 @@ index 617273e..cfc30d3 100644 encode_createmode(xdr, arg); } } -@@ -1198,16 +1174,16 @@ static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delega +@@ -1198,16 +1173,16 @@ static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delega { __be32 *p; @@ -1622421,7 +1700048,7 @@ index 617273e..cfc30d3 100644 break; default: BUG(); -@@ -1218,8 +1194,8 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr * +@@ -1218,8 +1193,8 @@ static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr * { __be32 *p; @@ -1622432,7 +1700059,7 @@ index 617273e..cfc30d3 100644 encode_string(xdr, name->len, name->name); } -@@ -1227,8 +1203,8 @@ static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type) +@@ -1227,8 +1202,8 @@ static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type) { __be32 *p; @@ -1622443,7 +1700070,7 @@ index 617273e..cfc30d3 100644 encode_delegation_type(xdr, type); } -@@ -1236,9 +1212,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc +@@ -1236,9 +1211,9 @@ static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struc { __be32 *p; @@ -1622456,7 +1700083,7 @@ index 617273e..cfc30d3 100644 encode_string(xdr, name->len, name->name); } -@@ -1267,10 +1243,10 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co +@@ -1267,10 +1242,10 @@ static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_co { __be32 *p; @@ -1622471,7 +1700098,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_open_confirm_maxsz; } -@@ -1279,10 +1255,10 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close +@@ -1279,10 +1254,10 @@ static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_close { __be32 *p; @@ -1622486,7 +1700113,7 @@ index 617273e..cfc30d3 100644 encode_share_access(xdr, arg->fmode); hdr->nops++; hdr->replen += decode_open_downgrade_maxsz; -@@ -1294,10 +1270,9 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd +@@ -1294,10 +1269,9 @@ encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hd int len = fh->size; __be32 *p; @@ -1622500,7 +1700127,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_putfh_maxsz; } -@@ -1306,8 +1281,8 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) +@@ -1306,8 +1280,8 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; @@ -1622511,7 +1700138,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_putrootfh_maxsz; } -@@ -1317,26 +1292,26 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context +@@ -1317,26 +1291,26 @@ static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context nfs4_stateid stateid; __be32 *p; @@ -1622546,7 +1700173,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_read_maxsz; } -@@ -1349,20 +1324,20 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg +@@ -1349,20 +1323,20 @@ static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg }; __be32 *p; @@ -1622576,7 +1700203,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_readdir_maxsz; dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n", -@@ -1378,8 +1353,8 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink * +@@ -1378,8 +1352,8 @@ static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink * { __be32 *p; @@ -1622587,7 +1700214,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_readlink_maxsz; } -@@ -1388,10 +1363,9 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc +@@ -1388,10 +1362,9 @@ static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struc { __be32 *p; @@ -1622601,7 +1700228,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_remove_maxsz; } -@@ -1400,14 +1374,10 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co +@@ -1400,14 +1373,10 @@ static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, co { __be32 *p; @@ -1622620,7 +1700247,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_rename_maxsz; } -@@ -1416,9 +1386,9 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client +@@ -1416,9 +1385,9 @@ static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client { __be32 *p; @@ -1622633,7 +1700260,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_renew_maxsz; } -@@ -1428,8 +1398,8 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) +@@ -1428,8 +1397,8 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; @@ -1622644,7 +1700271,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_restorefh_maxsz; } -@@ -1439,16 +1409,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun +@@ -1439,16 +1408,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun { __be32 *p; @@ -1622669,7 +1700296,7 @@ index 617273e..cfc30d3 100644 xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); hdr->nops++; hdr->replen += decode_setacl_maxsz; -@@ -1460,8 +1430,8 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr) +@@ -1460,8 +1429,8 @@ encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; @@ -1622680,7 +1700307,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_savefh_maxsz; } -@@ -1470,9 +1440,9 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs +@@ -1470,9 +1439,9 @@ static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs { __be32 *p; @@ -1622693,7 +1700320,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_setattr_maxsz; encode_attrs(xdr, arg->iap, server); -@@ -1482,17 +1452,17 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie +@@ -1482,17 +1451,17 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie { __be32 *p; @@ -1622718,7 +1700345,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_setclientid_maxsz; } -@@ -1501,10 +1471,10 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_ +@@ -1501,10 +1470,10 @@ static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_ { __be32 *p; @@ -1622733,7 +1700360,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_setclientid_confirm_maxsz; } -@@ -1513,15 +1483,15 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg +@@ -1513,15 +1482,15 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg { __be32 *p; @@ -1622755,7 +1700382,7 @@ index 617273e..cfc30d3 100644 xdr_write_pages(xdr, args->pages, args->pgbase, args->count); hdr->nops++; -@@ -1532,10 +1502,10 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state +@@ -1532,10 +1501,10 @@ static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *state { __be32 *p; @@ -1622769,7 +1700396,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_delegreturn_maxsz; } -@@ -1548,16 +1518,16 @@ static void encode_exchange_id(struct xdr_stream *xdr, +@@ -1548,16 +1517,16 @@ static void encode_exchange_id(struct xdr_stream *xdr, { __be32 *p; @@ -1622793,7 +1700420,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_exchange_id_maxsz; } -@@ -1571,55 +1541,43 @@ static void encode_create_session(struct xdr_stream *xdr, +@@ -1571,55 +1540,43 @@ static void encode_create_session(struct xdr_stream *xdr, uint32_t len; struct nfs_client *clp = args->client; @@ -1622879,7 +1700506,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_create_session_maxsz; } -@@ -1629,9 +1587,9 @@ static void encode_destroy_session(struct xdr_stream *xdr, +@@ -1629,9 +1586,9 @@ static void encode_destroy_session(struct xdr_stream *xdr, struct compound_hdr *hdr) { __be32 *p; @@ -1622892,7 +1700519,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_destroy_session_maxsz; } -@@ -1655,8 +1613,8 @@ static void encode_sequence(struct xdr_stream *xdr, +@@ -1655,8 +1612,8 @@ static void encode_sequence(struct xdr_stream *xdr, WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE); slot = tp->slots + args->sa_slotid; @@ -1622903,7 +1700530,7 @@ index 617273e..cfc30d3 100644 /* * Sessionid + seqid + slotid + max slotid + cache_this -@@ -1670,12 +1628,11 @@ static void encode_sequence(struct xdr_stream *xdr, +@@ -1670,12 +1627,11 @@ static void encode_sequence(struct xdr_stream *xdr, ((u32 *)session->sess_id.data)[3], slot->seq_nr, args->sa_slotid, tp->highest_used_slotid, args->sa_cache_this); @@ -1622921,7 +1700548,7 @@ index 617273e..cfc30d3 100644 hdr->nops++; hdr->replen += decode_sequence_maxsz; #endif /* CONFIG_NFS_V4_1 */ -@@ -2466,68 +2423,53 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, +@@ -2466,68 +2422,53 @@ static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, } #endif /* CONFIG_NFS_V4_1 */ @@ -1623018,7 +1700645,7 @@ index 617273e..cfc30d3 100644 } static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) -@@ -2536,18 +2478,23 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) +@@ -2536,18 +2477,23 @@ static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) uint32_t opnum; int32_t nfserr; @@ -1623045,7 +1700672,7 @@ index 617273e..cfc30d3 100644 } /* Dummy routine */ -@@ -2557,8 +2504,11 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) +@@ -2557,8 +2503,11 @@ static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp) unsigned int strlen; char *str; @@ -1623059,7 +1700686,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) -@@ -2566,27 +2516,39 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) +@@ -2566,27 +2515,39 @@ static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) uint32_t bmlen; __be32 *p; @@ -1623106,7 +1700733,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) -@@ -2609,8 +2571,10 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * +@@ -2609,8 +2570,10 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { @@ -1623119,7 +1700746,7 @@ index 617273e..cfc30d3 100644 if (*type < NF4REG || *type > NF4NAMEDATTR) { dprintk("%s: bad type %d\n", __func__, *type); return -EIO; -@@ -2620,6 +2584,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * +@@ -2620,6 +2583,9 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * } dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); return ret; @@ -1623129,7 +1700756,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) -@@ -2631,14 +2598,19 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t +@@ -2631,14 +2597,19 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { @@ -1623151,7 +1700778,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) -@@ -2650,13 +2622,18 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * +@@ -2650,13 +2621,18 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { @@ -1623172,7 +1700799,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -2667,12 +2644,17 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui +@@ -2667,12 +2643,17 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { @@ -1623192,7 +1700819,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -2683,12 +2665,17 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, +@@ -2683,12 +2664,17 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { @@ -1623212,7 +1700839,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) -@@ -2701,9 +2688,11 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs +@@ -2701,9 +2687,11 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { @@ -1623227,7 +1700854,7 @@ index 617273e..cfc30d3 100644 bitmap[0] &= ~FATTR4_WORD0_FSID; ret = NFS_ATTR_FATTR_FSID; } -@@ -2711,6 +2700,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs +@@ -2711,6 +2699,9 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs (unsigned long long)fsid->major, (unsigned long long)fsid->minor); return ret; @@ -1623237,7 +1700864,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -2721,12 +2713,17 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint +@@ -2721,12 +2712,17 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { @@ -1623257,7 +1700884,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -2737,12 +2734,17 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint +@@ -2737,12 +2733,17 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { @@ -1623277,7 +1700904,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) -@@ -2754,13 +2756,18 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t +@@ -2754,13 +2755,18 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { @@ -1623298,7 +1700925,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) -@@ -2772,13 +2779,18 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma +@@ -2772,13 +2778,18 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { @@ -1623319,7 +1700946,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -2790,12 +2802,17 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin +@@ -2790,12 +2801,17 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { @@ -1623339,7 +1700966,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -2807,12 +2824,17 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint +@@ -2807,12 +2823,17 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { @@ -1623359,7 +1700986,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -2824,12 +2846,17 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin +@@ -2824,12 +2845,17 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { @@ -1623379,7 +1701006,7 @@ index 617273e..cfc30d3 100644 } static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) -@@ -2838,8 +2865,10 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) +@@ -2838,8 +2864,10 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) __be32 *p; int status = 0; @@ -1623392,7 +1701019,7 @@ index 617273e..cfc30d3 100644 if (n == 0) goto root_path; dprintk("path "); -@@ -2873,6 +2902,9 @@ out_eio: +@@ -2873,6 +2901,9 @@ out_eio: dprintk(" status %d", status); status = -EIO; goto out; @@ -1623402,7 +1701029,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) -@@ -2890,8 +2922,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st +@@ -2890,8 +2921,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st status = decode_pathname(xdr, &res->fs_path); if (unlikely(status != 0)) goto out; @@ -1623415,7 +1701042,7 @@ index 617273e..cfc30d3 100644 if (n <= 0) goto out_eio; res->nlocations = 0; -@@ -2899,8 +2933,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st +@@ -2899,8 +2932,10 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st u32 m; struct nfs4_fs_location *loc = &res->locations[res->nlocations]; @@ -1623428,7 +1701055,7 @@ index 617273e..cfc30d3 100644 loc->nservers = 0; dprintk("%s: servers ", __func__); -@@ -2939,6 +2975,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st +@@ -2939,6 +2974,8 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st out: dprintk("%s: fs_locations done, error = %d\n", __func__, status); return status; @@ -1623437,7 +1701064,7 @@ index 617273e..cfc30d3 100644 out_eio: status = -EIO; goto out; -@@ -2953,12 +2991,17 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin +@@ -2953,12 +2990,17 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { @@ -1623457,7 +1701084,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) -@@ -2970,12 +3013,17 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ +@@ -2970,12 +3012,17 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { @@ -1623477,7 +1701104,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) -@@ -2987,12 +3035,17 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ +@@ -2987,12 +3034,17 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { @@ -1623497,7 +1701124,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -3005,8 +3058,10 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ +@@ -3005,8 +3057,10 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) { uint64_t maxread; @@ -1623510,7 +1701137,7 @@ index 617273e..cfc30d3 100644 if (maxread > 0x7FFFFFFF) maxread = 0x7FFFFFFF; *res = (uint32_t)maxread; -@@ -3014,6 +3069,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ +@@ -3014,6 +3068,9 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ } dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); return status; @@ -1623520,7 +1701147,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) -@@ -3026,8 +3084,10 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 +@@ -3026,8 +3083,10 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) { uint64_t maxwrite; @@ -1623533,7 +1701160,7 @@ index 617273e..cfc30d3 100644 if (maxwrite > 0x7FFFFFFF) maxwrite = 0x7FFFFFFF; *res = (uint32_t)maxwrite; -@@ -3035,6 +3095,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 +@@ -3035,6 +3094,9 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 } dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); return status; @@ -1623543,7 +1701170,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) -@@ -3047,14 +3110,19 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m +@@ -3047,14 +3109,19 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { @@ -1623565,7 +1701192,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) -@@ -3066,16 +3134,22 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t +@@ -3066,16 +3133,22 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { @@ -1623591,7 +1701218,7 @@ index 617273e..cfc30d3 100644 { uint32_t len; __be32 *p; -@@ -3085,10 +3159,16 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf +@@ -3085,10 +3158,16 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) { @@ -1623612,7 +1701239,7 @@ index 617273e..cfc30d3 100644 if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) ret = NFS_ATTR_FATTR_OWNER; else -@@ -3101,9 +3181,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf +@@ -3101,9 +3180,13 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nf } dprintk("%s: uid=%d\n", __func__, (int)*uid); return ret; @@ -1623627,7 +1701254,7 @@ index 617273e..cfc30d3 100644 { uint32_t len; __be32 *p; -@@ -3113,10 +3197,16 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf +@@ -3113,10 +3196,16 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) { @@ -1623648,7 +1701275,7 @@ index 617273e..cfc30d3 100644 if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) ret = NFS_ATTR_FATTR_GROUP; else -@@ -3129,6 +3219,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf +@@ -3129,6 +3218,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nf } dprintk("%s: gid=%d\n", __func__, (int)*gid); return ret; @@ -1623658,7 +1701285,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) -@@ -3143,9 +3236,11 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde +@@ -3143,9 +3235,11 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) { dev_t tmp; @@ -1623673,7 +1701300,7 @@ index 617273e..cfc30d3 100644 tmp = MKDEV(major, minor); if (MAJOR(tmp) == major && MINOR(tmp) == minor) *rdev = tmp; -@@ -3154,6 +3249,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde +@@ -3154,6 +3248,9 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde } dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); return ret; @@ -1623683,7 +1701310,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -3165,12 +3263,17 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin +@@ -3165,12 +3262,17 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { @@ -1623703,7 +1701330,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -3182,12 +3285,17 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint +@@ -3182,12 +3284,17 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { @@ -1623723,7 +1701350,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) -@@ -3199,12 +3307,17 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin +@@ -3199,12 +3306,17 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { @@ -1623743,7 +1701370,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) -@@ -3216,14 +3329,19 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint +@@ -3216,14 +3328,19 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U))) return -EIO; if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { @@ -1623765,7 +1701392,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) -@@ -3232,12 +3350,17 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) +@@ -3232,12 +3349,17 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) uint64_t sec; uint32_t nsec; @@ -1623786,7 +1701413,7 @@ index 617273e..cfc30d3 100644 } static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) -@@ -3315,11 +3438,16 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c +@@ -3315,11 +3437,16 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c { __be32 *p; @@ -1623807,7 +1701434,7 @@ index 617273e..cfc30d3 100644 } static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) -@@ -3331,40 +3459,62 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) +@@ -3331,40 +3458,62 @@ static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access) status = decode_op_hdr(xdr, OP_ACCESS); if (status) return status; @@ -1623885,7 +1701512,7 @@ index 617273e..cfc30d3 100644 } static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) -@@ -3378,10 +3528,16 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) +@@ -3378,10 +3527,16 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) return status; if ((status = decode_change_info(xdr, cinfo))) return status; @@ -1623906,7 +1701533,7 @@ index 617273e..cfc30d3 100644 } static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res) -@@ -3466,7 +3622,8 @@ xdr_error: +@@ -3466,7 +3621,8 @@ xdr_error: return status; } @@ -1623916,7 +1701543,7 @@ index 617273e..cfc30d3 100644 { __be32 *savep; uint32_t attrlen, -@@ -3538,12 +3695,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons +@@ -3538,12 +3694,14 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons goto xdr_error; fattr->valid |= status; @@ -1623933,7 +1701560,7 @@ index 617273e..cfc30d3 100644 if (status < 0) goto xdr_error; fattr->valid |= status; -@@ -3633,14 +3792,21 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) +@@ -3633,14 +3791,21 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) if (status) return status; @@ -1623959,7 +1701586,7 @@ index 617273e..cfc30d3 100644 } static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) -@@ -3662,10 +3828,12 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) +@@ -3662,10 +3827,12 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) __be32 *p; uint32_t namelen, type; @@ -1623976,7 +1701603,7 @@ index 617273e..cfc30d3 100644 if (fl != NULL) { fl->fl_start = (loff_t)offset; fl->fl_end = fl->fl_start + (loff_t)length - 1; -@@ -3676,23 +3844,27 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) +@@ -3676,23 +3843,27 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) fl->fl_type = F_RDLCK; fl->fl_pid = 0; } @@ -1624011,7 +1701638,7 @@ index 617273e..cfc30d3 100644 } else if (status == -NFS4ERR_DENIED) status = decode_lock_denied(xdr, NULL); if (res->open_seqid != NULL) -@@ -3713,16 +3885,13 @@ static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) +@@ -3713,16 +3884,13 @@ static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res) static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res) { @@ -1624030,7 +1701657,7 @@ index 617273e..cfc30d3 100644 return status; } -@@ -3737,34 +3906,46 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) +@@ -3737,34 +3905,46 @@ static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize) __be32 *p; uint32_t limit_type, nblocks, blocksize; @@ -1624087,7 +1701714,7 @@ index 617273e..cfc30d3 100644 switch (delegation_type) { case NFS4_OPEN_DELEGATE_READ: -@@ -3776,6 +3957,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -3776,6 +3956,9 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) return -EIO; } return decode_ace(xdr, NULL, res->server->nfs_client); @@ -1624097,7 +1701724,7 @@ index 617273e..cfc30d3 100644 } static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) -@@ -3787,23 +3971,27 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -3787,23 +3970,27 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) status = decode_op_hdr(xdr, OP_OPEN); if (status != -EIO) nfs_increment_open_seqid(status, res->seqid); @@ -1624133,7 +1701760,7 @@ index 617273e..cfc30d3 100644 for (; i < NFS4_BITMAP_SIZE; i++) res->attrset[i] = 0; -@@ -3811,36 +3999,33 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -3811,36 +3998,33 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) xdr_error: dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); return -EIO; @@ -1624179,7 +1701806,7 @@ index 617273e..cfc30d3 100644 } static int decode_putfh(struct xdr_stream *xdr) -@@ -3863,9 +4048,11 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ +@@ -3863,9 +4047,11 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ status = decode_op_hdr(xdr, OP_READ); if (status) return status; @@ -1624194,7 +1701821,7 @@ index 617273e..cfc30d3 100644 hdrlen = (u8 *) p - (u8 *) iov->iov_base; recvd = req->rq_rcv_buf.len - hdrlen; if (count > recvd) { -@@ -3878,6 +4065,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ +@@ -3878,6 +4064,9 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ res->eof = eof; res->count = count; return 0; @@ -1624204,7 +1701831,7 @@ index 617273e..cfc30d3 100644 } static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) -@@ -3892,17 +4082,17 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n +@@ -3892,17 +4081,17 @@ static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct n int status; status = decode_op_hdr(xdr, OP_READDIR); @@ -1624226,7 +1701853,7 @@ index 617273e..cfc30d3 100644 recvd = rcvbuf->len - hdrlen; if (pglen > recvd) pglen = recvd; -@@ -3990,8 +4180,10 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) +@@ -3990,8 +4179,10 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) return status; /* Convert length of symlink */ @@ -1624239,7 +1701866,7 @@ index 617273e..cfc30d3 100644 if (len >= rcvbuf->page_len || len <= 0) { dprintk("nfs: server returned giant symlink!\n"); return -ENAMETOOLONG; -@@ -4015,6 +4207,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) +@@ -4015,6 +4206,9 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) kaddr[len+rcvbuf->page_base] = '\0'; kunmap_atomic(kaddr, KM_USER0); return 0; @@ -1624249,7 +1701876,7 @@ index 617273e..cfc30d3 100644 } static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) -@@ -4112,10 +4307,16 @@ static int decode_setattr(struct xdr_stream *xdr) +@@ -4112,10 +4306,16 @@ static int decode_setattr(struct xdr_stream *xdr) status = decode_op_hdr(xdr, OP_SETATTR); if (status) return status; @@ -1624270,7 +1701897,7 @@ index 617273e..cfc30d3 100644 } static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) -@@ -4124,35 +4325,50 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) +@@ -4124,35 +4324,50 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp) uint32_t opnum; int32_t nfserr; @@ -1624333,7 +1701960,7 @@ index 617273e..cfc30d3 100644 } static int decode_setclientid_confirm(struct xdr_stream *xdr) -@@ -4169,11 +4385,16 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res) +@@ -4169,11 +4384,16 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res) if (status) return status; @@ -1624354,7 +1701981,7 @@ index 617273e..cfc30d3 100644 } static int decode_delegreturn(struct xdr_stream *xdr) -@@ -4187,6 +4408,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, +@@ -4187,6 +4407,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, { __be32 *p; uint32_t dummy; @@ -1624362,7 +1701989,7 @@ index 617273e..cfc30d3 100644 int status; struct nfs_client *clp = res->client; -@@ -4194,36 +4416,45 @@ static int decode_exchange_id(struct xdr_stream *xdr, +@@ -4194,36 +4415,45 @@ static int decode_exchange_id(struct xdr_stream *xdr, if (status) return status; @@ -1624424,7 +1702051,7 @@ index 617273e..cfc30d3 100644 } static int decode_chan_attrs(struct xdr_stream *xdr, -@@ -4232,22 +4463,35 @@ static int decode_chan_attrs(struct xdr_stream *xdr, +@@ -4232,22 +4462,35 @@ static int decode_chan_attrs(struct xdr_stream *xdr, __be32 *p; u32 nr_attrs; @@ -1624470,7 +1702097,7 @@ index 617273e..cfc30d3 100644 } static int decode_create_session(struct xdr_stream *xdr, -@@ -4259,24 +4503,26 @@ static int decode_create_session(struct xdr_stream *xdr, +@@ -4259,24 +4502,26 @@ static int decode_create_session(struct xdr_stream *xdr, struct nfs4_session *session = clp->cl_session; status = decode_op_hdr(xdr, OP_CREATE_SESSION); @@ -1624506,7 +1702133,7 @@ index 617273e..cfc30d3 100644 } static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) -@@ -4300,7 +4546,9 @@ static int decode_sequence(struct xdr_stream *xdr, +@@ -4300,7 +4545,9 @@ static int decode_sequence(struct xdr_stream *xdr, return 0; status = decode_op_hdr(xdr, OP_SEQUENCE); @@ -1624517,7 +1702144,7 @@ index 617273e..cfc30d3 100644 goto out_err; /* -@@ -4309,36 +4557,43 @@ static int decode_sequence(struct xdr_stream *xdr, +@@ -4309,36 +4556,43 @@ static int decode_sequence(struct xdr_stream *xdr, */ status = -ESERVERFAULT; @@ -1624569,7 +1702196,7 @@ index 617273e..cfc30d3 100644 #else /* CONFIG_NFS_V4_1 */ return 0; #endif /* CONFIG_NFS_V4_1 */ -@@ -4370,7 +4625,8 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct +@@ -4370,7 +4624,8 @@ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct status = decode_open_downgrade(&xdr, res); if (status != 0) goto out; @@ -1624579,7 +1702206,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4397,7 +4653,8 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac +@@ -4397,7 +4652,8 @@ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_ac status = decode_access(&xdr, res); if (status != 0) goto out; @@ -1624589,7 +1702216,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4424,7 +4681,8 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo +@@ -4424,7 +4680,8 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lo goto out; if ((status = decode_getfh(&xdr, res->fh)) != 0) goto out; @@ -1624599,7 +1702226,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4448,7 +4706,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf +@@ -4448,7 +4705,8 @@ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nf if ((status = decode_putrootfh(&xdr)) != 0) goto out; if ((status = decode_getfh(&xdr, res->fh)) == 0) @@ -1624609,7 +1702236,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4473,7 +4732,8 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem +@@ -4473,7 +4731,8 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_rem goto out; if ((status = decode_remove(&xdr, &res->cinfo)) != 0) goto out; @@ -1624619,7 +1702246,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4503,11 +4763,13 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re +@@ -4503,11 +4762,13 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_re if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) goto out; /* Current FH is target directory */ @@ -1624635,7 +1702262,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4540,11 +4802,13 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link +@@ -4540,11 +4801,13 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link * Note order: OP_LINK leaves the directory as the current * filehandle. */ @@ -1624651,7 +1702278,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4573,11 +4837,13 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr +@@ -4573,11 +4836,13 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_cr goto out; if ((status = decode_getfh(&xdr, res->fh)) != 0) goto out; @@ -1624667,7 +1702294,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4609,7 +4875,8 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g +@@ -4609,7 +4874,8 @@ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_g status = decode_putfh(&xdr); if (status) goto out; @@ -1624677,7 +1702304,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4716,7 +4983,8 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos +@@ -4716,7 +4982,8 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos * an ESTALE error. Shouldn't be a problem, * though, since fattr->valid will remain unset. */ @@ -1624687,7 +1702314,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4748,11 +5016,13 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr +@@ -4748,11 +5015,13 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openr goto out; if (decode_getfh(&xdr, &res->fh) != 0) goto out; @@ -1624703,7 +1702330,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4800,7 +5070,8 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf +@@ -4800,7 +5069,8 @@ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nf status = decode_open(&xdr, res); if (status) goto out; @@ -1624713,7 +1702340,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -4827,7 +5098,8 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se +@@ -4827,7 +5097,8 @@ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_se status = decode_setattr(&xdr); if (status) goto out; @@ -1624723,7 +1702350,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -5001,7 +5273,8 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ +@@ -5001,7 +5272,8 @@ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writ status = decode_write(&xdr, res); if (status) goto out; @@ -1624733,7 +1702360,7 @@ index 617273e..cfc30d3 100644 if (!status) status = res->count; out: -@@ -5030,7 +5303,8 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri +@@ -5030,7 +5302,8 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_wri status = decode_commit(&xdr, res); if (status) goto out; @@ -1624743,7 +1702370,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -5194,7 +5468,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf +@@ -5194,7 +5467,8 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nf if (status != 0) goto out; status = decode_delegreturn(&xdr); @@ -1624753,7 +1702380,7 @@ index 617273e..cfc30d3 100644 out: return status; } -@@ -5222,7 +5497,8 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, +@@ -5222,7 +5496,8 @@ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, goto out; xdr_enter_page(&xdr, PAGE_SIZE); status = decode_getfattr(&xdr, &res->fs_locations->fattr, @@ -1624763,6 +1702390,18 @@ index 617273e..cfc30d3 100644 out: return status; } +diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c +index 7be72d9..ef58385 100644 +--- a/fs/nfs/proc.c ++++ b/fs/nfs/proc.c +@@ -32,7 +32,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 0b4cbdc..810770f 100644 --- a/fs/nfs/super.c @@ -1626519,10 +1704158,18 @@ index 3fd23f7..24e8d78 100644 nfs4_put_delegation(dp); } diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c -index 5b39842..cdfa86f 100644 +index 5b39842..ba2c199 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c -@@ -146,6 +146,12 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, +@@ -38,7 +38,6 @@ + #include + + #include +-#include + #include + #include + #include +@@ -146,6 +145,12 @@ idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, } static int @@ -1626535,7 +1704182,7 @@ index 5b39842..cdfa86f 100644 idtoname_match(struct cache_head *ca, struct cache_head *cb) { struct ent *a = container_of(ca, struct ent, h); -@@ -175,10 +181,10 @@ idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) +@@ -175,10 +180,10 @@ idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) } static void @@ -1626548,7 +1704195,7 @@ index 5b39842..cdfa86f 100644 } -@@ -192,7 +198,7 @@ static struct cache_detail idtoname_cache = { +@@ -192,7 +197,7 @@ static struct cache_detail idtoname_cache = { .hash_table = idtoname_table, .name = "nfs4.idtoname", .cache_put = ent_put, @@ -1626557,7 +1704204,7 @@ index 5b39842..cdfa86f 100644 .cache_parse = idtoname_parse, .cache_show = idtoname_show, .warn_no_listener = warn_no_idmapd, -@@ -325,6 +331,12 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, +@@ -325,6 +330,12 @@ nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, } static int @@ -1626570,7 +1704217,7 @@ index 5b39842..cdfa86f 100644 nametoid_match(struct cache_head *ca, struct cache_head *cb) { struct ent *a = container_of(ca, struct ent, h); -@@ -363,7 +375,7 @@ static struct cache_detail nametoid_cache = { +@@ -363,7 +374,7 @@ static struct cache_detail nametoid_cache = { .hash_table = nametoid_table, .name = "nfs4.nametoid", .cache_put = ent_put, @@ -1631469,7 +1709116,7 @@ index 1b9caaf..20abd55 100644 static inline void nilfs_put_sbinfo(struct nilfs_sb_info *sbi) diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c -index 477d37d..b25c218 100644 +index 477d37d..44a88a9 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c @@ -124,10 +124,10 @@ int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs) @@ -1631487,6 +1709134,16 @@ index 477d37d..b25c218 100644 u -= PLANE_SIZE; *op++ = (wchar_t) (SURROGATE_PAIR | ((u >> 10) & SURROGATE_BITS)); +@@ -270,7 +270,8 @@ struct nls_table *load_nls(char *charset) + + void unload_nls(struct nls_table *nls) + { +- module_put(nls->owner); ++ if (nls) ++ module_put(nls->owner); + } + + static const wchar_t charset2uni[256] = { diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 828a889..8c568a0 100644 --- a/fs/notify/dnotify/dnotify.c @@ -1632557,6 +1710214,34 @@ index 23bf684..1caa0ef 100644 */ void __mark_mft_record_dirty(ntfs_inode *ni) { +diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c +index abaaa1c..80b0477 100644 +--- a/fs/ntfs/super.c ++++ b/fs/ntfs/super.c +@@ -201,8 +201,7 @@ use_utf8: + v, old_nls->charset); + nls_map = old_nls; + } else /* nls_map */ { +- if (old_nls) +- unload_nls(old_nls); ++ unload_nls(old_nls); + } + } else if (!strcmp(p, "utf8")) { + bool val = false; +@@ -2427,10 +2426,9 @@ static void ntfs_put_super(struct super_block *sb) + ntfs_free(vol->upcase); + vol->upcase = NULL; + } +- if (vol->nls_map) { +- unload_nls(vol->nls_map); +- vol->nls_map = NULL; +- } ++ ++ unload_nls(vol->nls_map); ++ + sb->s_fs_info = NULL; + kfree(vol); + diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index 0159607..31f25ce 100644 --- a/fs/ocfs2/Makefile @@ -1637038,11 +1714723,43 @@ index b358f3b..28c3ec2 100644 out: ocfs2_schedule_truncate_log_flush(osb, 1); ocfs2_run_deallocs(osb, &dealloc); +diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c +index 81eff8e..01cf8cc 100644 +--- a/fs/ocfs2/dlm/dlmast.c ++++ b/fs/ocfs2/dlm/dlmast.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c +index 75997b4..ca96bce 100644 +--- a/fs/ocfs2/dlm/dlmconvert.c ++++ b/fs/ocfs2/dlm/dlmconvert.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c -index df52f70..c5c8812 100644 +index df52f70..ca46002 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c -@@ -683,7 +683,7 @@ static int lockres_seq_show(struct seq_file *s, void *v) +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -683,7 +682,7 @@ static int lockres_seq_show(struct seq_file *s, void *v) return 0; } @@ -1637051,6 +1714768,18 @@ index df52f70..c5c8812 100644 .start = lockres_seq_start, .stop = lockres_seq_stop, .next = lockres_seq_next, +diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c +index 4d9e6b2..0334000 100644 +--- a/fs/ocfs2/dlm/dlmdomain.c ++++ b/fs/ocfs2/dlm/dlmdomain.c +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 1c9efb4..02bf178 100644 --- a/fs/ocfs2/dlm/dlmfs.c @@ -1637063,11 +1714792,55 @@ index 1c9efb4..02bf178 100644 .ra_pages = 0, /* No readahead */ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, }; +diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c +index 83a9f29..437698e 100644 +--- a/fs/ocfs2/dlm/dlmlock.c ++++ b/fs/ocfs2/dlm/dlmlock.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c +index f8b653f..83bcaf2 100644 +--- a/fs/ocfs2/dlm/dlmmaster.c ++++ b/fs/ocfs2/dlm/dlmmaster.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c +index 43e6e32..d9fa3d2 100644 +--- a/fs/ocfs2/dlm/dlmrecovery.c ++++ b/fs/ocfs2/dlm/dlmrecovery.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c -index d490b66..98569e8 100644 +index d490b66..52ec020 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c -@@ -212,14 +212,18 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -212,14 +211,18 @@ static int dlm_purge_lockres(struct dlm_ctxt *dlm, spin_lock(&dlm->spinlock); } @@ -1637087,6 +1714860,18 @@ index d490b66..98569e8 100644 __dlm_unhash_lockres(res); /* lockres is not in the hash now. drop the flag and wake up +diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c +index 756f5b0..00f53b2 100644 +--- a/fs/ocfs2/dlm/dlmunlock.c ++++ b/fs/ocfs2/dlm/dlmunlock.c +@@ -30,7 +30,6 @@ + #include + #include + #include +-#include + #include + #include + #include diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 110bb57..0d38d67 100644 --- a/fs/ocfs2/dlmglue.c @@ -1644056,10 +1721841,18 @@ index 73a16d4..c30b644 100644 ret = num_free_extents; mlog_errno(ret); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c -index a3f8871..24feb44 100644 +index a3f8871..4cc3c89 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c -@@ -69,6 +69,7 @@ +@@ -28,7 +28,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -69,6 +68,7 @@ #include "ver.h" #include "xattr.h" #include "quota.h" @@ -1644067,7 +1721860,7 @@ index a3f8871..24feb44 100644 #include "buffer_head_io.h" -@@ -965,7 +966,7 @@ static int ocfs2_quota_off(struct super_block *sb, int type, int remount) +@@ -965,7 +965,7 @@ static int ocfs2_quota_off(struct super_block *sb, int type, int remount) return vfs_quota_disable(sb, type, DQUOT_LIMITS_ENABLED); } @@ -1644076,7 +1721869,7 @@ index a3f8871..24feb44 100644 .quota_on = ocfs2_quota_on, .quota_off = ocfs2_quota_off, .quota_sync = vfs_quota_sync, -@@ -1668,8 +1669,6 @@ static void ocfs2_inode_init_once(void *data) +@@ -1668,8 +1668,6 @@ static void ocfs2_inode_init_once(void *data) spin_lock_init(&oi->ip_lock); ocfs2_extent_map_init(&oi->vfs_inode); INIT_LIST_HEAD(&oi->ip_io_markers); @@ -1644085,7 +1721878,7 @@ index a3f8871..24feb44 100644 oi->ip_dir_start_lookup = 0; init_rwsem(&oi->ip_alloc_sem); -@@ -1683,7 +1682,8 @@ static void ocfs2_inode_init_once(void *data) +@@ -1683,7 +1681,8 @@ static void ocfs2_inode_init_once(void *data) ocfs2_lock_res_init_once(&oi->ip_inode_lockres); ocfs2_lock_res_init_once(&oi->ip_open_lockres); @@ -1644095,7 +1721888,7 @@ index a3f8871..24feb44 100644 inode_init_once(&oi->vfs_inode); } -@@ -1859,6 +1859,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) +@@ -1859,6 +1858,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) ocfs2_sync_blockdev(sb); @@ -1644104,7 +1721897,7 @@ index a3f8871..24feb44 100644 /* No cluster connection means we've failed during mount, so skip * all the steps which depended on that to complete. */ if (osb->cconn) { -@@ -2065,6 +2067,8 @@ static int ocfs2_initialize_super(struct super_block *sb, +@@ -2065,6 +2066,8 @@ static int ocfs2_initialize_super(struct super_block *sb, goto bail; } @@ -1644113,7 +1721906,7 @@ index a3f8871..24feb44 100644 osb->s_feature_compat = le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_compat); osb->s_feature_ro_compat = -@@ -2490,7 +2494,8 @@ void __ocfs2_abort(struct super_block* sb, +@@ -2490,7 +2493,8 @@ void __ocfs2_abort(struct super_block* sb, /* Force a panic(). This stinks, but it's better than letting * things continue without having a proper hard readonly * here. */ @@ -1644123,6 +1721916,18 @@ index a3f8871..24feb44 100644 ocfs2_handle_error(sb); } +diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c +index 579dd1b..e342103 100644 +--- a/fs/ocfs2/symlink.c ++++ b/fs/ocfs2/symlink.c +@@ -38,7 +38,6 @@ + #include + #include + #include +-#include + #include + + #define MLOG_MASK_PREFIX ML_NAMEI diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c index 187b99f..b6284f2 100644 --- a/fs/ocfs2/uptodate.c @@ -1648452,6 +1726257,19 @@ index 2707c6c..2281c2c 100644 /* * compound pages: export both head/tail info +diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c +index 9b1e4e9..f667e8a 100644 +--- a/fs/proc/proc_sysctl.c ++++ b/fs/proc/proc_sysctl.c +@@ -153,7 +153,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, + + /* careful: calling conventions are nasty here */ + res = count; +- error = table->proc_handler(table, write, filp, buf, &res, ppos); ++ error = table->proc_handler(table, write, buf, &res, ppos); + if (!error) + error = res; + out: diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 9bd8be1..2a1bef9 100644 --- a/fs/proc/task_mmu.c @@ -1649083,6 +1726901,43 @@ index 38f7bd5..39b49c4 100644 .quota_on = vfs_quota_on, .quota_off = vfs_quota_off, .quota_sync = vfs_quota_sync, +diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c +index 11f0c06..32fae40 100644 +--- a/fs/ramfs/file-nommu.c ++++ b/fs/ramfs/file-nommu.c +@@ -69,14 +69,11 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) + /* make various checks */ + order = get_order(newsize); + if (unlikely(order >= MAX_ORDER)) +- goto too_big; ++ return -EFBIG; + +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && newsize > limit) +- goto fsize_exceeded; +- +- if (newsize > inode->i_sb->s_maxbytes) +- goto too_big; ++ ret = inode_newsize_ok(inode, newsize); ++ if (ret) ++ return ret; + + i_size_write(inode, newsize); + +@@ -118,12 +115,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) + + return 0; + +- fsize_exceeded: +- send_sig(SIGXFSZ, current, 0); +- too_big: +- return -EFBIG; +- +- add_error: ++add_error: + while (loop < npages) + __free_page(pages + loop++); + return ret; diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 0ff7566..a6090aa 100644 --- a/fs/ramfs/inode.c @@ -1649109,7 +1726964,7 @@ index 0ff7566..a6090aa 100644 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY | diff --git a/fs/read_write.c b/fs/read_write.c -index 6c8c55d..c7479e9 100644 +index 6c8c55d..0ddf162 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -293,7 +293,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) @@ -1649142,6 +1726997,16 @@ index 6c8c55d..c7479e9 100644 } return ret; } +@@ -839,9 +839,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, + max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes); + + pos = *ppos; +- retval = -EINVAL; +- if (unlikely(pos < 0)) +- goto fput_out; + if (unlikely(pos + count > max)) { + retval = -EOVERFLOW; + if (pos >= max) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 7adea74..f0ad05f 100644 --- a/fs/reiserfs/super.c @@ -1649165,7 +1727030,7 @@ index 7adea74..f0ad05f 100644 .quota_off = vfs_quota_off, .quota_sync = vfs_quota_sync, diff --git a/fs/romfs/super.c b/fs/romfs/super.c -index 4ab3c03..47f132d 100644 +index 4ab3c03..c117fa8 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -284,7 +284,7 @@ static const struct file_operations romfs_dir_operations = { @@ -1649177,6 +1727042,15 @@ index 4ab3c03..47f132d 100644 .lookup = romfs_lookup, }; +@@ -528,7 +528,7 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) + pos = (ROMFH_SIZE + len + 1 + ROMFH_PAD) & ROMFH_MASK; + + root = romfs_iget(sb, pos); +- if (!root) ++ if (IS_ERR(root)) + goto error; + + sb->s_root = d_alloc_root(root); diff --git a/fs/select.c b/fs/select.c index 8084834..a201fc3 100644 --- a/fs/select.c @@ -1649214,6 +1727088,139 @@ index 8084834..a201fc3 100644 return slack; } +diff --git a/fs/seq_file.c b/fs/seq_file.c +index 6c95927..eae7d9d 100644 +--- a/fs/seq_file.c ++++ b/fs/seq_file.c +@@ -429,20 +429,21 @@ EXPORT_SYMBOL(mangle_path); + */ + int seq_path(struct seq_file *m, struct path *path, char *esc) + { +- if (m->count < m->size) { +- char *s = m->buf + m->count; +- char *p = d_path(path, s, m->size - m->count); ++ char *buf; ++ size_t size = seq_get_buf(m, &buf); ++ int res = -1; ++ ++ if (size) { ++ char *p = d_path(path, buf, size); + if (!IS_ERR(p)) { +- s = mangle_path(s, p, esc); +- if (s) { +- p = m->buf + m->count; +- m->count = s - m->buf; +- return s - p; +- } ++ char *end = mangle_path(buf, p, esc); ++ if (end) ++ res = end - buf; + } + } +- m->count = m->size; +- return -1; ++ seq_commit(m, res); ++ ++ return res; + } + EXPORT_SYMBOL(seq_path); + +@@ -454,26 +455,28 @@ EXPORT_SYMBOL(seq_path); + int seq_path_root(struct seq_file *m, struct path *path, struct path *root, + char *esc) + { +- int err = -ENAMETOOLONG; +- if (m->count < m->size) { +- char *s = m->buf + m->count; ++ char *buf; ++ size_t size = seq_get_buf(m, &buf); ++ int res = -ENAMETOOLONG; ++ ++ if (size) { + char *p; + + spin_lock(&dcache_lock); +- p = __d_path(path, root, s, m->size - m->count); ++ p = __d_path(path, root, buf, size); + spin_unlock(&dcache_lock); +- err = PTR_ERR(p); ++ res = PTR_ERR(p); + if (!IS_ERR(p)) { +- s = mangle_path(s, p, esc); +- if (s) { +- p = m->buf + m->count; +- m->count = s - m->buf; +- return 0; +- } ++ char *end = mangle_path(buf, p, esc); ++ if (end) ++ res = end - buf; ++ else ++ res = -ENAMETOOLONG; + } + } +- m->count = m->size; +- return err; ++ seq_commit(m, res); ++ ++ return res < 0 ? res : 0; + } + + /* +@@ -481,20 +484,21 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, + */ + int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc) + { +- if (m->count < m->size) { +- char *s = m->buf + m->count; +- char *p = dentry_path(dentry, s, m->size - m->count); ++ char *buf; ++ size_t size = seq_get_buf(m, &buf); ++ int res = -1; ++ ++ if (size) { ++ char *p = dentry_path(dentry, buf, size); + if (!IS_ERR(p)) { +- s = mangle_path(s, p, esc); +- if (s) { +- p = m->buf + m->count; +- m->count = s - m->buf; +- return s - p; +- } ++ char *end = mangle_path(buf, p, esc); ++ if (end) ++ res = end - buf; + } + } +- m->count = m->size; +- return -1; ++ seq_commit(m, res); ++ ++ return res; + } + + int seq_bitmap(struct seq_file *m, const unsigned long *bits, +diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c +index 1402d2d..1c4c8f0 100644 +--- a/fs/smbfs/inode.c ++++ b/fs/smbfs/inode.c +@@ -459,14 +459,8 @@ smb_show_options(struct seq_file *s, struct vfsmount *m) + static void + smb_unload_nls(struct smb_sb_info *server) + { +- if (server->remote_nls) { +- unload_nls(server->remote_nls); +- server->remote_nls = NULL; +- } +- if (server->local_nls) { +- unload_nls(server->local_nls); +- server->local_nls = NULL; +- } ++ unload_nls(server->remote_nls); ++ unload_nls(server->local_nls); + } + + static void diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index 9468168..71c29b6 100644 --- a/fs/smbfs/proc.c @@ -1649310,7 +1727317,7 @@ index cb5fc57..6c197ef 100644 .destroy_inode = squashfs_destroy_inode, .statfs = squashfs_statfs, diff --git a/fs/super.c b/fs/super.c -index 2761d3e..0e7207b 100644 +index 2761d3e..19eb70b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -54,7 +54,7 @@ DEFINE_SPINLOCK(sb_lock); @@ -1649341,7 +1727348,73 @@ index 2761d3e..0e7207b 100644 { spin_lock(&sb_lock); __put_super(sb); -@@ -710,6 +707,12 @@ static int set_bdev_super(struct super_block *s, void *data) +@@ -468,6 +465,48 @@ rescan: + } + + EXPORT_SYMBOL(get_super); ++ ++/** ++ * get_active_super - get an active reference to the superblock of a device ++ * @bdev: device to get the superblock for ++ * ++ * Scans the superblock list and finds the superblock of the file system ++ * mounted on the device given. Returns the superblock with an active ++ * reference and s_umount held exclusively or %NULL if none was found. ++ */ ++struct super_block *get_active_super(struct block_device *bdev) ++{ ++ struct super_block *sb; ++ ++ if (!bdev) ++ return NULL; ++ ++ spin_lock(&sb_lock); ++ list_for_each_entry(sb, &super_blocks, s_list) { ++ if (sb->s_bdev != bdev) ++ continue; ++ ++ sb->s_count++; ++ spin_unlock(&sb_lock); ++ down_write(&sb->s_umount); ++ if (sb->s_root) { ++ spin_lock(&sb_lock); ++ if (sb->s_count > S_BIAS) { ++ atomic_inc(&sb->s_active); ++ sb->s_count--; ++ spin_unlock(&sb_lock); ++ return sb; ++ } ++ spin_unlock(&sb_lock); ++ } ++ up_write(&sb->s_umount); ++ put_super(sb); ++ yield(); ++ spin_lock(&sb_lock); ++ } ++ spin_unlock(&sb_lock); ++ return NULL; ++} + + struct super_block * user_get_super(dev_t dev) + { +@@ -530,11 +569,15 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) + { + int retval; + int remount_rw; +- ++ ++ if (sb->s_frozen != SB_UNFROZEN) ++ return -EBUSY; ++ + #ifdef CONFIG_BLOCK + if (!(flags & MS_RDONLY) && bdev_read_only(sb->s_bdev)) + return -EACCES; + #endif ++ + if (flags & MS_RDONLY) + acct_auto_close(sb); + shrink_dcache_sb(sb); +@@ -710,6 +753,12 @@ static int set_bdev_super(struct super_block *s, void *data) { s->s_bdev = data; s->s_dev = s->s_bdev->bd_dev; @@ -1649354,6 +1727427,40 @@ index 2761d3e..0e7207b 100644 return 0; } +@@ -740,9 +789,14 @@ int get_sb_bdev(struct file_system_type *fs_type, + * will protect the lockfs code from trying to start a snapshot + * while we are mounting + */ +- down(&bdev->bd_mount_sem); ++ mutex_lock(&bdev->bd_fsfreeze_mutex); ++ if (bdev->bd_fsfreeze_count > 0) { ++ mutex_unlock(&bdev->bd_fsfreeze_mutex); ++ error = -EBUSY; ++ goto error_bdev; ++ } + s = sget(fs_type, test_bdev_super, set_bdev_super, bdev); +- up(&bdev->bd_mount_sem); ++ mutex_unlock(&bdev->bd_fsfreeze_mutex); + if (IS_ERR(s)) + goto error_s; + +@@ -889,6 +943,16 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void + if (error) + goto out_sb; + ++ /* ++ * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE ++ * but s_maxbytes was an unsigned long long for many releases. Throw ++ * this warning for a little while to try and catch filesystems that ++ * violate this rule. This warning should be either removed or ++ * converted to a BUG() in 2.6.34. ++ */ ++ WARN((mnt->mnt_sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " ++ "negative value (%lld)\n", type->name, mnt->mnt_sb->s_maxbytes); ++ + mnt->mnt_mountpoint = mnt->mnt_root; + mnt->mnt_parent = mnt; + up_write(&mnt->mnt_sb->s_umount); diff --git a/fs/sync.c b/fs/sync.c index 3422ba6..d104591 100644 --- a/fs/sync.c @@ -1651757,6 +1729864,27 @@ index 5912060..27920eb 100644 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag, struct xfs_inode *ip); +diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c +index 916c0ff..c5bc67c 100644 +--- a/fs/xfs/linux-2.6/xfs_sysctl.c ++++ b/fs/xfs/linux-2.6/xfs_sysctl.c +@@ -26,7 +26,6 @@ STATIC int + xfs_stats_clear_proc_handler( + ctl_table *ctl, + int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, + loff_t *ppos) +@@ -34,7 +33,7 @@ xfs_stats_clear_proc_handler( + int c, ret, *valp = ctl->data; + __uint32_t vn_active; + +- ret = proc_dointvec_minmax(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); + + if (!ret && write && *valp) { + printk("XFS Clearing xfsstats\n"); diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c index 21b08c0..83e7ea3 100644 --- a/fs/xfs/quota/xfs_qm_stats.c @@ -1654029,7 +1732157,7 @@ index 492d75b..a434f28 100644 if (error == ENOSPC) { /* No space at all so try a "no-allocation" reservation */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h -index c65e4ce..1cef139 100644 +index c65e4ce..670f7f3 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -30,8 +30,6 @@ @@ -1654041,7 +1732169,15 @@ index c65e4ce..1cef139 100644 /* TBD: Make dynamic */ #define ACPI_MAX_HANDLES 10 struct acpi_handle_list { -@@ -89,7 +87,6 @@ struct acpi_device; +@@ -72,7 +70,6 @@ enum acpi_bus_device_type { + ACPI_BUS_TYPE_POWER, + ACPI_BUS_TYPE_PROCESSOR, + ACPI_BUS_TYPE_THERMAL, +- ACPI_BUS_TYPE_SYSTEM, + ACPI_BUS_TYPE_POWER_BUTTON, + ACPI_BUS_TYPE_SLEEP_BUTTON, + ACPI_BUS_DEVICE_TYPE_COUNT +@@ -89,7 +86,6 @@ struct acpi_device; typedef int (*acpi_op_add) (struct acpi_device * device); typedef int (*acpi_op_remove) (struct acpi_device * device, int type); typedef int (*acpi_op_start) (struct acpi_device * device); @@ -1654049,7 +1732185,7 @@ index c65e4ce..1cef139 100644 typedef int (*acpi_op_suspend) (struct acpi_device * device, pm_message_t state); typedef int (*acpi_op_resume) (struct acpi_device * device); -@@ -106,7 +103,6 @@ struct acpi_device_ops { +@@ -106,7 +102,6 @@ struct acpi_device_ops { acpi_op_add add; acpi_op_remove remove; acpi_op_start start; @@ -1654057,7 +1732193,7 @@ index c65e4ce..1cef139 100644 acpi_op_suspend suspend; acpi_op_resume resume; acpi_op_bind bind; -@@ -173,17 +169,15 @@ struct acpi_device_dir { +@@ -173,17 +168,15 @@ struct acpi_device_dir { typedef char acpi_bus_id[8]; typedef unsigned long acpi_bus_address; @@ -1654078,7 +1732214,7 @@ index c65e4ce..1cef139 100644 acpi_device_name device_name; /* Driver-determined */ acpi_device_class device_class; /* " */ }; -@@ -248,7 +242,6 @@ struct acpi_device_perf { +@@ -248,7 +241,6 @@ struct acpi_device_perf { /* Wakeup Management */ struct acpi_device_wakeup_flags { u8 valid:1; /* Can successfully enable wakeup? */ @@ -1654086,7 +1732222,7 @@ index c65e4ce..1cef139 100644 u8 run_wake:1; /* Run-Wake GPE devices */ }; -@@ -263,6 +256,7 @@ struct acpi_device_wakeup { +@@ -263,12 +255,14 @@ struct acpi_device_wakeup { struct acpi_handle_list resources; struct acpi_device_wakeup_state state; struct acpi_device_wakeup_flags flags; @@ -1654094,6 +1732230,14 @@ index c65e4ce..1cef139 100644 }; /* Device */ + + struct acpi_device { +- acpi_handle handle; ++ int device_type; ++ acpi_handle handle; /* no handle for fixed hardware */ + struct acpi_device *parent; + struct list_head children; + struct list_head node; @@ -314,7 +308,7 @@ struct acpi_bus_event { extern struct kobject *acpi_kobj; @@ -1654103,16 +1732247,18 @@ index c65e4ce..1cef139 100644 int acpi_bus_get_private_data(acpi_handle, void **); extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); extern int register_acpi_notifier(struct notifier_block *); -@@ -327,7 +321,7 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); +@@ -327,7 +321,9 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); */ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); -void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); +void acpi_bus_data_handler(acpi_handle handle, void *context); ++acpi_status acpi_bus_get_status_handle(acpi_handle handle, ++ unsigned long long *sta); int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); -@@ -356,7 +350,6 @@ void acpi_remove_dir(struct acpi_device *); +@@ -356,7 +352,6 @@ void acpi_remove_dir(struct acpi_device *); /* * Bind physical devices with ACPI devices */ @@ -1654120,7 +1732266,7 @@ index c65e4ce..1cef139 100644 struct acpi_bus_type { struct list_head list; struct bus_type *bus; -@@ -369,10 +362,26 @@ int register_acpi_bus_type(struct acpi_bus_type *); +@@ -369,10 +364,26 @@ int register_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *); struct device *acpi_get_physical_device(acpi_handle); @@ -1656629,6 +1734775,37 @@ index 37ba576..153f12d 100644 /* Context structs for address space handlers */ struct acpi_pci_id { +diff --git a/include/acpi/button.h b/include/acpi/button.h +new file mode 100644 +index 0000000..97eea0e +--- /dev/null ++++ b/include/acpi/button.h +@@ -0,0 +1,25 @@ ++#ifndef ACPI_BUTTON_H ++#define ACPI_BUTTON_H ++ ++#include ++ ++#if defined(CONFIG_ACPI_BUTTON) || defined(CONFIG_ACPI_BUTTON_MODULE) ++extern int acpi_lid_notifier_register(struct notifier_block *nb); ++extern int acpi_lid_notifier_unregister(struct notifier_block *nb); ++extern int acpi_lid_open(void); ++#else ++static inline int acpi_lid_notifier_register(struct notifier_block *nb) ++{ ++ return 0; ++} ++static inline int acpi_lid_notifier_unregister(struct notifier_block *nb) ++{ ++ return 0; ++} ++static inline int acpi_lid_open(void) ++{ ++ return 1; ++} ++#endif /* defined(CONFIG_ACPI_BUTTON) || defined(CONFIG_ACPI_BUTTON_MODULE) */ ++ ++#endif /* ACPI_BUTTON_H */ diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h index 935c5d7..6aadbf8 100644 --- a/include/acpi/platform/acgcc.h @@ -1656751,6 +1734928,30 @@ index 5406a60..e694263 100644 } #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, NULL) +diff --git a/include/asm-generic/fcntl.h b/include/asm-generic/fcntl.h +index 4d3e483..0c3dd86 100644 +--- a/include/asm-generic/fcntl.h ++++ b/include/asm-generic/fcntl.h +@@ -73,6 +73,19 @@ + #define F_SETSIG 10 /* for sockets. */ + #define F_GETSIG 11 /* for sockets. */ + #endif ++#ifndef F_SETOWN_EX ++#define F_SETOWN_EX 12 ++#define F_GETOWN_EX 13 ++#endif ++ ++#define F_OWNER_TID 0 ++#define F_OWNER_PID 1 ++#define F_OWNER_GID 2 ++ ++struct f_owner_ex { ++ int type; ++ pid_t pid; ++}; + + /* for F_[GET|SET]FL */ + #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index d6c379d..9cca378 100644 --- a/include/asm-generic/gpio.h @@ -1658342,6 +1736543,18 @@ index ae304cc..1f90841 100644 struct drm_mode_get_connector { +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 8535084..3f6e545 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -552,6 +552,7 @@ + {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x2e32, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ ++ {0x8086, 0x2e42, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0xa001, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0xa011, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ + {0x8086, 0x35e8, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, 0xffff00, 0}, \ diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h new file mode 100644 index 0000000..1d8e033 @@ -1658360,6 +1736573,48 @@ index 0000000..1d8e033 +extern void drm_class_device_unregister(struct device *dev); + +#endif +diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h +index 8e1e925..7e0cb1d 100644 +--- a/include/drm/i915_drm.h ++++ b/include/drm/i915_drm.h +@@ -185,6 +185,7 @@ typedef struct _drm_i915_sarea { + #define DRM_I915_GEM_GET_APERTURE 0x23 + #define DRM_I915_GEM_MMAP_GTT 0x24 + #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 ++#define DRM_I915_GEM_MADVISE 0x26 + + #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) + #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) +@@ -221,6 +222,7 @@ typedef struct _drm_i915_sarea { + #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) + #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) + #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id) ++#define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) + + /* Allow drivers to submit batchbuffers directly to hardware, relying + * on the security mechanisms provided by hardware. +@@ -667,4 +669,21 @@ struct drm_i915_get_pipe_from_crtc_id { + __u32 pipe; + }; + ++#define I915_MADV_WILLNEED 0 ++#define I915_MADV_DONTNEED 1 ++#define __I915_MADV_PURGED 2 /* internal state */ ++ ++struct drm_i915_gem_madvise { ++ /** Handle of the buffer to change the backing store advice */ ++ __u32 handle; ++ ++ /* Advice: either the buffer will be needed again in the near future, ++ * or wont be and could be discarded under memory pressure. ++ */ ++ __u32 madv; ++ ++ /** Whether the backing store still exists. */ ++ __u32 retained; ++}; ++ + #endif /* _I915_DRM_H_ */ diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 2ba61e1..3b9932a 100644 --- a/include/drm/radeon_drm.h @@ -1659490,6 +1737745,44 @@ index 1d52425..0ee33c2 100644 +} + #endif /* _LINUX_BACKING_DEV_H */ +diff --git a/include/linux/backlight.h b/include/linux/backlight.h +index 79ca2da..0f5f578 100644 +--- a/include/linux/backlight.h ++++ b/include/linux/backlight.h +@@ -27,6 +27,11 @@ + * Any other use of the locks below is probably wrong. + */ + ++enum backlight_update_reason { ++ BACKLIGHT_UPDATE_HOTKEY, ++ BACKLIGHT_UPDATE_SYSFS, ++}; ++ + struct backlight_device; + struct fb_info; + +@@ -100,6 +105,8 @@ static inline void backlight_update_status(struct backlight_device *bd) + extern struct backlight_device *backlight_device_register(const char *name, + struct device *dev, void *devdata, struct backlight_ops *ops); + extern void backlight_device_unregister(struct backlight_device *bd); ++extern void backlight_force_update(struct backlight_device *bd, ++ enum backlight_update_reason reason); + + #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) + +diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h +index 2046b5b..aece486 100644 +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -120,7 +120,7 @@ extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); + extern int prepare_bprm_creds(struct linux_binprm *bprm); + extern void install_exec_creds(struct linux_binprm *bprm); + extern void do_coredump(long signr, int exit_code, struct pt_regs *regs); +-extern int set_binfmt(struct linux_binfmt *new); ++extern void set_binfmt(struct linux_binfmt *new); + extern void free_bprm(struct linux_binprm *); + + #endif /* __KERNEL__ */ diff --git a/include/linux/bio.h b/include/linux/bio.h index 2892b71..5be93f1 100644 --- a/include/linux/bio.h @@ -1659836,6 +1738129,92 @@ index c302110..c8f2a5f 100644 */ #ifndef _LINUX_CAPABILITY_H +diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h +index 90bba9e..b62bb92 100644 +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -141,6 +141,38 @@ enum { + CGRP_WAIT_ON_RMDIR, + }; + ++/* which pidlist file are we talking about? */ ++enum cgroup_filetype { ++ CGROUP_FILE_PROCS, ++ CGROUP_FILE_TASKS, ++}; ++ ++/* ++ * A pidlist is a list of pids that virtually represents the contents of one ++ * of the cgroup files ("procs" or "tasks"). We keep a list of such pidlists, ++ * a pair (one each for procs, tasks) for each pid namespace that's relevant ++ * to the cgroup. ++ */ ++struct cgroup_pidlist { ++ /* ++ * used to find which pidlist is wanted. doesn't change as long as ++ * this particular list stays in the list. ++ */ ++ struct { enum cgroup_filetype type; struct pid_namespace *ns; } key; ++ /* array of xids */ ++ pid_t *list; ++ /* how many elements the above list has */ ++ int length; ++ /* how many files are using the current array */ ++ int use_count; ++ /* each of these stored in a list by its cgroup */ ++ struct list_head links; ++ /* pointer to the cgroup we belong to, for list removal purposes */ ++ struct cgroup *owner; ++ /* protects the other fields */ ++ struct rw_semaphore mutex; ++}; ++ + struct cgroup { + unsigned long flags; /* "unsigned long" so bitops work */ + +@@ -179,11 +211,12 @@ struct cgroup { + */ + struct list_head release_list; + +- /* pids_mutex protects pids_list and cached pid arrays. */ +- struct rw_semaphore pids_mutex; +- +- /* Linked list of struct cgroup_pids */ +- struct list_head pids_list; ++ /* ++ * list of pidlists, up to two for each namespace (one for procs, one ++ * for tasks); created on demand. ++ */ ++ struct list_head pidlists; ++ struct mutex pidlist_mutex; + + /* For RCU-protected deletion */ + struct rcu_head rcu_head; +@@ -227,6 +260,9 @@ struct css_set { + * during subsystem registration (at boot time). + */ + struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; ++ ++ /* For RCU-protected deletion */ ++ struct rcu_head rcu_head; + }; + + /* +@@ -389,10 +425,11 @@ struct cgroup_subsys { + struct cgroup *cgrp); + int (*pre_destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); + void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cgrp); +- int (*can_attach)(struct cgroup_subsys *ss, +- struct cgroup *cgrp, struct task_struct *tsk); ++ int (*can_attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, ++ struct task_struct *tsk, bool threadgroup); + void (*attach)(struct cgroup_subsys *ss, struct cgroup *cgrp, +- struct cgroup *old_cgrp, struct task_struct *tsk); ++ struct cgroup *old_cgrp, struct task_struct *tsk, ++ bool threadgroup); + void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); + void (*exit)(struct cgroup_subsys *ss, struct task_struct *task); + int (*populate)(struct cgroup_subsys *ss, diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 1219be4..9ea40ff 100644 --- a/include/linux/clocksource.h @@ -1660079,6 +1738458,21 @@ index b8125b2..47dac5e 100644 static inline void proc_exit_connector(struct task_struct *task) {} #endif /* CONFIG_PROC_EVENTS */ +diff --git a/include/linux/configfs.h b/include/linux/configfs.h +index 7f62777..ddb7a97 100644 +--- a/include/linux/configfs.h ++++ b/include/linux/configfs.h +@@ -27,8 +27,8 @@ + * + * configfs Copyright (C) 2005 Oracle. All rights reserved. + * +- * Please read Documentation/filesystems/configfs.txt before using the +- * configfs interface, ESPECIALLY the parts about reference counts and ++ * Please read Documentation/filesystems/configfs/configfs.txt before using ++ * the configfs interface, ESPECIALLY the parts about reference counts and + * item destructors. + */ + diff --git a/include/linux/connector.h b/include/linux/connector.h index b68d278..47ebf41 100644 --- a/include/linux/connector.h @@ -1661291,6 +1739685,19 @@ index 7d2e100..b7cdbb4 100644 +}; #endif /* __LINUX_DCBNL_H__ */ +diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h +index eb5c2ba..fc1b930 100644 +--- a/include/linux/debugfs.h ++++ b/include/linux/debugfs.h +@@ -9,7 +9,7 @@ + * 2 as published by the Free Software Foundation. + * + * debugfs is for people to use instead of /proc or /sys. +- * See Documentation/DocBook/kernel-api for more details. ++ * See Documentation/DocBook/filesystems for more details. + */ + + #ifndef _DEBUGFS_H_ diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h index f352f06..5076fe0 100644 --- a/include/linux/delayacct.h @@ -1662874,7 +1741281,7 @@ index 45ff184..1d747f7 100644 #endif /* _FLEX_ARRAY_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h -index 73e9b64..c282a6e 100644 +index 73e9b64..2adaa25 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -161,8 +161,8 @@ struct inodes_stat_t { @@ -1662896,7 +1741303,15 @@ index 73e9b64..c282a6e 100644 }; /* -@@ -655,7 +656,6 @@ struct block_device { +@@ -640,7 +641,6 @@ struct block_device { + struct super_block * bd_super; + int bd_openers; + struct mutex bd_mutex; /* open/close mutex */ +- struct semaphore bd_mount_sem; + struct list_head bd_inodes; + void * bd_holder; + int bd_holders; +@@ -655,7 +655,6 @@ struct block_device { int bd_invalidated; struct gendisk * bd_disk; struct list_head bd_list; @@ -1662904,7 +1741319,7 @@ index 73e9b64..c282a6e 100644 /* * Private data. You must have bd_claim'ed the block_device * to use this. NOTE: bd_claim allows an owner to claim -@@ -715,7 +715,7 @@ struct posix_acl; +@@ -715,7 +714,7 @@ struct posix_acl; struct inode { struct hlist_node i_hash; @@ -1662913,7 +1741328,7 @@ index 73e9b64..c282a6e 100644 struct list_head i_sb_list; struct list_head i_dentry; unsigned long i_ino; -@@ -1067,8 +1067,8 @@ struct file_lock { +@@ -1067,8 +1066,8 @@ struct file_lock { struct fasync_struct * fl_fasync; /* for lease break notifications */ unsigned long fl_break_time; /* for nonblocking lease breaks */ @@ -1662924,8 +1741339,12 @@ index 73e9b64..c282a6e 100644 union { struct nfs_lock_info nfs_fl; struct nfs4_lock_info nfs4_fl; -@@ -1319,8 +1319,8 @@ struct super_block { - unsigned long long s_maxbytes; /* Max file size */ +@@ -1316,11 +1315,11 @@ struct super_block { + unsigned long s_blocksize; + unsigned char s_blocksize_bits; + unsigned char s_dirt; +- unsigned long long s_maxbytes; /* Max file size */ ++ loff_t s_maxbytes; /* Max file size */ struct file_system_type *s_type; const struct super_operations *s_op; - struct dquot_operations *dq_op; @@ -1662935,7 +1741354,7 @@ index 73e9b64..c282a6e 100644 const struct export_operations *s_export_op; unsigned long s_flags; unsigned long s_magic; -@@ -1336,9 +1336,6 @@ struct super_block { +@@ -1336,9 +1335,6 @@ struct super_block { struct xattr_handler **s_xattr; struct list_head s_inodes; /* all inodes */ @@ -1662945,7 +1741364,7 @@ index 73e9b64..c282a6e 100644 struct hlist_head s_anon; /* anonymous dentries for (nfs) exporting */ struct list_head s_files; /* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */ -@@ -1346,6 +1343,7 @@ struct super_block { +@@ -1346,6 +1342,7 @@ struct super_block { int s_nr_dentry_unused; /* # of dentry on lru */ struct block_device *s_bdev; @@ -1662953,7 +1741372,7 @@ index 73e9b64..c282a6e 100644 struct mtd_info *s_mtd; struct list_head s_instances; struct quota_info s_dquot; /* Diskquota specific options */ -@@ -1458,11 +1456,6 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); +@@ -1458,11 +1455,6 @@ int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); #define DT_SOCK 12 #define DT_WHT 14 @@ -1662965,7 +1741384,7 @@ index 73e9b64..c282a6e 100644 /* * This is the "filldir" function type, used by readdir() to let * the kernel specify what kind of dirent layout it wants to have. -@@ -1528,6 +1521,7 @@ struct inode_operations { +@@ -1528,6 +1520,7 @@ struct inode_operations { void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); @@ -1662973,7 +1741392,7 @@ index 73e9b64..c282a6e 100644 int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); -@@ -1788,6 +1782,7 @@ extern int get_sb_pseudo(struct file_system_type *, char *, +@@ -1788,6 +1781,7 @@ extern int get_sb_pseudo(struct file_system_type *, char *, struct vfsmount *mnt); extern void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); int __put_super_and_need_restart(struct super_block *sb); @@ -1662981,7 +1741400,7 @@ index 73e9b64..c282a6e 100644 /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ -@@ -1998,12 +1993,25 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *); +@@ -1998,12 +1992,25 @@ extern void bd_release_from_disk(struct block_device *, struct gendisk *); #define CHRDEV_MAJOR_HASH_SIZE 255 extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); extern int register_chrdev_region(dev_t, unsigned, const char *); @@ -1663010,7 +1741429,7 @@ index 73e9b64..c282a6e 100644 /* fs/block_dev.c */ #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ #define BDEVT_SIZE 10 /* Largest string for MAJ:MIN for blkdev */ -@@ -2070,12 +2078,12 @@ static inline void invalidate_remote_inode(struct inode *inode) +@@ -2070,12 +2077,12 @@ static inline void invalidate_remote_inode(struct inode *inode) extern int invalidate_inode_pages2(struct address_space *mapping); extern int invalidate_inode_pages2_range(struct address_space *mapping, pgoff_t start, pgoff_t end); @@ -1663025,7 +1741444,7 @@ index 73e9b64..c282a6e 100644 extern int filemap_write_and_wait(struct address_space *mapping); extern int filemap_write_and_wait_range(struct address_space *mapping, loff_t lstart, loff_t lend); -@@ -2086,7 +2094,10 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping, +@@ -2086,7 +2093,10 @@ extern int __filemap_fdatawrite_range(struct address_space *mapping, extern int filemap_fdatawrite_range(struct address_space *mapping, loff_t start, loff_t end); @@ -1663036,6 +1741455,14 @@ index 73e9b64..c282a6e 100644 extern void sync_supers(void); extern void emergency_sync(void); extern void emergency_remount(void); +@@ -2146,6 +2156,7 @@ extern ino_t iunique(struct super_block *, ino_t); + extern int inode_needs_sync(struct inode *inode); + extern void generic_delete_inode(struct inode *inode); + extern void generic_drop_inode(struct inode *inode); ++extern int generic_detach_inode(struct inode *inode); + + extern struct inode *ilookup5_nowait(struct super_block *sb, + unsigned long hashval, int (*test)(struct inode *, void *), @@ -2186,16 +2197,15 @@ extern int bdev_read_only(struct block_device *); extern int set_blocksize(struct block_device *, int); extern int sb_set_blocksize(struct super_block *, int); @@ -1663066,6 +1741493,33 @@ index 73e9b64..c282a6e 100644 /* fs/splice.c */ extern ssize_t generic_file_splice_read(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); +@@ -2321,6 +2335,7 @@ extern void get_filesystem(struct file_system_type *fs); + extern void put_filesystem(struct file_system_type *fs); + extern struct file_system_type *get_fs_type(const char *name); + extern struct super_block *get_super(struct block_device *); ++extern struct super_block *get_active_super(struct block_device *bdev); + extern struct super_block *user_get_super(dev_t); + extern void drop_super(struct super_block *sb); + +@@ -2368,7 +2383,8 @@ extern int buffer_migrate_page(struct address_space *, + #define buffer_migrate_page NULL + #endif + +-extern int inode_change_ok(struct inode *, struct iattr *); ++extern int inode_change_ok(const struct inode *, struct iattr *); ++extern int inode_newsize_ok(const struct inode *, loff_t offset); + extern int __must_check inode_setattr(struct inode *, struct iattr *); + + extern void file_update_time(struct file *file); +@@ -2454,7 +2470,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos); + + struct ctl_table; +-int proc_nr_files(struct ctl_table *table, int write, struct file *filp, ++int proc_nr_files(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + + int __init get_filesystem_list(char *buf); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 936f9aa..c0de28b 100644 --- a/include/linux/fsnotify.h @@ -1663296,9 +1741750,27 @@ index 4d6f47b..57e503d 100644 static inline void __fsnotify_inode_delete(struct inode *inode) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h -index dc3b132..3c0924a 100644 +index dc3b132..cd3d2ab 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h +@@ -19,7 +19,7 @@ + extern int ftrace_enabled; + extern int + ftrace_enable_sysctl(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + + typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip); +@@ -94,7 +94,7 @@ static inline void ftrace_start(void) { } + extern int stack_tracer_enabled; + int + stack_trace_sysctl(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + #endif + @@ -446,7 +446,6 @@ static inline void unpause_graph_tracing(void) { } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ @@ -1663493,6 +1741965,34 @@ index cf593bf..3e2925a 100644 __u32 max_write; }; +diff --git a/include/linux/futex.h b/include/linux/futex.h +index 34956c8..8ec1799 100644 +--- a/include/linux/futex.h ++++ b/include/linux/futex.h +@@ -4,11 +4,6 @@ + #include + #include + +-struct inode; +-struct mm_struct; +-struct task_struct; +-union ktime; +- + /* Second argument to futex syscall */ + + +@@ -129,6 +124,11 @@ struct robust_list_head { + #define FUTEX_BITSET_MATCH_ANY 0xffffffff + + #ifdef __KERNEL__ ++struct inode; ++struct mm_struct; ++struct task_struct; ++union ktime; ++ + long do_futex(u32 __user *uaddr, int op, u32 val, union ktime *timeout, + u32 __user *uaddr2, u32 val2, u32 val3); + diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 45fc320..297df45 100644 --- a/include/linux/genhd.h @@ -1663929,12 +1742429,19 @@ index 4759917..ff037f0 100644 int start_pid; void *start_site; diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h -index 5cbc620..176e7ee 100644 +index 5cbc620..11ab19a 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h -@@ -24,7 +24,9 @@ int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user * - int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); - int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); +@@ -20,11 +20,13 @@ static inline int is_vm_hugetlb_page(struct vm_area_struct *vma) + } + + void reset_vma_resv_huge_pages(struct vm_area_struct *vma); +-int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); +-int hugetlb_overcommit_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); +-int hugetlb_treat_movable_handler(struct ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); ++int hugetlb_sysctl_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); ++int hugetlb_overcommit_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); ++int hugetlb_treat_movable_handler(struct ctl_table *, int, void __user *, size_t *, loff_t *); int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); -int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int); +int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, @@ -1666943,6 +1745450,34 @@ index cfdf1df..c779b49 100644 unsigned mode_support; struct net_device *dev; +diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h +index e46a073..bf9213b 100644 +--- a/include/linux/memcontrol.h ++++ b/include/linux/memcontrol.h +@@ -118,6 +118,9 @@ static inline bool mem_cgroup_disabled(void) + + extern bool mem_cgroup_oom_called(struct task_struct *task); + void mem_cgroup_update_mapped_file_stat(struct page *page, int val); ++unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, ++ gfp_t gfp_mask, int nid, ++ int zid); + #else /* CONFIG_CGROUP_MEM_RES_CTLR */ + struct mem_cgroup; + +@@ -276,6 +279,13 @@ static inline void mem_cgroup_update_mapped_file_stat(struct page *page, + { + } + ++static inline ++unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, ++ gfp_t gfp_mask, int nid, int zid) ++{ ++ return 0; ++} ++ + #endif /* CONFIG_CGROUP_MEM_CONT */ + + #endif /* _LINUX_MEMCONTROL_H */ diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index d95f72e..fed9692 100644 --- a/include/linux/memory_hotplug.h @@ -1670840,7 +1749375,7 @@ index 0521177..adaf3c1 100644 extern int misc_register(struct miscdevice * misc); diff --git a/include/linux/mm.h b/include/linux/mm.h -index 9a72cc7..dd635af 100644 +index 9a72cc7..df08551 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -25,6 +25,7 @@ extern unsigned long max_mapnr; @@ -1670907,19 +1749442,24 @@ index 9a72cc7..dd635af 100644 int shmem_zero_setup(struct vm_area_struct *); #ifndef CONFIG_MMU -@@ -793,6 +795,11 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, - extern int vmtruncate(struct inode * inode, loff_t offset); - extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end); +@@ -790,8 +792,14 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, + unmap_mapping_range(mapping, holebegin, holelen, 0); + } +-extern int vmtruncate(struct inode * inode, loff_t offset); +-extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end); ++extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new); ++extern int vmtruncate(struct inode *inode, loff_t offset); ++extern int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end); ++ +int truncate_inode_page(struct address_space *mapping, struct page *page); +int generic_error_remove_page(struct address_space *mapping, struct page *page); + +int invalidate_inode_page(struct page *page); -+ + #ifdef CONFIG_MMU extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, - unsigned long address, unsigned int flags); -@@ -815,6 +822,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -815,6 +823,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, struct page **pages, struct vm_area_struct **vmas); int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages); @@ -1670927,7 +1749467,7 @@ index 9a72cc7..dd635af 100644 extern int try_to_release_page(struct page * page, gfp_t gfp_mask); extern void do_invalidatepage(struct page *page, unsigned long offset); -@@ -1058,6 +1066,8 @@ extern void setup_per_cpu_pageset(void); +@@ -1058,6 +1067,8 @@ extern void setup_per_cpu_pageset(void); static inline void setup_per_cpu_pageset(void) {} #endif @@ -1670936,7 +1749476,7 @@ index 9a72cc7..dd635af 100644 /* nommu.c */ extern atomic_long_t mmap_pages_allocated; -@@ -1226,7 +1236,8 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address, +@@ -1226,7 +1237,8 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address, #define FOLL_WRITE 0x01 /* check pte is writable */ #define FOLL_TOUCH 0x02 /* mark page accessed */ #define FOLL_GET 0x04 /* do get_page on page */ @@ -1670946,7 +1749486,16 @@ index 9a72cc7..dd635af 100644 typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); -@@ -1303,5 +1314,12 @@ void vmemmap_populate_print_last(void); +@@ -1274,7 +1286,7 @@ int in_gate_area_no_task(unsigned long addr); + #define in_gate_area(task, addr) ({(void)task; in_gate_area_no_task(addr);}) + #endif /* __HAVE_ARCH_GATE_AREA */ + +-int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *, ++int drop_caches_sysctl_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + unsigned long shrink_slab(unsigned long scanned, gfp_t gfp_mask, + unsigned long lru_pages); +@@ -1303,5 +1315,12 @@ void vmemmap_populate_print_last(void); extern int account_locked_memory(struct mm_struct *mm, struct rlimit *rlim, size_t size); extern void refund_locked_memory(struct mm_struct *mm, size_t size); @@ -1671041,6 +1749590,33 @@ index 7fbb972..8835b87 100644 } return lru; +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 0042090..21d6aa4 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -240,6 +240,8 @@ struct mm_struct { + + unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ + ++ struct linux_binfmt *binfmt; ++ + cpumask_t cpu_vm_mask; + + /* Architecture-specific MM context */ +@@ -259,11 +261,10 @@ struct mm_struct { + unsigned long flags; /* Must use atomic bitops to access the bits */ + + struct core_state *core_state; /* coredumping support */ +- +- /* aio bits */ ++#ifdef CONFIG_AIO + spinlock_t ioctx_lock; + struct hlist_head ioctx_list; +- ++#endif + #ifdef CONFIG_MM_OWNER + /* + * "owner" points to a task that is regarded as the canonical diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 403aa50..2ee22e8 100644 --- a/include/linux/mmc/card.h @@ -1671358,7 +1749934,7 @@ index b77486d..4e02ee2 100644 #endif /* CONFIG_MMU_NOTIFIER */ diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h -index 8895985..652ef01 100644 +index 8895985..6f75617 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -38,6 +38,7 @@ @@ -1671417,6 +1749993,34 @@ index 8895985..652ef01 100644 } lru[NR_LRU_LISTS]; struct zone_reclaim_stat reclaim_stat; +@@ -744,21 +755,20 @@ static inline int is_dma(struct zone *zone) + + /* These two functions are used to setup the per zone pages min values */ + struct ctl_table; +-struct file; +-int min_free_kbytes_sysctl_handler(struct ctl_table *, int, struct file *, ++int min_free_kbytes_sysctl_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1]; +-int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *, ++int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, struct file *, ++int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + int sysctl_min_unmapped_ratio_sysctl_handler(struct ctl_table *, int, +- struct file *, void __user *, size_t *, loff_t *); ++ void __user *, size_t *, loff_t *); + int sysctl_min_slab_ratio_sysctl_handler(struct ctl_table *, int, +- struct file *, void __user *, size_t *, loff_t *); ++ void __user *, size_t *, loff_t *); + + extern int numa_zonelist_order_handler(struct ctl_table *, int, +- struct file *, void __user *, size_t *, loff_t *); ++ void __user *, size_t *, loff_t *); + extern char numa_zonelist_order[]; + #define NUMA_ZONELIST_ORDER_LEN 16 /* string buffer size */ + diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 1bf5900..f58e9d8 100644 --- a/include/linux/mod_devicetable.h @@ -1671546,11 +1750150,91 @@ index 098bdb7..482efc8 100644 static inline void module_update_tracepoints(void) { } +diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h +index fff8c53..9c3757c 100644 +--- a/include/linux/mtd/bbm.h ++++ b/include/linux/mtd/bbm.h +@@ -19,22 +19,21 @@ + + /** + * struct nand_bbt_descr - bad block table descriptor +- * @options: options for this descriptor +- * @pages: the page(s) where we find the bbt, used with +- * option BBT_ABSPAGE when bbt is searched, +- * then we store the found bbts pages here. +- * Its an array and supports up to 8 chips now +- * @offs: offset of the pattern in the oob area of the page +- * @veroffs: offset of the bbt version counter in the oob area of the page +- * @version: version read from the bbt page during scan +- * @len: length of the pattern, if 0 no pattern check is performed +- * @maxblocks: maximum number of blocks to search for a bbt. This +- * number of blocks is reserved at the end of the device +- * where the tables are written. +- * @reserved_block_code: if non-0, this pattern denotes a reserved +- * (rather than bad) block in the stored bbt +- * @pattern: pattern to identify bad block table or factory marked +- * good / bad blocks, can be NULL, if len = 0 ++ * @options: options for this descriptor ++ * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE ++ * when bbt is searched, then we store the found bbts pages here. ++ * Its an array and supports up to 8 chips now ++ * @offs: offset of the pattern in the oob area of the page ++ * @veroffs: offset of the bbt version counter in the oob are of the page ++ * @version: version read from the bbt page during scan ++ * @len: length of the pattern, if 0 no pattern check is performed ++ * @maxblocks: maximum number of blocks to search for a bbt. This number of ++ * blocks is reserved at the end of the device where the tables are ++ * written. ++ * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than ++ * bad) block in the stored bbt ++ * @pattern: pattern to identify bad block table or factory marked good / ++ * bad blocks, can be NULL, if len = 0 + * + * Descriptor for the bad block table marker and the descriptor for the + * pattern which identifies good and bad blocks. The assumption is made +@@ -90,7 +89,9 @@ struct nand_bbt_descr { + /* + * Constants for oob configuration + */ +-#define ONENAND_BADBLOCK_POS 0 ++#define NAND_SMALL_BADBLOCK_POS 5 ++#define NAND_LARGE_BADBLOCK_POS 0 ++#define ONENAND_BADBLOCK_POS 0 + + /* + * Bad block scanning errors +diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h +index d4f38c5..f350a48 100644 +--- a/include/linux/mtd/flashchip.h ++++ b/include/linux/mtd/flashchip.h +@@ -38,6 +38,13 @@ typedef enum { + FL_XIP_WHILE_ERASING, + FL_XIP_WHILE_WRITING, + FL_SHUTDOWN, ++ /* These 2 come from nand_state_t, which has been unified here */ ++ FL_READING, ++ FL_CACHEDPRG, ++ /* These 2 come from onenand_state_t, which has been unified here */ ++ FL_RESETING, ++ FL_OTPING, ++ + FL_UNKNOWN + } flstate_t; + diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h -index 4030eba..7a232a9 100644 +index 4030eba..2476078 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h -@@ -121,6 +121,7 @@ typedef enum { +@@ -21,6 +21,8 @@ + #include + #include + #include ++#include ++#include + + struct mtd_info; + /* Scan and identify a NAND device */ +@@ -121,6 +123,7 @@ typedef enum { NAND_ECC_SOFT, NAND_ECC_HW, NAND_ECC_HW_SYNDROME, @@ -1671558,7 +1750242,28 @@ index 4030eba..7a232a9 100644 } nand_ecc_modes_t; /* -@@ -271,13 +272,13 @@ struct nand_ecc_ctrl { +@@ -201,20 +204,6 @@ typedef enum { + #define NAND_CI_CHIPNR_MSK 0x03 + #define NAND_CI_CELLTYPE_MSK 0x0C + +-/* +- * nand_state_t - chip states +- * Enumeration for NAND flash chip state +- */ +-typedef enum { +- FL_READY, +- FL_READING, +- FL_WRITING, +- FL_ERASING, +- FL_SYNCING, +- FL_CACHEDPRG, +- FL_PM_SUSPENDED, +-} nand_state_t; +- + /* Keep gcc happy */ + struct nand_chip; + +@@ -271,13 +260,13 @@ struct nand_ecc_ctrl { uint8_t *calc_ecc); int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, @@ -1671574,6 +1750279,104 @@ index 4030eba..7a232a9 100644 int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip, uint32_t offs, uint32_t len, +@@ -401,7 +390,7 @@ struct nand_chip { + uint8_t cellinfo; + int badblockpos; + +- nand_state_t state; ++ flstate_t state; + + uint8_t *oob_poi; + struct nand_hw_control *controller; +@@ -469,75 +458,6 @@ struct nand_manufacturers { + extern struct nand_flash_dev nand_flash_ids[]; + extern struct nand_manufacturers nand_manuf_ids[]; + +-/** +- * struct nand_bbt_descr - bad block table descriptor +- * @options: options for this descriptor +- * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE +- * when bbt is searched, then we store the found bbts pages here. +- * Its an array and supports up to 8 chips now +- * @offs: offset of the pattern in the oob area of the page +- * @veroffs: offset of the bbt version counter in the oob are of the page +- * @version: version read from the bbt page during scan +- * @len: length of the pattern, if 0 no pattern check is performed +- * @maxblocks: maximum number of blocks to search for a bbt. This number of +- * blocks is reserved at the end of the device where the tables are +- * written. +- * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than +- * bad) block in the stored bbt +- * @pattern: pattern to identify bad block table or factory marked good / +- * bad blocks, can be NULL, if len = 0 +- * +- * Descriptor for the bad block table marker and the descriptor for the +- * pattern which identifies good and bad blocks. The assumption is made +- * that the pattern and the version count are always located in the oob area +- * of the first block. +- */ +-struct nand_bbt_descr { +- int options; +- int pages[NAND_MAX_CHIPS]; +- int offs; +- int veroffs; +- uint8_t version[NAND_MAX_CHIPS]; +- int len; +- int maxblocks; +- int reserved_block_code; +- uint8_t *pattern; +-}; +- +-/* Options for the bad block table descriptors */ +- +-/* The number of bits used per block in the bbt on the device */ +-#define NAND_BBT_NRBITS_MSK 0x0000000F +-#define NAND_BBT_1BIT 0x00000001 +-#define NAND_BBT_2BIT 0x00000002 +-#define NAND_BBT_4BIT 0x00000004 +-#define NAND_BBT_8BIT 0x00000008 +-/* The bad block table is in the last good block of the device */ +-#define NAND_BBT_LASTBLOCK 0x00000010 +-/* The bbt is at the given page, else we must scan for the bbt */ +-#define NAND_BBT_ABSPAGE 0x00000020 +-/* The bbt is at the given page, else we must scan for the bbt */ +-#define NAND_BBT_SEARCH 0x00000040 +-/* bbt is stored per chip on multichip devices */ +-#define NAND_BBT_PERCHIP 0x00000080 +-/* bbt has a version counter at offset veroffs */ +-#define NAND_BBT_VERSION 0x00000100 +-/* Create a bbt if none axists */ +-#define NAND_BBT_CREATE 0x00000200 +-/* Search good / bad pattern through all pages of a block */ +-#define NAND_BBT_SCANALLPAGES 0x00000400 +-/* Scan block empty during good / bad block scan */ +-#define NAND_BBT_SCANEMPTY 0x00000800 +-/* Write bbt if neccecary */ +-#define NAND_BBT_WRITE 0x00001000 +-/* Read and write back block contents when writing bbt */ +-#define NAND_BBT_SAVECONTENT 0x00002000 +-/* Search good / bad pattern on the first and the second page */ +-#define NAND_BBT_SCAN2NDPAGE 0x00004000 +- +-/* The maximum number of blocks to scan for a bbt */ +-#define NAND_BBT_SCAN_MAXBLOCKS 4 +- + extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); + extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); + extern int nand_default_bbt(struct mtd_info *mtd); +@@ -547,12 +467,6 @@ extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, + extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, uint8_t * buf); + +-/* +-* Constants for oob configuration +-*/ +-#define NAND_SMALL_BADBLOCK_POS 5 +-#define NAND_LARGE_BADBLOCK_POS 0 +- + /** + * struct platform_nand_chip - chip level device structure + * @nr_chips: max. number of chips to scan for diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h index 090da50..052ea8c 100644 --- a/include/linux/mtd/nand_ecc.h @@ -1671592,10 +1750395,50 @@ index 090da50..052ea8c 100644 */ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h -index 8ed8733..4e49f33 100644 +index 8ed8733..f57e29e 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h -@@ -214,4 +214,12 @@ unsigned onenand_block(struct onenand_chip *this, loff_t addr); +@@ -14,6 +14,7 @@ + + #include + #include ++#include + #include + #include + +@@ -25,22 +26,6 @@ extern int onenand_scan(struct mtd_info *mtd, int max_chips); + /* Free resources held by the OneNAND device */ + extern void onenand_release(struct mtd_info *mtd); + +-/* +- * onenand_state_t - chip states +- * Enumeration for OneNAND flash chip state +- */ +-typedef enum { +- FL_READY, +- FL_READING, +- FL_WRITING, +- FL_ERASING, +- FL_SYNCING, +- FL_LOCKING, +- FL_RESETING, +- FL_OTPING, +- FL_PM_SUSPENDED, +-} onenand_state_t; +- + /** + * struct onenand_bufferram - OneNAND BufferRAM Data + * @blockpage: block & page address in BufferRAM +@@ -137,7 +122,7 @@ struct onenand_chip { + + spinlock_t chip_lock; + wait_queue_head_t wq; +- onenand_state_t state; ++ flstate_t state; + unsigned char *page_buf; + unsigned char *oob_buf; + +@@ -214,4 +199,12 @@ unsigned onenand_block(struct onenand_chip *this, loff_t addr); loff_t onenand_addr(struct onenand_chip *this, int block); int flexonenand_region(struct mtd_info *mtd, loff_t addr); @@ -1673929,10 +1752772,42 @@ index e2e5ce5..6b202b1 100644 #endif /* PAGE_FLAGS_H */ diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h -index 13f126c..ada779f 100644 +index 13f126c..4b938d4 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h -@@ -105,14 +105,14 @@ static inline void __init page_cgroup_init_flatmem(void) +@@ -38,6 +38,7 @@ enum { + PCG_LOCK, /* page cgroup is locked */ + PCG_CACHE, /* charged as cache */ + PCG_USED, /* this object is in use. */ ++ PCG_ACCT_LRU, /* page has been accounted for */ + }; + + #define TESTPCGFLAG(uname, lname) \ +@@ -52,11 +53,23 @@ static inline void SetPageCgroup##uname(struct page_cgroup *pc)\ + static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ + { clear_bit(PCG_##lname, &pc->flags); } + ++#define TESTCLEARPCGFLAG(uname, lname) \ ++static inline int TestClearPageCgroup##uname(struct page_cgroup *pc) \ ++ { return test_and_clear_bit(PCG_##lname, &pc->flags); } ++ + /* Cache flag is set only once (at allocation) */ + TESTPCGFLAG(Cache, CACHE) ++CLEARPCGFLAG(Cache, CACHE) ++SETPCGFLAG(Cache, CACHE) + + TESTPCGFLAG(Used, USED) + CLEARPCGFLAG(Used, USED) ++SETPCGFLAG(Used, USED) ++ ++SETPCGFLAG(AcctLRU, ACCT_LRU) ++CLEARPCGFLAG(AcctLRU, ACCT_LRU) ++TESTPCGFLAG(AcctLRU, ACCT_LRU) ++TESTCLEARPCGFLAG(AcctLRU, ACCT_LRU) + + static inline int page_cgroup_nid(struct page_cgroup *pc) + { +@@ -105,14 +118,14 @@ static inline void __init page_cgroup_init_flatmem(void) #endif @@ -1677554,6 +1756429,134 @@ index 4456319..de9a7fa 100644 * @subdevs: regulator used * At most, there will be a regulator for V3 and one for V6 voltages. * @v3_gain: gain on the V3 voltage output multiplied by 1e6. +diff --git a/include/linux/relay.h b/include/linux/relay.h +index 953fc05..14a86bc 100644 +--- a/include/linux/relay.h ++++ b/include/linux/relay.h +@@ -140,7 +140,7 @@ struct rchan_callbacks + * cause relay_open() to create a single global buffer rather + * than the default set of per-cpu buffers. + * +- * See Documentation/filesystems/relayfs.txt for more info. ++ * See Documentation/filesystems/relay.txt for more info. + */ + struct dentry *(*create_buf_file)(const char *filename, + struct dentry *parent, +diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h +index 511f42f..731af71 100644 +--- a/include/linux/res_counter.h ++++ b/include/linux/res_counter.h +@@ -35,6 +35,10 @@ struct res_counter { + */ + unsigned long long limit; + /* ++ * the limit that usage can be exceed ++ */ ++ unsigned long long soft_limit; ++ /* + * the number of unsuccessful attempts to consume the resource + */ + unsigned long long failcnt; +@@ -87,6 +91,7 @@ enum { + RES_MAX_USAGE, + RES_LIMIT, + RES_FAILCNT, ++ RES_SOFT_LIMIT, + }; + + /* +@@ -109,7 +114,8 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent); + int __must_check res_counter_charge_locked(struct res_counter *counter, + unsigned long val); + int __must_check res_counter_charge(struct res_counter *counter, +- unsigned long val, struct res_counter **limit_fail_at); ++ unsigned long val, struct res_counter **limit_fail_at, ++ struct res_counter **soft_limit_at); + + /* + * uncharge - tell that some portion of the resource is released +@@ -122,7 +128,8 @@ int __must_check res_counter_charge(struct res_counter *counter, + */ + + void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val); +-void res_counter_uncharge(struct res_counter *counter, unsigned long val); ++void res_counter_uncharge(struct res_counter *counter, unsigned long val, ++ bool *was_soft_limit_excess); + + static inline bool res_counter_limit_check_locked(struct res_counter *cnt) + { +@@ -132,6 +139,36 @@ static inline bool res_counter_limit_check_locked(struct res_counter *cnt) + return false; + } + ++static inline bool res_counter_soft_limit_check_locked(struct res_counter *cnt) ++{ ++ if (cnt->usage < cnt->soft_limit) ++ return true; ++ ++ return false; ++} ++ ++/** ++ * Get the difference between the usage and the soft limit ++ * @cnt: The counter ++ * ++ * Returns 0 if usage is less than or equal to soft limit ++ * The difference between usage and soft limit, otherwise. ++ */ ++static inline unsigned long long ++res_counter_soft_limit_excess(struct res_counter *cnt) ++{ ++ unsigned long long excess; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cnt->lock, flags); ++ if (cnt->usage <= cnt->soft_limit) ++ excess = 0; ++ else ++ excess = cnt->usage - cnt->soft_limit; ++ spin_unlock_irqrestore(&cnt->lock, flags); ++ return excess; ++} ++ + /* + * Helper function to detect if the cgroup is within it's limit or + * not. It's currently called from cgroup_rss_prepare() +@@ -147,6 +184,17 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt) + return ret; + } + ++static inline bool res_counter_check_under_soft_limit(struct res_counter *cnt) ++{ ++ bool ret; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cnt->lock, flags); ++ ret = res_counter_soft_limit_check_locked(cnt); ++ spin_unlock_irqrestore(&cnt->lock, flags); ++ return ret; ++} ++ + static inline void res_counter_reset_max(struct res_counter *cnt) + { + unsigned long flags; +@@ -180,4 +228,16 @@ static inline int res_counter_set_limit(struct res_counter *cnt, + return ret; + } + ++static inline int ++res_counter_set_soft_limit(struct res_counter *cnt, ++ unsigned long long soft_limit) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cnt->lock, flags); ++ cnt->soft_limit = soft_limit; ++ spin_unlock_irqrestore(&cnt->lock, flags); ++ return 0; ++} ++ + #endif diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 278777f..3392c59 100644 --- a/include/linux/rfkill.h @@ -1677754,7 +1756757,7 @@ index f7b826b..a53915c 100644 #endif /* _LINUX_RXRPC_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h -index 0f1ea4a..992ccc3 100644 +index 0f1ea4a..1aa4574 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -38,6 +38,8 @@ @@ -1677803,14 +1756806,18 @@ index 0f1ea4a..992ccc3 100644 extern void task_rq_unlock_wait(struct task_struct *p); extern cpumask_var_t nohz_cpu_mask; -@@ -300,6 +307,7 @@ extern void sched_show_task(struct task_struct *p); +@@ -300,9 +307,10 @@ extern void sched_show_task(struct task_struct *p); #ifdef CONFIG_DETECT_SOFTLOCKUP extern void softlockup_tick(void); extern void touch_softlockup_watchdog(void); +extern void touch_softlockup_watchdog_sync(void); extern void touch_all_softlockup_watchdogs(void); extern int proc_dosoftlockup_thresh(struct ctl_table *table, int write, - struct file *filp, void __user *buffer, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos); + extern unsigned int softlockup_panic; + extern int softlockup_thresh; @@ -313,6 +321,9 @@ static inline void softlockup_tick(void) static inline void touch_softlockup_watchdog(void) { @@ -1677821,6 +1756828,15 @@ index 0f1ea4a..992ccc3 100644 static inline void touch_all_softlockup_watchdogs(void) { } +@@ -324,7 +335,7 @@ extern unsigned long sysctl_hung_task_check_count; + extern unsigned long sysctl_hung_task_timeout_secs; + extern unsigned long sysctl_hung_task_warnings; + extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos); + #endif + @@ -419,6 +430,15 @@ static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm) return max(mm->hiwater_rss, get_mm_rss(mm)); } @@ -1678111,7 +1757127,15 @@ index 0f1ea4a..992ccc3 100644 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) struct sched_info sched_info; -@@ -1230,11 +1284,19 @@ struct task_struct { +@@ -1221,7 +1275,6 @@ struct task_struct { + struct mm_struct *mm, *active_mm; + + /* task state */ +- struct linux_binfmt *binfmt; + int exit_state; + int exit_code, exit_signal; + int pdeath_signal; /* The signal sent when the parent dies */ +@@ -1230,11 +1283,19 @@ struct task_struct { unsigned did_exec:1; unsigned in_execve:1; /* Tell the LSMs that the process is doing an * execve */ @@ -1678131,7 +1757155,7 @@ index 0f1ea4a..992ccc3 100644 /* * pointers to (original) parent process, youngest child, younger sibling, -@@ -1292,6 +1354,7 @@ struct task_struct { +@@ -1292,6 +1353,7 @@ struct task_struct { struct mutex cred_guard_mutex; /* guard against foreign influences on * credential calculations * (notably. ptrace) */ @@ -1678139,7 +1757163,7 @@ index 0f1ea4a..992ccc3 100644 char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock -@@ -1424,10 +1487,10 @@ struct task_struct { +@@ -1424,10 +1486,10 @@ struct task_struct { struct list_head pi_state_list; struct futex_pi_state *pi_state_cache; #endif @@ -1678154,7 +1757178,7 @@ index 0f1ea4a..992ccc3 100644 #endif #ifdef CONFIG_NUMA struct mempolicy *mempolicy; /* Protected by alloc_lock */ -@@ -1480,6 +1543,7 @@ struct task_struct { +@@ -1480,6 +1542,7 @@ struct task_struct { /* bitmask of trace recursion */ unsigned long trace_recursion; #endif /* CONFIG_TRACING */ @@ -1678162,7 +1757186,7 @@ index 0f1ea4a..992ccc3 100644 }; /* Future-safe accessor for struct task_struct's cpus_allowed. */ -@@ -1675,6 +1739,7 @@ extern cputime_t task_gtime(struct task_struct *p); +@@ -1675,6 +1738,7 @@ extern cputime_t task_gtime(struct task_struct *p); #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ #define PF_VCPU 0x00000010 /* I'm a virtual CPU */ #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ @@ -1678170,7 +1757194,7 @@ index 0f1ea4a..992ccc3 100644 #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ #define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_SIGNALED 0x00000400 /* killed by a signal */ -@@ -1686,7 +1751,7 @@ extern cputime_t task_gtime(struct task_struct *p); +@@ -1686,7 +1750,7 @@ extern cputime_t task_gtime(struct task_struct *p); #define PF_FROZEN 0x00010000 /* frozen for system suspend */ #define PF_FSTRANS 0x00020000 /* inside a filesystem transaction */ #define PF_KSWAPD 0x00040000 /* I am kswapd */ @@ -1678179,7 +1757203,7 @@ index 0f1ea4a..992ccc3 100644 #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ -@@ -1694,6 +1759,7 @@ extern cputime_t task_gtime(struct task_struct *p); +@@ -1694,6 +1758,7 @@ extern cputime_t task_gtime(struct task_struct *p); #define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ #define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ #define PF_THREAD_BOUND 0x04000000 /* Thread bound to specific cpu */ @@ -1678187,7 +1757211,7 @@ index 0f1ea4a..992ccc3 100644 #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ #define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */ #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezeable */ -@@ -1724,6 +1790,27 @@ extern cputime_t task_gtime(struct task_struct *p); +@@ -1724,6 +1789,27 @@ extern cputime_t task_gtime(struct task_struct *p); #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) #define used_math() tsk_used_math(current) @@ -1678215,7 +1757239,7 @@ index 0f1ea4a..992ccc3 100644 #ifdef CONFIG_SMP extern int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask); -@@ -1736,10 +1823,13 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, +@@ -1736,10 +1822,13 @@ static inline int set_cpus_allowed_ptr(struct task_struct *p, return 0; } #endif @@ -1678229,7 +1757253,7 @@ index 0f1ea4a..992ccc3 100644 /* * Architectures can set this to 1 if they have specified -@@ -1813,11 +1903,12 @@ extern unsigned int sysctl_sched_min_granularity; +@@ -1813,15 +1902,16 @@ extern unsigned int sysctl_sched_min_granularity; extern unsigned int sysctl_sched_wakeup_granularity; extern unsigned int sysctl_sched_shares_ratelimit; extern unsigned int sysctl_sched_shares_thresh; @@ -1678243,6 +1757267,28 @@ index 0f1ea4a..992ccc3 100644 extern unsigned int sysctl_timer_migration; int sched_nr_latency_handler(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, ++ void __user *buffer, size_t *length, + loff_t *ppos); + #endif + #ifdef CONFIG_SCHED_DEBUG +@@ -1839,7 +1929,7 @@ extern unsigned int sysctl_sched_rt_period; + extern int sysctl_sched_rt_runtime; + + int sched_rt_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + + extern unsigned int sysctl_sched_compat_yield; +@@ -1974,6 +2064,7 @@ extern int kill_pgrp(struct pid *pid, int sig, int priv); + extern int kill_pid(struct pid *pid, int sig, int priv); + extern int kill_proc_info(int, struct siginfo *, pid_t); + extern int do_notify_parent(struct task_struct *, int); ++extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent); + extern void force_sig(int, struct task_struct *); + extern void force_sig_specific(int, struct task_struct *); + extern int send_sig(int, struct task_struct *, int); @@ -2077,7 +2168,7 @@ static inline unsigned long wait_task_inactive(struct task_struct *p, #define for_each_process(p) \ for (p = &init_task ; (p = next_task(p)) != &init_task ; ) @@ -1678252,7 +1757298,19 @@ index 0f1ea4a..992ccc3 100644 /* * Careful: do_each_thread/while_each_thread is a double loop so -@@ -2281,23 +2372,31 @@ static inline int need_resched(void) +@@ -2251,7 +2342,10 @@ static inline int signal_pending(struct task_struct *p) + return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); + } + +-extern int __fatal_signal_pending(struct task_struct *p); ++static inline int __fatal_signal_pending(struct task_struct *p) ++{ ++ return unlikely(sigismember(&p->pending.signal, SIGKILL)); ++} + + static inline int fatal_signal_pending(struct task_struct *p) + { +@@ -2281,23 +2375,31 @@ static inline int need_resched(void) * cond_resched_softirq() will enable bhs before scheduling. */ extern int _cond_resched(void); @@ -1678300,7 +1757358,7 @@ index 0f1ea4a..992ccc3 100644 /* * Does a critical section need to be broken due to another diff --git a/include/linux/security.h b/include/linux/security.h -index 1f16eea..d050b66 100644 +index 1f16eea..239e40d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -53,7 +53,7 @@ struct audit_krule; @@ -1678312,6 +1757370,15 @@ index 1f16eea..d050b66 100644 extern int cap_ptrace_traceme(struct task_struct *parent); extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern int cap_capset(struct cred *new, const struct cred *old, +@@ -133,7 +133,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) + return PAGE_ALIGN(mmap_min_addr); + return hint; + } +-extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, ++extern int mmap_min_addr_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + + #ifdef CONFIG_SECURITY @@ -653,6 +653,11 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * manual page for definitions of the @clone_flags. * @clone_flags contains the flags indicating what should be shared. @@ -1678677,6 +1757744,55 @@ index 20f965d..82e0f26 100644 #endif /* CONFIG_SECURITY_SELINUX */ #endif /* _LINUX_SELINUX_H */ +diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h +index 0c6a86b..8366d8f 100644 +--- a/include/linux/seq_file.h ++++ b/include/linux/seq_file.h +@@ -35,6 +35,44 @@ struct seq_operations { + + #define SEQ_SKIP 1 + ++/** ++ * seq_get_buf - get buffer to write arbitrary data to ++ * @m: the seq_file handle ++ * @bufp: the beginning of the buffer is stored here ++ * ++ * Return the number of bytes available in the buffer, or zero if ++ * there's no space. ++ */ ++static inline size_t seq_get_buf(struct seq_file *m, char **bufp) ++{ ++ BUG_ON(m->count > m->size); ++ if (m->count < m->size) ++ *bufp = m->buf + m->count; ++ else ++ *bufp = NULL; ++ ++ return m->size - m->count; ++} ++ ++/** ++ * seq_commit - commit data to the buffer ++ * @m: the seq_file handle ++ * @num: the number of bytes to commit ++ * ++ * Commit @num bytes of data written to a buffer previously acquired ++ * by seq_buf_get. To signal an error condition, or that the data ++ * didn't fit in the available space, pass a negative @num value. ++ */ ++static inline void seq_commit(struct seq_file *m, int num) ++{ ++ if (num < 0) { ++ m->count = m->size; ++ } else { ++ BUG_ON(m->count + num > m->size); ++ m->count += num; ++ } ++} ++ + char *mangle_path(char *s, char *p, char *esc); + int seq_open(struct file *, const struct seq_operations *); + ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); diff --git a/include/linux/serial.h b/include/linux/serial.h index e5bb75a..c8613c3 100644 --- a/include/linux/serial.h @@ -1679273,6 +1758389,19 @@ index abff6c9..deee7af 100644 int shmem_acl_init(struct inode *, struct inode *); extern struct xattr_handler shmem_xattr_acl_access_handler; +diff --git a/include/linux/signal.h b/include/linux/signal.h +index c755283..ab9272c 100644 +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -233,6 +233,8 @@ static inline int valid_signal(unsigned long sig) + } + + extern int next_signal(struct sigpending *pending, sigset_t *mask); ++extern int do_send_sig_info(int sig, struct siginfo *info, ++ struct task_struct *p, bool group); + extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); + extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); + extern long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f2c69a2..df7b23a 100644 --- a/include/linux/skbuff.h @@ -1681178,7 +1760307,7 @@ index c2a46c4..3f14a02 100644 */ extern unsigned int xprt_udp_slot_table_entries; diff --git a/include/linux/swap.h b/include/linux/swap.h -index 7c15334..e1ec8c6 100644 +index 7c15334..4ec9001 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -34,15 +34,37 @@ static inline int current_is_kswapd(void) @@ -1681225,7 +1760354,28 @@ index 7c15334..e1ec8c6 100644 /* * Magic header for a swap area. The first part of the union is * what the swap magic looks like for the old (limited to 128MB) -@@ -419,10 +441,22 @@ static inline swp_entry_t get_swap_page(void) +@@ -217,6 +239,11 @@ extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, + extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, + gfp_t gfp_mask, bool noswap, + unsigned int swappiness); ++extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, ++ gfp_t gfp_mask, bool noswap, ++ unsigned int swappiness, ++ struct zone *zone, ++ int nid); + extern int __isolate_lru_page(struct page *page, int mode, int file); + extern unsigned long shrink_all_memory(unsigned long nr_pages); + extern int vm_swappiness; +@@ -240,7 +267,7 @@ extern int page_evictable(struct page *page, struct vm_area_struct *vma); + extern void scan_mapping_unevictable_pages(struct address_space *); + + extern unsigned long scan_unevictable_pages; +-extern int scan_unevictable_handler(struct ctl_table *, int, struct file *, ++extern int scan_unevictable_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + extern int scan_unevictable_register_node(struct node *node); + extern void scan_unevictable_unregister_node(struct node *node); +@@ -419,10 +446,22 @@ static inline swp_entry_t get_swap_page(void) } /* linux/mm/thrash.c */ @@ -1681522,6 +1760672,53 @@ index 80de700..a990ace 100644 + struct perf_event_attr __user *attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags); #endif +diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h +index e76d3b2..1e4743e 100644 +--- a/include/linux/sysctl.h ++++ b/include/linux/sysctl.h +@@ -29,7 +29,6 @@ + #include + #include + +-struct file; + struct completion; + + #define CTL_MAXNAME 10 /* how many path components do we allow in a +@@ -977,25 +976,25 @@ typedef int ctl_handler (struct ctl_table *table, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen); + +-typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp, ++typedef int proc_handler (struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + +-extern int proc_dostring(struct ctl_table *, int, struct file *, ++extern int proc_dostring(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_dointvec(struct ctl_table *, int, struct file *, ++extern int proc_dointvec(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *, ++extern int proc_dointvec_minmax(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *, ++extern int proc_dointvec_jiffies(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *, ++extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *, ++extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, + void __user *, size_t *, loff_t *); +-extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *, ++extern int proc_doulongvec_minmax(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, +- struct file *, void __user *, size_t *, loff_t *); ++ void __user *, size_t *, loff_t *); + + extern int do_sysctl (int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, diff --git a/include/linux/taskstats_kern.h b/include/linux/taskstats_kern.h index 7e9680f..3398f45 100644 --- a/include/linux/taskstats_kern.h @@ -1681728,7 +1760925,7 @@ index 8afac76..61723a7 100644 #endif }; diff --git a/include/linux/time.h b/include/linux/time.h -index ea16c1a..56787c0 100644 +index ea16c1a..fe04e5e 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -75,7 +75,7 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon, @@ -1681759,7 +1760956,7 @@ index ea16c1a..56787c0 100644 #define CURRENT_TIME (current_kernel_time()) #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) -@@ -147,6 +150,7 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran); +@@ -147,10 +150,39 @@ extern struct timespec timespec_trunc(struct timespec t, unsigned gran); extern int timekeeping_valid_for_hres(void); extern void update_wall_time(void); extern void update_xtime_cache(u64 nsec); @@ -1681767,7 +1760964,39 @@ index ea16c1a..56787c0 100644 struct tms; extern void do_sys_times(struct tms *); -@@ -241,6 +245,8 @@ struct itimerval { + ++/* ++ * Similar to the struct tm in userspace , but it needs to be here so ++ * that the kernel source is self contained. ++ */ ++struct tm { ++ /* ++ * the number of seconds after the minute, normally in the range ++ * 0 to 59, but can be up to 60 to allow for leap seconds ++ */ ++ int tm_sec; ++ /* the number of minutes after the hour, in the range 0 to 59*/ ++ int tm_min; ++ /* the number of hours past midnight, in the range 0 to 23 */ ++ int tm_hour; ++ /* the day of the month, in the range 1 to 31 */ ++ int tm_mday; ++ /* the number of months since January, in the range 0 to 11 */ ++ int tm_mon; ++ /* the number of years since 1900 */ ++ long tm_year; ++ /* the number of days since Sunday, in the range 0 to 6 */ ++ int tm_wday; ++ /* the number of days since January 1, in the range 0 to 365 */ ++ int tm_yday; ++}; ++ ++void time_to_tm(time_t totalsecs, int offset, struct tm *result); ++ + /** + * timespec_to_ns - Convert timespec to nanoseconds + * @ts: pointer to the timespec variable to be converted +@@ -241,6 +273,8 @@ struct itimerval { #define CLOCK_PROCESS_CPUTIME_ID 2 #define CLOCK_THREAD_CPUTIME_ID 3 #define CLOCK_MONOTONIC_RAW 4 @@ -1682029,10 +1761258,79 @@ index 7402c1a..fc0bf3e 100644 #ifndef topology_thread_cpumask #define topology_thread_cpumask(cpu) cpumask_of(cpu) #endif +diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h +index 17ba82e..1eb44a9 100644 +--- a/include/linux/tracehook.h ++++ b/include/linux/tracehook.h +@@ -1,7 +1,7 @@ + /* + * Tracing hooks + * +- * Copyright (C) 2008 Red Hat, Inc. All rights reserved. ++ * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions +@@ -463,22 +463,38 @@ static inline int tracehook_get_signal(struct task_struct *task, + + /** + * tracehook_notify_jctl - report about job control stop/continue +- * @notify: nonzero if this is the last thread in the group to stop ++ * @notify: zero, %CLD_STOPPED or %CLD_CONTINUED + * @why: %CLD_STOPPED or %CLD_CONTINUED + * + * This is called when we might call do_notify_parent_cldstop(). +- * It's called when about to stop for job control; we are already in +- * %TASK_STOPPED state, about to call schedule(). It's also called when +- * a delayed %CLD_STOPPED or %CLD_CONTINUED report is ready to be made. + * +- * Return nonzero to generate a %SIGCHLD with @why, which is +- * normal if @notify is nonzero. ++ * @notify is zero if we would not ordinarily send a %SIGCHLD, ++ * or is the %CLD_STOPPED or %CLD_CONTINUED .si_code for %SIGCHLD. + * +- * Called with no locks held. ++ * @why is %CLD_STOPPED when about to stop for job control; ++ * we are already in %TASK_STOPPED state, about to call schedule(). ++ * It might also be that we have just exited (check %PF_EXITING), ++ * but need to report that a group-wide stop is complete. ++ * ++ * @why is %CLD_CONTINUED when waking up after job control stop and ++ * ready to make a delayed @notify report. ++ * ++ * Return the %CLD_* value for %SIGCHLD, or zero to generate no signal. ++ * ++ * Called with the siglock held. + */ + static inline int tracehook_notify_jctl(int notify, int why) + { +- return notify || (current->ptrace & PT_PTRACED); ++ return notify ?: (current->ptrace & PT_PTRACED) ? why : 0; ++} ++ ++/** ++ * tracehook_finish_jctl - report about return from job control stop ++ * ++ * This is called by do_signal_stop() after wakeup. ++ */ ++static inline void tracehook_finish_jctl(void) ++{ + } + + #define DEATH_REAP -1 diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h -index b9dc4ca..63a3f7a 100644 +index b9dc4ca..660a9de 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h +@@ -4,7 +4,7 @@ + /* + * Kernel Tracepoint API. + * +- * See Documentation/tracepoint.txt. ++ * See Documentation/trace/tracepoints.txt. + * + * (C) Copyright 2008 Mathieu Desnoyers + * @@ -23,6 +23,8 @@ struct tracepoint; struct tracepoint { const char *name; /* Tracepoint name */ @@ -1682373,6 +1761671,32 @@ index 0000000..21b0d03 +}; + +#endif /* _LINUX_UMMUNOTIFY_H */ +diff --git a/include/linux/unaligned/be_byteshift.h b/include/linux/unaligned/be_byteshift.h +index 46dd12c..9356b24 100644 +--- a/include/linux/unaligned/be_byteshift.h ++++ b/include/linux/unaligned/be_byteshift.h +@@ -1,7 +1,7 @@ + #ifndef _LINUX_UNALIGNED_BE_BYTESHIFT_H + #define _LINUX_UNALIGNED_BE_BYTESHIFT_H + +-#include ++#include + + static inline u16 __get_unaligned_be16(const u8 *p) + { +diff --git a/include/linux/unaligned/le_byteshift.h b/include/linux/unaligned/le_byteshift.h +index 59777e9..be376fb 100644 +--- a/include/linux/unaligned/le_byteshift.h ++++ b/include/linux/unaligned/le_byteshift.h +@@ -1,7 +1,7 @@ + #ifndef _LINUX_UNALIGNED_LE_BYTESHIFT_H + #define _LINUX_UNALIGNED_LE_BYTESHIFT_H + +-#include ++#include + + static inline u16 __get_unaligned_le16(const u8 *p) + { diff --git a/include/linux/usb.h b/include/linux/usb.h index b1e3c2f..a34fa89 100644 --- a/include/linux/usb.h @@ -1683540,7 +1762864,7 @@ index 0ec50ba..c17eb64 100644 struct usb_serial_port *port, const unsigned char *buf, int count); extern void usb_serial_generic_close(struct usb_serial_port *port); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h -index 310e18a..bb69e25 100644 +index 310e18a..f814730 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -53,6 +53,7 @@ struct usbnet { @@ -1683559,15 +1762883,16 @@ index 310e18a..bb69e25 100644 }; static inline struct usb_driver *driver_of(struct usb_interface *intf) -@@ -86,6 +88,7 @@ struct driver_info { +@@ -86,6 +88,8 @@ struct driver_info { #define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ #define FLAG_WLAN 0x0080 /* use "wlan%d" names */ +#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */ ++#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */ /* init device ... can sleep, or cause probe() failure */ -@@ -97,6 +100,9 @@ struct driver_info { +@@ -97,6 +101,9 @@ struct driver_info { /* reset device ... can sleep */ int (*reset)(struct usbnet *); @@ -1683577,7 +1762902,7 @@ index 310e18a..bb69e25 100644 /* see if peer is connected ... can sleep */ int (*check_connect)(struct usbnet *); -@@ -118,9 +124,8 @@ struct driver_info { +@@ -118,9 +125,8 @@ struct driver_info { * right after minidriver have initialized hardware. */ int (*early_init)(struct usbnet *dev); @@ -1683589,7 +1762914,7 @@ index 310e18a..bb69e25 100644 /* for new devices, use the descriptor-reading code instead */ int in; /* rx endpoint */ -@@ -177,7 +182,8 @@ struct skb_data { /* skb->cb is one of these */ +@@ -177,7 +183,8 @@ struct skb_data { /* skb->cb is one of these */ extern int usbnet_open (struct net_device *net); extern int usbnet_stop (struct net_device *net); @@ -1683599,7 +1762924,7 @@ index 310e18a..bb69e25 100644 extern void usbnet_tx_timeout (struct net_device *net); extern int usbnet_change_mtu (struct net_device *net, int new_mtu); -@@ -187,6 +193,10 @@ extern void usbnet_defer_kevent (struct usbnet *, int); +@@ -187,6 +194,10 @@ extern void usbnet_defer_kevent (struct usbnet *, int); extern void usbnet_skb_return (struct usbnet *, struct sk_buff *); extern void usbnet_unlink_rx_urbs(struct usbnet *); @@ -1683799,6 +1763124,18 @@ index 0044d9b..b2a7d8b 100644 +#define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int) +#define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int) #endif /* _LINUX_USBDEVICE_FS_H */ +diff --git a/include/linux/utsname.h b/include/linux/utsname.h +index 3656b30..69f3997 100644 +--- a/include/linux/utsname.h ++++ b/include/linux/utsname.h +@@ -36,7 +36,6 @@ struct new_utsname { + #include + #include + #include +-#include + + struct uts_namespace { + struct kref kref; diff --git a/include/linux/uwb.h b/include/linux/uwb.h index c021289..7fc9746 100644 --- a/include/linux/uwb.h @@ -1684695,7 +1764032,7 @@ index 6273fa9..7ef0c7b 100644 * to generate better code. */ diff --git a/include/linux/writeback.h b/include/linux/writeback.h -index 3224820..75cf586 100644 +index 3224820..66ebddc 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -14,17 +14,6 @@ extern struct list_head inode_in_use; @@ -1684757,7 +1764094,34 @@ index 3224820..75cf586 100644 void laptop_io_completion(void); void laptop_sync_completion(void); void throttle_vm_writeout(gfp_t gfp_mask); -@@ -150,17 +143,12 @@ balance_dirty_pages_ratelimited(struct address_space *mapping) +@@ -117,21 +110,20 @@ extern int laptop_mode; + extern unsigned long determine_dirtyable_memory(void); + + extern int dirty_background_ratio_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + extern int dirty_background_bytes_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + extern int dirty_ratio_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + extern int dirty_bytes_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos); + + struct ctl_table; +-struct file; +-int dirty_writeback_centisecs_handler(struct ctl_table *, int, struct file *, ++int dirty_writeback_centisecs_handler(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + + void get_dirty_limits(unsigned long *pbackground, unsigned long *pdirty, +@@ -150,17 +142,12 @@ balance_dirty_pages_ratelimited(struct address_space *mapping) typedef int (*writepage_t)(struct page *page, struct writeback_control *wbc, void *data); @@ -1688554,6 +1767918,19 @@ index 0000000..5dc6a61 +#endif + + +diff --git a/include/net/ip.h b/include/net/ip.h +index 72c3692..5b26a0b 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -399,7 +399,7 @@ extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport, + * fed into the routing cache should use these handlers. + */ + int ipv4_doint_and_flush(ctl_table *ctl, int write, +- struct file* filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos); + int ipv4_doint_and_flush_strategy(ctl_table *table, + void __user *oldval, size_t __user *oldlenp, diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 7c5c0f7..15b492a 100644 --- a/include/net/ip6_fib.h @@ -1689238,6 +1768615,26 @@ index c061044..466859b 100644 int ieee80211_rate_control_register(struct rate_control_ops *ops); void ieee80211_rate_control_unregister(struct rate_control_ops *ops); +diff --git a/include/net/ndisc.h b/include/net/ndisc.h +index 1459ed3..f76f22d 100644 +--- a/include/net/ndisc.h ++++ b/include/net/ndisc.h +@@ -55,7 +55,6 @@ enum { + #include + + struct ctl_table; +-struct file; + struct inet6_dev; + struct net_device; + struct net_proto_family; +@@ -139,7 +138,6 @@ extern int igmp6_event_report(struct sk_buff *skb); + #ifdef CONFIG_SYSCTL + extern int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, + int write, +- struct file * filp, + void __user *buffer, + size_t *lenp, + loff_t *ppos); diff --git a/include/net/neighbour.h b/include/net/neighbour.h index d8d790e..3817fda 100644 --- a/include/net/neighbour.h @@ -1690223,6 +1769620,33 @@ index 0000000..5660381 +header-y += fc_fs.h +header-y += fc_gs.h +header-y += fc_ns.h +diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h +index 195ca01..f943281 100644 +--- a/include/scsi/fc/fc_els.h ++++ b/include/scsi/fc/fc_els.h +@@ -20,6 +20,8 @@ + #ifndef _FC_ELS_H_ + #define _FC_ELS_H_ + ++#include ++ + /* + * Fibre Channel Switch - Enhanced Link Services definitions. + * From T11 FC-LS Rev 1.2 June 7, 2005. +@@ -248,10 +250,12 @@ struct fc_els_csp { + /* + * sp_features + */ +-#define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel. off. */ ++#define FC_SP_FT_NPIV 0x8000 /* multiple N_Port_ID support (FLOGI) */ ++#define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel off (PLOGI) */ + #define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */ + #define FC_SP_FT_RAND 0x4000 /* random relative offset */ + #define FC_SP_FT_VAL 0x2000 /* valid vendor version level */ ++#define FC_SP_FT_NPIV_ACC 0x2000 /* NPIV assignment (FLOGI LS_ACC) */ + #define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */ + #define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */ + #define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */ diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h index cff8a8c..f87777d 100644 --- a/include/scsi/fc/fc_fc2.h @@ -1690237,11 +1769661,33 @@ index cff8a8c..f87777d 100644 /* * Define expected size for ASSERTs. +diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h +index ac4cd38..50f28b1 100644 +--- a/include/scsi/fc/fc_fs.h ++++ b/include/scsi/fc/fc_fs.h +@@ -20,6 +20,8 @@ + #ifndef _FC_FS_H_ + #define _FC_FS_H_ + ++#include ++ + /* + * Fibre Channel Framing and Signalling definitions. + * From T11 FC-FS-2 Rev 0.90 - 9 August 2005. diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h -index ffab027..324dd0e 100644 +index ffab027..a37346d 100644 --- a/include/scsi/fc/fc_gs.h +++ b/include/scsi/fc/fc_gs.h -@@ -87,6 +87,7 @@ enum fc_ct_explan { +@@ -20,6 +20,8 @@ + #ifndef _FC_GS_H_ + #define _FC_GS_H_ + ++#include ++ + /* + * Fibre Channel Services - Common Transport. + * From T11.org FC-GS-2 Rev 5.3 November 1998. +@@ -87,6 +89,7 @@ enum fc_ct_explan { FC_FS_EXP_PNAM = 0x02, /* port name not registered */ FC_FS_EXP_NNAM = 0x03, /* node name not registered */ FC_FS_EXP_COS = 0x04, /* class of service not registered */ @@ -1690249,19 +1769695,66 @@ index ffab027..324dd0e 100644 /* definitions not complete */ }; +diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h +index 790d7b9..f4d354e 100644 +--- a/include/scsi/fc/fc_ns.h ++++ b/include/scsi/fc/fc_ns.h +@@ -20,6 +20,8 @@ + #ifndef _FC_NS_H_ + #define _FC_NS_H_ + ++#include ++ + /* + * Fibre Channel Services - Name Service (dNS) + * From T11.org FC-GS-2 Rev 5.3 November 1998. +@@ -47,6 +49,8 @@ enum fc_ns_req { + FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */ + FC_NS_RPN_ID = 0x0212, /* reg port name for ID */ + FC_NS_RNN_ID = 0x0213, /* reg node name for ID */ ++ FC_NS_RSPN_ID = 0x0218, /* reg symbolic port name */ ++ FC_NS_RSNN_NN = 0x0239, /* reg symbolic node name */ + }; + + /* +@@ -156,4 +160,22 @@ struct fc_ns_rn_id { + __be64 fr_wwn; /* node name or port name */ + } __attribute__((__packed__)); + ++/* ++ * RSNN_NN request - register symbolic node name ++ */ ++struct fc_ns_rsnn { ++ __be64 fr_wwn; /* node name */ ++ __u8 fr_name_len; ++ char fr_name[]; ++} __attribute__((__packed__)); ++ ++/* ++ * RSPN_ID request - register symbolic port name ++ */ ++struct fc_ns_rspn { ++ struct fc_ns_fid fr_fid; /* port ID object */ ++ __u8 fr_name_len; ++ char fr_name[]; ++} __attribute__((__packed__)); ++ + #endif /* _FC_NS_H_ */ diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h -index a0ff61c..27dad70 100644 +index a0ff61c..9afcbb9 100644 --- a/include/scsi/fc_encode.h +++ b/include/scsi/fc_encode.h -@@ -32,6 +32,7 @@ struct fc_ct_req { +@@ -32,6 +32,9 @@ struct fc_ct_req { struct fc_ns_gid_ft gid; struct fc_ns_rn_id rn; struct fc_ns_rft rft; + struct fc_ns_fid fid; ++ struct fc_ns_rsnn snn; ++ struct fc_ns_rspn spn; } payload; }; -@@ -57,6 +58,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, +@@ -57,6 +60,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, } /** @@ -1690285,7 +1769778,7 @@ index a0ff61c..27dad70 100644 * fc_ct_hdr_fill- fills ct header and reset ct payload * returns pointer to ct request. */ -@@ -77,10 +95,17 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, +@@ -77,10 +97,17 @@ static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, } /** @@ -1690306,7 +1769799,7 @@ index a0ff61c..27dad70 100644 enum fc_fh_type *fh_type) { struct fc_ct_req *ct; -@@ -91,6 +116,11 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, +@@ -91,6 +118,11 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; break; @@ -1690318,7 +1769811,40 @@ index a0ff61c..27dad70 100644 case FC_NS_RFT_ID: ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); hton24(ct->payload.rft.fid.fp_fid, -@@ -110,7 +140,6 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, +@@ -98,19 +130,37 @@ static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, + ct->payload.rft.fts = lport->fcts; + break; + +- case FC_NS_RPN_ID: ++ case FC_NS_RNN_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); + hton24(ct->payload.rn.fr_fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; +- put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); ++ put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn); ++ break; ++ ++ case FC_NS_RSPN_ID: ++ ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn)); ++ hton24(ct->payload.spn.fr_fid.fp_fid, ++ fc_host_port_id(lport->host)); ++ strncpy(ct->payload.spn.fr_name, ++ fc_host_symbolic_name(lport->host), 255); ++ ct->payload.spn.fr_name_len = ++ strnlen(ct->payload.spn.fr_name, 255); ++ break; ++ ++ case FC_NS_RSNN_NN: ++ ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn)); ++ put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn); ++ strncpy(ct->payload.snn.fr_name, ++ fc_host_symbolic_name(lport->host), 255); ++ ct->payload.snn.fr_name_len = ++ strnlen(ct->payload.snn.fr_name, 255); + break; + + default: return -EINVAL; } *r_ctl = FC_RCTL_DD_UNSOL_CTL; @@ -1690326,7 +1769852,39 @@ index a0ff61c..27dad70 100644 *fh_type = FC_TYPE_CT; return 0; } -@@ -249,51 +278,42 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) +@@ -169,6 +219,31 @@ static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) + sp->sp_bb_data = htons((u16) lport->mfs); + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); ++ if (lport->does_npiv) ++ sp->sp_features = htons(FC_SP_FT_NPIV); ++} ++ ++/** ++ * fc_fdisc_fill - Fill in a fdisc request frame. ++ */ ++static inline void fc_fdisc_fill(struct fc_lport *lport, struct fc_frame *fp) ++{ ++ struct fc_els_csp *sp; ++ struct fc_els_cssp *cp; ++ struct fc_els_flogi *fdisc; ++ ++ fdisc = fc_frame_payload_get(fp, sizeof(*fdisc)); ++ memset(fdisc, 0, sizeof(*fdisc)); ++ fdisc->fl_cmd = (u8) ELS_FDISC; ++ put_unaligned_be64(lport->wwpn, &fdisc->fl_wwpn); ++ put_unaligned_be64(lport->wwnn, &fdisc->fl_wwnn); ++ sp = &fdisc->fl_csp; ++ sp->sp_hi_ver = 0x20; ++ sp->sp_lo_ver = 0x20; ++ sp->sp_bb_cred = htons(10); /* this gets set by gateway */ ++ sp->sp_bb_data = htons((u16) lport->mfs); ++ cp = &fdisc->fl_cssp[3 - 1]; /* class 3 parameters */ ++ cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); + } + + /** +@@ -249,51 +324,46 @@ static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) /** * fc_els_fill - Fill in an ELS request frame */ @@ -1690350,6 +1769908,10 @@ index a0ff61c..27dad70 100644 case ELS_FLOGI: fc_flogi_fill(lport, fp); - *did = FC_FID_FLOGI; ++ break; ++ ++ case ELS_FDISC: ++ fc_fdisc_fill(lport, fp); break; case ELS_LOGO: @@ -1690386,10 +1769948,19 @@ index a0ff61c..27dad70 100644 default: diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h -index 5951105..c35d238 100644 +index 5951105..bfdb7aa 100644 --- a/include/scsi/fc_frame.h +++ b/include/scsi/fc_frame.h -@@ -37,13 +37,6 @@ +@@ -28,6 +28,8 @@ + #include + #include + ++#include ++ + /* + * The fc_frame interface is used to pass frame data between functions. + * The frame includes the data buffer, length, and SOF / EOF delimiter types. +@@ -37,13 +39,6 @@ #define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */ #define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */ @@ -1690403,6 +1769974,14 @@ index 5951105..c35d238 100644 #define fp_skb(fp) (&((fp)->skb)) #define fr_hdr(fp) ((fp)->skb.data) #define fr_len(fp) ((fp)->skb.len) +@@ -71,6 +66,7 @@ struct fcoe_rcv_info { + enum fc_sof fr_sof; /* start of frame delimiter */ + enum fc_eof fr_eof; /* end of frame delimiter */ + u8 fr_flags; /* flags - see below */ ++ u8 granted_mac[ETH_ALEN]; /* FCoE MAC address */ + }; + + diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 4426f00..d67dda2 100644 --- a/include/scsi/iscsi_if.h @@ -1690416,31 +1769995,51 @@ index 4426f00..d67dda2 100644 /* diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h -index b92584a..65dc9aa 100644 +index b92584a..8f99b23 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h -@@ -51,55 +51,49 @@ do { \ - do { \ - CMD; \ - } while (0); \ +@@ -26,6 +26,7 @@ + + #include + #include ++#include + + #include + #include +@@ -34,73 +35,6 @@ + + #include + +-#define FC_LIBFC_LOGGING 0x01 /* General logging, not categorized */ +-#define FC_LPORT_LOGGING 0x02 /* lport layer logging */ +-#define FC_DISC_LOGGING 0x04 /* discovery layer logging */ +-#define FC_RPORT_LOGGING 0x08 /* rport layer logging */ +-#define FC_FCP_LOGGING 0x10 /* I/O path logging */ +-#define FC_EM_LOGGING 0x20 /* Exchange Manager logging */ +-#define FC_EXCH_LOGGING 0x40 /* Exchange/Sequence logging */ +-#define FC_SCSI_LOGGING 0x80 /* SCSI logging (mostly error handling) */ +- +-extern unsigned int fc_debug_logging; +- +-#define FC_CHECK_LOGGING(LEVEL, CMD) \ +-do { \ +- if (unlikely(fc_debug_logging & LEVEL)) \ +- do { \ +- CMD; \ +- } while (0); \ -} while (0); -+} while (0) - - #define FC_LIBFC_DBG(fmt, args...) \ - FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ +- +-#define FC_LIBFC_DBG(fmt, args...) \ +- FC_CHECK_LOGGING(FC_LIBFC_LOGGING, \ - printk(KERN_INFO "libfc: " fmt, ##args);) -+ printk(KERN_INFO "libfc: " fmt, ##args)) - - #define FC_LPORT_DBG(lport, fmt, args...) \ - FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ +- +-#define FC_LPORT_DBG(lport, fmt, args...) \ +- FC_CHECK_LOGGING(FC_LPORT_LOGGING, \ - printk(KERN_INFO "lport: %6x: " fmt, \ - fc_host_port_id(lport->host), ##args);) -+ printk(KERN_INFO "host%u: lport %6x: " fmt, \ -+ (lport)->host->host_no, \ -+ fc_host_port_id((lport)->host), ##args)) - - #define FC_DISC_DBG(disc, fmt, args...) \ - FC_CHECK_LOGGING(FC_DISC_LOGGING, \ +- +-#define FC_DISC_DBG(disc, fmt, args...) \ +- FC_CHECK_LOGGING(FC_DISC_LOGGING, \ - printk(KERN_INFO "disc: %6x: " fmt, \ - fc_host_port_id(disc->lport->host), \ - ##args);) @@ -1690449,25 +1770048,14 @@ index b92584a..65dc9aa 100644 -do { \ - struct fc_rport_libfc_priv *rdata = rport->dd_data; \ - struct fc_lport *lport = rdata->local_port; \ -+ printk(KERN_INFO "host%u: disc: " fmt, \ -+ (disc)->lport->host->host_no, \ -+ ##args)) -+ -+#define FC_RPORT_ID_DBG(lport, port_id, fmt, args...) \ - FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ +- FC_CHECK_LOGGING(FC_RPORT_LOGGING, \ - printk(KERN_INFO "rport: %6x: %6x: " fmt, \ - fc_host_port_id(lport->host), \ - rport->port_id, ##args);) \ -} while (0); -+ printk(KERN_INFO "host%u: rport %6x: " fmt, \ -+ (lport)->host->host_no, \ -+ (port_id), ##args)) -+ -+#define FC_RPORT_DBG(rdata, fmt, args...) \ -+ FC_RPORT_ID_DBG((rdata)->local_port, (rdata)->ids.port_id, fmt, ##args) - - #define FC_FCP_DBG(pkt, fmt, args...) \ - FC_CHECK_LOGGING(FC_FCP_LOGGING, \ +- +-#define FC_FCP_DBG(pkt, fmt, args...) \ +- FC_CHECK_LOGGING(FC_FCP_LOGGING, \ - printk(KERN_INFO "fcp: %6x: %6x: " fmt, \ - fc_host_port_id(pkt->lp->host), \ - pkt->rport->port_id, ##args);) @@ -1690477,29 +1770065,22 @@ index b92584a..65dc9aa 100644 - printk(KERN_INFO "em: %6x: " fmt, \ - fc_host_port_id(em->lp->host), \ - ##args);) -+ printk(KERN_INFO "host%u: fcp: %6x: " fmt, \ -+ (pkt)->lp->host->host_no, \ -+ pkt->rport->port_id, ##args)) - - #define FC_EXCH_DBG(exch, fmt, args...) \ - FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ +- +-#define FC_EXCH_DBG(exch, fmt, args...) \ +- FC_CHECK_LOGGING(FC_EXCH_LOGGING, \ - printk(KERN_INFO "exch: %6x: %4x: " fmt, \ - fc_host_port_id(exch->lp->host), \ - exch->xid, ##args);) -+ printk(KERN_INFO "host%u: xid %4x: " fmt, \ -+ (exch)->lp->host->host_no, \ -+ exch->xid, ##args)) - - #define FC_SCSI_DBG(lport, fmt, args...) \ - FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ +- +-#define FC_SCSI_DBG(lport, fmt, args...) \ +- FC_CHECK_LOGGING(FC_SCSI_LOGGING, \ - printk(KERN_INFO "scsi: %6x: " fmt, \ - fc_host_port_id(lport->host), ##args);) -+ printk(KERN_INFO "host%u: scsi: " fmt, \ -+ (lport)->host->host_no, ##args)) - +- /* * libfc error codes -@@ -125,7 +119,7 @@ do { \ + */ +@@ -125,10 +59,12 @@ do { \ * FC HBA status */ enum fc_lport_state { @@ -1690507,8 +1770088,14 @@ index b92584a..65dc9aa 100644 + LPORT_ST_DISABLED = 0, LPORT_ST_FLOGI, LPORT_ST_DNS, - LPORT_ST_RPN_ID, -@@ -143,53 +137,74 @@ enum fc_disc_event { +- LPORT_ST_RPN_ID, ++ LPORT_ST_RNN_ID, ++ LPORT_ST_RSNN_NN, ++ LPORT_ST_RSPN_ID, + LPORT_ST_RFT_ID, + LPORT_ST_SCR, + LPORT_ST_READY, +@@ -143,53 +79,74 @@ enum fc_disc_event { }; enum fc_rport_state { @@ -1690596,7 +1770183,7 @@ index b92584a..65dc9aa 100644 * @retries: retry count in current state * @e_d_tov: error detect timeout value (in msec) * @r_a_tov: resource allocation timeout value (in msec) -@@ -197,38 +212,28 @@ struct fc_rport_operations { +@@ -197,38 +154,28 @@ struct fc_rport_operations { * @retry_work: * @event_callback: Callback for rport READY, FAILED or LOGO */ @@ -1690642,7 +1770229,7 @@ index b92584a..65dc9aa 100644 /* * fcoe stats structure */ -@@ -344,6 +349,8 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp) +@@ -344,6 +291,8 @@ static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp) */ struct fc_exch_mgr; @@ -1690651,7 +1770238,7 @@ index b92584a..65dc9aa 100644 /* * Sequence. -@@ -368,6 +375,7 @@ struct fc_seq { +@@ -368,6 +317,7 @@ struct fc_seq { */ struct fc_exch { struct fc_exch_mgr *em; /* exchange manager */ @@ -1690659,7 +1770246,7 @@ index b92584a..65dc9aa 100644 u32 state; /* internal driver state */ u16 xid; /* our exchange ID */ struct list_head ex_list; /* free or busy list linkage */ -@@ -415,7 +423,7 @@ struct libfc_function_template { +@@ -415,7 +365,7 @@ struct libfc_function_template { * STATUS: OPTIONAL */ struct fc_seq *(*elsct_send)(struct fc_lport *lport, @@ -1690668,7 +1770255,7 @@ index b92584a..65dc9aa 100644 struct fc_frame *fp, unsigned int op, void (*resp)(struct fc_seq *, -@@ -519,25 +527,6 @@ struct libfc_function_template { +@@ -519,25 +469,6 @@ struct libfc_function_template { void (*exch_done)(struct fc_seq *sp); /* @@ -1690694,7 +1770281,7 @@ index b92584a..65dc9aa 100644 * Start a new sequence on the same exchange/sequence tuple. * * STATUS: OPTIONAL -@@ -577,9 +566,11 @@ struct libfc_function_template { +@@ -577,9 +508,11 @@ struct libfc_function_template { int (*lport_reset)(struct fc_lport *); /* @@ -1690708,7 +1770295,7 @@ index b92584a..65dc9aa 100644 /* * Initiates the RP state machine. It is called from the LP module. -@@ -592,7 +583,7 @@ struct libfc_function_template { +@@ -592,7 +525,7 @@ struct libfc_function_template { * * STATUS: OPTIONAL */ @@ -1690717,7 +1770304,7 @@ index b92584a..65dc9aa 100644 /* * Logoff, and remove the rport from the transport if -@@ -600,7 +591,7 @@ struct libfc_function_template { +@@ -600,7 +533,7 @@ struct libfc_function_template { * * STATUS: OPTIONAL */ @@ -1690726,7 +1770313,7 @@ index b92584a..65dc9aa 100644 /* * Recieve a request from a remote port. -@@ -608,14 +599,20 @@ struct libfc_function_template { +@@ -608,14 +541,20 @@ struct libfc_function_template { * STATUS: OPTIONAL */ void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, @@ -1690749,7 +1770336,7 @@ index b92584a..65dc9aa 100644 /* * Send a fcp cmd from fsp pkt. -@@ -681,18 +678,16 @@ struct libfc_function_template { +@@ -681,18 +620,16 @@ struct libfc_function_template { /* information used by the discovery layer */ struct fc_disc { unsigned char retry_count; @@ -1690769,7 +1770356,7 @@ index b92584a..65dc9aa 100644 struct fc_lport *lport; struct mutex disc_mutex; struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ -@@ -704,9 +699,9 @@ struct fc_lport { +@@ -704,9 +641,11 @@ struct fc_lport { /* Associations */ struct Scsi_Host *host; @@ -1690777,12 +1770364,134 @@ index b92584a..65dc9aa 100644 - struct fc_rport *dns_rp; - struct fc_rport *ptp_rp; + struct list_head ema_list; ++ struct list_head vports; /* child vports if N_Port */ ++ struct fc_vport *vport; /* parent vport if VN_Port */ + struct fc_rport_priv *dns_rp; + struct fc_rport_priv *ptp_rp; void *scsi_priv; struct fc_disc disc; -@@ -960,6 +955,28 @@ int fc_elsct_init(struct fc_lport *lp); +@@ -729,6 +668,8 @@ struct fc_lport { + u32 seq_offload:1; /* seq offload supported */ + u32 crc_offload:1; /* crc offload supported */ + u32 lro_enabled:1; /* large receive offload */ ++ u32 does_npiv:1; /* supports multiple vports */ ++ u32 npiv_enabled:1; /* switch/fabric allows NPIV */ + u32 mfs; /* max FC payload size */ + unsigned int service_params; + unsigned int e_d_tov; +@@ -805,12 +746,22 @@ static inline void *lport_priv(const struct fc_lport *lp) + * @sht: ptr to the scsi host templ + * @priv_size: size of private data after fc_lport + * +- * Returns: ptr to Scsi_Host ++ * Returns: libfc lport + */ +-static inline struct Scsi_Host * ++static inline struct fc_lport * + libfc_host_alloc(struct scsi_host_template *sht, int priv_size) + { +- return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size); ++ struct fc_lport *lport; ++ struct Scsi_Host *shost; ++ ++ shost = scsi_host_alloc(sht, sizeof(*lport) + priv_size); ++ if (!shost) ++ return NULL; ++ lport = shost_priv(shost); ++ lport->host = shost; ++ INIT_LIST_HEAD(&lport->ema_list); ++ INIT_LIST_HEAD(&lport->vports); ++ return lport; + } + + /* +@@ -840,11 +791,13 @@ int fc_fabric_login(struct fc_lport *lp); + /* + * The link is up for the given local port. + */ ++void __fc_linkup(struct fc_lport *); + void fc_linkup(struct fc_lport *); + + /* + * Link is down for the given local port. + */ ++void __fc_linkdown(struct fc_lport *); + void fc_linkdown(struct fc_lport *); + + /* +@@ -862,6 +815,27 @@ int fc_lport_reset(struct fc_lport *); + */ + int fc_set_mfs(struct fc_lport *lp, u32 mfs); + ++/* ++ * Allocate a new lport struct for an NPIV VN_Port ++ */ ++struct fc_lport *libfc_vport_create(struct fc_vport *vport, int privsize); ++ ++/* ++ * Find an NPIV VN_Port by port ID ++ */ ++struct fc_lport *fc_vport_id_lookup(struct fc_lport *n_port, u32 port_id); ++ ++/* ++ * NPIV VN_Port link state management ++ */ ++void fc_vport_setlink(struct fc_lport *vn_port); ++void fc_vports_linkchange(struct fc_lport *n_port); ++ ++/* ++ * Issue fc pass-thru request via bsg interface ++ */ ++int fc_lport_bsg_request(struct fc_bsg_job *job); ++ + + /* + * REMOTE PORT LAYER +@@ -893,14 +867,6 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, + void (*done)(struct scsi_cmnd *)); + + /* +- * complete processing of a fcp packet +- * +- * This function may sleep if a fsp timer is pending. +- * The host lock must not be held by caller. +- */ +-void fc_fcp_complete(struct fc_fcp_pkt *fsp); +- +-/* + * Send an ABTS frame to the target device. The sc_cmd argument + * is a pointer to the SCSI command to be aborted. + */ +@@ -937,17 +903,22 @@ int fc_change_queue_type(struct scsi_device *sdev, int tag_type); + void fc_fcp_destroy(struct fc_lport *); + + /* +- * Set up direct-data placement for this I/O request +- */ +-void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid); +- +-/* + * ELS/CT interface + *****************************/ + /* + * Initializes ELS/CT interface + */ + int fc_elsct_init(struct fc_lport *lp); ++struct fc_seq *fc_elsct_send(struct fc_lport *lport, ++ u32 did, ++ struct fc_frame *fp, ++ unsigned int op, ++ void (*resp)(struct fc_seq *, ++ struct fc_frame *fp, ++ void *arg), ++ void *arg, u32 timer_msec); ++void fc_lport_flogi_resp(struct fc_seq *, struct fc_frame *, void *); ++void fc_lport_logo_resp(struct fc_seq *, struct fc_frame *, void *); + + + /* +@@ -960,6 +931,34 @@ int fc_elsct_init(struct fc_lport *lp); int fc_exch_init(struct fc_lport *lp); /* @@ -1690807,11 +1770516,17 @@ index b92584a..65dc9aa 100644 + */ +void fc_exch_mgr_del(struct fc_exch_mgr_anchor *ema); + ++/* ++ * Clone an exchange manager list, getting reference holds for each EM. ++ * This is for use with NPIV and sharing the X_ID space between VN_Ports. ++ */ ++int fc_exch_mgr_list_clone(struct fc_lport *src, struct fc_lport *dst); ++ +/* * Allocates an Exchange Manager (EM). * * The EM manages exchanges for their allocation and -@@ -974,27 +991,25 @@ int fc_exch_init(struct fc_lport *lp); +@@ -974,90 +973,31 @@ int fc_exch_init(struct fc_lport *lp); * a new exchange. * The LLD may choose to have multiple EMs, * e.g. one EM instance per CPU receive thread in LLD. @@ -1690842,13 +1770557,47 @@ index b92584a..65dc9aa 100644 */ -void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, - struct fc_frame *fp); +- +-/* +- * This function is for exch_seq_send function pointer in +- * struct libfc_function_template, see comment block on +- * exch_seq_send for description of this function. +- */ +-struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, +- struct fc_frame *fp, +- void (*resp)(struct fc_seq *sp, +- struct fc_frame *fp, +- void *arg), +- void (*destructor)(struct fc_seq *sp, +- void *arg), +- void *arg, u32 timer_msec); +- +-/* +- * send a frame using existing sequence and exchange. +- */ +-int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); +- +-/* +- * Send ELS response using mainly infomation +- * in exchange and sequence in EM layer. +- */ +-void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, +- struct fc_seq_els_data *els_data); +- +-/* +- * This function is for seq_exch_abort function pointer in +- * struct libfc_function_template, see comment block on +- * seq_exch_abort for description of this function. +- */ +-int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); +- +-/* +- * Indicate that an exchange/sequence tuple is complete and the memory +- * allocated for the related objects may be freed. +- */ +-void fc_exch_done(struct fc_seq *sp); +void fc_exch_recv(struct fc_lport *lp, struct fc_frame *fp); - /* - * This function is for exch_seq_send function pointer in -@@ -1036,28 +1051,20 @@ int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); - void fc_exch_done(struct fc_seq *sp); - /* - * Assigns a EM and XID for a frame and then allocates - * a new exchange and sequence pair. @@ -1690857,20 +1770606,18 @@ index b92584a..65dc9aa 100644 -struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); - -/* - * Allocate a new exchange and sequence pair. +- * Allocate a new exchange and sequence pair. - * if ex_id is zero then next free exchange id - * from specified exchange manger mp will be assigned. - */ +- */ -struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, - struct fc_frame *fp, u16 ex_id); -+struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp); - /* - * Start a new sequence on the same exchange as the supplied sequence. - */ - struct fc_seq *fc_seq_start_next(struct fc_seq *sp); - -+ - /* +-/* +- * Start a new sequence on the same exchange as the supplied sequence. +- */ +-struct fc_seq *fc_seq_start_next(struct fc_seq *sp); +- +-/* - * Reset an exchange manager, completing all sequences and exchanges. - * If s_id is non-zero, reset only exchanges originating from that FID. - * If d_id is non-zero, reset only exchanges sending to that FID. @@ -1690881,16 +1770628,142 @@ index b92584a..65dc9aa 100644 */ void fc_exch_mgr_reset(struct fc_lport *, u32 s_id, u32 d_id); -@@ -1078,4 +1085,9 @@ void fc_destroy_exch_mgr(void); - int fc_setup_rport(void); - void fc_destroy_rport(void); +@@ -1070,12 +1010,4 @@ void fc_get_host_port_state(struct Scsi_Host *shost); + void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); + struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); -+/* -+ * Internal libfc functions. -+ */ -+const char *fc_els_resp_type(struct fc_frame *); -+ +-/* +- * module setup functions. +- */ +-int fc_setup_exch_mgr(void); +-void fc_destroy_exch_mgr(void); +-int fc_setup_rport(void); +-void fc_destroy_rport(void); +- #endif /* _LIBFC_H_ */ +diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h +index b241060..76d08c9 100644 +--- a/include/scsi/libfcoe.h ++++ b/include/scsi/libfcoe.h +@@ -53,33 +53,35 @@ enum fip_state { + }; + + /** +- * struct fcoe_ctlr - FCoE Controller and FIP state. +- * @state: internal FIP state for network link and FIP or non-FIP mode. +- * @lp: &fc_lport: libfc local port. +- * @sel_fcf: currently selected FCF, or NULL. +- * @fcfs: list of discovered FCFs. +- * @fcf_count: number of discovered FCF entries. +- * @sol_time: time when a multicast solicitation was last sent. +- * @sel_time: time after which to select an FCF. +- * @port_ka_time: time of next port keep-alive. +- * @ctlr_ka_time: time of next controller keep-alive. +- * @timer: timer struct used for all delayed events. +- * @link_work: &work_struct for doing FCF selection. +- * @recv_work: &work_struct for receiving FIP frames. ++ * struct fcoe_ctlr - FCoE Controller and FIP state ++ * @state: internal FIP state for network link and FIP or non-FIP mode. ++ * @lp: &fc_lport: libfc local port. ++ * @sel_fcf: currently selected FCF, or NULL. ++ * @fcfs: list of discovered FCFs. ++ * @fcf_count: number of discovered FCF entries. ++ * @sol_time: time when a multicast solicitation was last sent. ++ * @sel_time: time after which to select an FCF. ++ * @port_ka_time: time of next port keep-alive. ++ * @ctlr_ka_time: time of next controller keep-alive. ++ * @timer: timer struct used for all delayed events. ++ * @link_work: &work_struct for doing FCF selection. ++ * @recv_work: &work_struct for receiving FIP frames. + * @fip_recv_list: list of received FIP frames. +- * @user_mfs: configured maximum FC frame size, including FC header. +- * @flogi_oxid: exchange ID of most recent fabric login. +- * @flogi_count: number of FLOGI attempts in AUTO mode. +- * @link: current link status for libfc. +- * @last_link: last link state reported to libfc. +- * @map_dest: use the FC_MAP mode for destination MAC addresses. +- * @spma: supports SPMA server-provided MACs mode +- * @dest_addr: MAC address of the selected FC forwarder. +- * @ctl_src_addr: the native MAC address of our local port. +- * @data_src_addr: the assigned MAC address for the local port after FLOGI. +- * @send: LLD-supplied function to handle sending of FIP Ethernet frames. +- * @update_mac: LLD-supplied function to handle changes to MAC addresses. +- * @lock: lock protecting this structure. ++ * @user_mfs: configured maximum FC frame size, including FC header. ++ * @flogi_oxid: exchange ID of most recent fabric login. ++ * @flogi_count: number of FLOGI attempts in AUTO mode. ++ * @link: current link status for libfc. ++ * @last_link: last link state reported to libfc. ++ * @map_dest: use the FC_MAP mode for destination MAC addresses. ++ * @spma: supports SPMA server-provided MACs mode ++ * @send_ctlr_ka: need to send controller keep alive ++ * @send_port_ka: need to send port keep alives ++ * @dest_addr: MAC address of the selected FC forwarder. ++ * @ctl_src_addr: the native MAC address of our local port. ++ * @send: LLD-supplied function to handle sending FIP Ethernet frames ++ * @update_mac: LLD-supplied function to handle changes to MAC addresses. ++ * @get_src_addr: LLD-supplied function to supply a source MAC address. ++ * @lock: lock protecting this structure. + * + * This structure is used by all FCoE drivers. It contains information + * needed by all FCoE low-level drivers (LLDs) as well as internal state +@@ -106,27 +108,29 @@ struct fcoe_ctlr { + u8 last_link; + u8 map_dest; + u8 spma; ++ u8 send_ctlr_ka; ++ u8 send_port_ka; + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; +- u8 data_src_addr[ETH_ALEN]; + + void (*send)(struct fcoe_ctlr *, struct sk_buff *); +- void (*update_mac)(struct fcoe_ctlr *, u8 *old, u8 *new); ++ void (*update_mac)(struct fc_lport *, u8 *addr); ++ u8 * (*get_src_addr)(struct fc_lport *); + spinlock_t lock; + }; + +-/* +- * struct fcoe_fcf - Fibre-Channel Forwarder. +- * @list: list linkage. +- * @time: system time (jiffies) when an advertisement was last received. +- * @switch_name: WWN of switch from advertisement. +- * @fabric_name: WWN of fabric from advertisement. +- * @fc_map: FC_MAP value from advertisement. +- * @fcf_mac: Ethernet address of the FCF. +- * @vfid: virtual fabric ID. +- * @pri: seletion priority, smaller values are better. +- * @flags: flags received from advertisement. +- * @fka_period: keep-alive period, in jiffies. ++/** ++ * struct fcoe_fcf - Fibre-Channel Forwarder ++ * @list: list linkage ++ * @time: system time (jiffies) when an advertisement was last received ++ * @switch_name: WWN of switch from advertisement ++ * @fabric_name: WWN of fabric from advertisement ++ * @fc_map: FC_MAP value from advertisement ++ * @fcf_mac: Ethernet address of the FCF ++ * @vfid: virtual fabric ID ++ * @pri: selection priority, smaller values are better ++ * @flags: flags received from advertisement ++ * @fka_period: keep-alive period, in jiffies + * + * A Fibre-Channel Forwarder (FCF) is the entity on the Ethernet that + * passes FCoE frames on to an FC fabric. This structure represents +@@ -155,9 +159,10 @@ void fcoe_ctlr_init(struct fcoe_ctlr *); + void fcoe_ctlr_destroy(struct fcoe_ctlr *); + void fcoe_ctlr_link_up(struct fcoe_ctlr *); + int fcoe_ctlr_link_down(struct fcoe_ctlr *); +-int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct sk_buff *); ++int fcoe_ctlr_els_send(struct fcoe_ctlr *, struct fc_lport *, struct sk_buff *); + void fcoe_ctlr_recv(struct fcoe_ctlr *, struct sk_buff *); +-int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_frame *fp, u8 *sa); ++int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, ++ struct fc_frame *, u8 *); + + /* libfcoe funcs */ + u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 61afeb5..887e57e 100644 --- a/include/scsi/libiscsi.h @@ -1691015,6 +1770888,35 @@ index ff9b33c..91db543 100644 }; #endif /* ndef __OSD_SENSE_H__ */ +diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h +index 084478e..34c46ab 100644 +--- a/include/scsi/scsi.h ++++ b/include/scsi/scsi.h +@@ -129,6 +129,9 @@ struct scsi_cmnd; + #define MI_REPORT_TARGET_PGS 0x0a + /* values for maintenance out */ + #define MO_SET_TARGET_PGS 0x0a ++/* values for variable length command */ ++#define READ_32 0x09 ++#define WRITE_32 0x0b + + /* Values for T10/04-262r7 */ + #define ATA_16 0x85 /* 16-byte pass-thru */ +diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h +index 3878d1d..a5e885a 100644 +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -229,10 +229,6 @@ enum scsi_prot_operations { + /* OS-HBA: Protected, HBA-Target: Protected */ + SCSI_PROT_READ_PASS, + SCSI_PROT_WRITE_PASS, +- +- /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */ +- SCSI_PROT_READ_CONVERT, +- SCSI_PROT_WRITE_CONVERT, + }; + + static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 3f566af..9af48cb 100644 --- a/include/scsi/scsi_device.h @@ -1691054,6 +1770956,45 @@ index 33efce2..ff24074 100644 + return -SCSI_DH_NOSYS; +} #endif +diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h +index b62a097..6e728b1 100644 +--- a/include/scsi/scsi_host.h ++++ b/include/scsi/scsi_host.h +@@ -798,9 +798,15 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost) + static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) + { + switch (target_type) { +- case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; +- case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; +- case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; ++ case 1: ++ if (shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION) ++ return target_type; ++ case 2: ++ if (shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION) ++ return target_type; ++ case 3: ++ if (shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION) ++ return target_type; + } + + return 0; +@@ -808,13 +814,14 @@ static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsign + + static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) + { ++#if defined(CONFIG_BLK_DEV_INTEGRITY) + switch (target_type) { + case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; + case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; + case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; + case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; + } +- ++#endif + return 0; + } + diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 251fc1c..3dae3f7 100644 --- a/include/sound/ac97_codec.h @@ -1694357,10 +1774298,18 @@ index 093f659..bb008d0 100644 } - diff --git a/init/main.c b/init/main.c -index 11f4f14..51695ce 100644 +index 11f4f14..7449819 100644 --- a/init/main.c +++ b/init/main.c -@@ -68,6 +68,8 @@ +@@ -18,7 +18,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -68,6 +67,8 @@ #include #include #include @@ -1694369,7 +1774318,7 @@ index 11f4f14..51695ce 100644 #include #include -@@ -353,17 +355,11 @@ static void __init smp_init(void) +@@ -353,17 +354,11 @@ static void __init smp_init(void) #define smp_init() do { } while (0) #endif @@ -1694387,7 +1774336,7 @@ index 11f4f14..51695ce 100644 /* Setup number of possible processor ids */ int nr_cpu_ids __read_mostly = NR_CPUS; EXPORT_SYMBOL(nr_cpu_ids); -@@ -374,29 +370,6 @@ static void __init setup_nr_cpu_ids(void) +@@ -374,29 +369,6 @@ static void __init setup_nr_cpu_ids(void) nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; } @@ -1694417,7 +1774366,7 @@ index 11f4f14..51695ce 100644 /* Called by boot processor to activate the rest. */ static void __init smp_init(void) { -@@ -451,6 +424,7 @@ static noinline void __init_refok rest_init(void) +@@ -451,6 +423,7 @@ static noinline void __init_refok rest_init(void) { int pid; @@ -1694425,7 +1774374,7 @@ index 11f4f14..51695ce 100644 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); -@@ -462,7 +436,6 @@ static noinline void __init_refok rest_init(void) +@@ -462,7 +435,6 @@ static noinline void __init_refok rest_init(void) * at least once to get things moving: */ init_idle_bootup_task(current); @@ -1694433,7 +1774382,7 @@ index 11f4f14..51695ce 100644 preempt_enable_no_resched(); schedule(); preempt_disable(); -@@ -631,7 +604,6 @@ asmlinkage void __init start_kernel(void) +@@ -631,7 +603,6 @@ asmlinkage void __init start_kernel(void) softirq_init(); timekeeping_init(); time_init(); @@ -1694441,7 +1774390,7 @@ index 11f4f14..51695ce 100644 profile_init(); if (!irqs_disabled()) printk(KERN_CRIT "start_kernel(): bug: interrupts were " -@@ -682,6 +654,7 @@ asmlinkage void __init start_kernel(void) +@@ -682,6 +653,7 @@ asmlinkage void __init start_kernel(void) numa_policy_init(); if (late_time_init) late_time_init(); @@ -1694449,7 +1774398,7 @@ index 11f4f14..51695ce 100644 calibrate_delay(); pidmap_init(); anon_vma_init(); -@@ -691,12 +664,12 @@ asmlinkage void __init start_kernel(void) +@@ -691,12 +663,12 @@ asmlinkage void __init start_kernel(void) #endif thread_info_cache_init(); cred_init(); @@ -1694464,7 +1774413,7 @@ index 11f4f14..51695ce 100644 radix_tree_init(); signals_init(); /* rootfs populating might need page-writeback */ -@@ -712,6 +685,7 @@ asmlinkage void __init start_kernel(void) +@@ -712,6 +684,7 @@ asmlinkage void __init start_kernel(void) check_bugs(); acpi_early_init(); /* before LAPIC and SMP init */ @@ -1694472,7 +1774421,7 @@ index 11f4f14..51695ce 100644 ftrace_init(); -@@ -809,6 +783,7 @@ static void __init do_basic_setup(void) +@@ -809,6 +782,7 @@ static void __init do_basic_setup(void) init_workqueues(); cpuset_init_smp(); usermodehelper_init(); @@ -1694480,6 +1774429,108 @@ index 11f4f14..51695ce 100644 driver_init(); init_irq_proc(); do_ctors(); +diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c +index 40eab73..7d37047 100644 +--- a/ipc/ipc_sysctl.c ++++ b/ipc/ipc_sysctl.c +@@ -27,18 +27,18 @@ static void *get_ipc(ctl_table *table) + } + + #ifdef CONFIG_PROC_SYSCTL +-static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp, ++static int proc_ipc_dointvec(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table ipc_table; + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); + +- return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); ++ return proc_dointvec(&ipc_table, write, buffer, lenp, ppos); + } + + static int proc_ipc_callback_dointvec(ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) ++ void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table ipc_table; + size_t lenp_bef = *lenp; +@@ -47,7 +47,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write, + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); + +- rc = proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos); ++ rc = proc_dointvec(&ipc_table, write, buffer, lenp, ppos); + + if (write && !rc && lenp_bef == *lenp) + /* +@@ -61,13 +61,13 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write, + } + + static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) ++ void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table ipc_table; + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); + +- return proc_doulongvec_minmax(&ipc_table, write, filp, buffer, ++ return proc_doulongvec_minmax(&ipc_table, write, buffer, + lenp, ppos); + } + +@@ -95,7 +95,7 @@ static void ipc_auto_callback(int val) + } + + static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) ++ void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table ipc_table; + size_t lenp_bef = *lenp; +@@ -106,7 +106,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, + ipc_table.data = get_ipc(table); + oldval = *((int *)(ipc_table.data)); + +- rc = proc_dointvec_minmax(&ipc_table, write, filp, buffer, lenp, ppos); ++ rc = proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); + + if (write && !rc && lenp_bef == *lenp) { + int newval = *((int *)(ipc_table.data)); +diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c +index 24ae46d..8a05871 100644 +--- a/ipc/mq_sysctl.c ++++ b/ipc/mq_sysctl.c +@@ -31,24 +31,24 @@ static void *get_mq(ctl_table *table) + return which; + } + +-static int proc_mq_dointvec(ctl_table *table, int write, struct file *filp, ++static int proc_mq_dointvec(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table mq_table; + memcpy(&mq_table, table, sizeof(mq_table)); + mq_table.data = get_mq(table); + +- return proc_dointvec(&mq_table, write, filp, buffer, lenp, ppos); ++ return proc_dointvec(&mq_table, write, buffer, lenp, ppos); + } + + static int proc_mq_dointvec_minmax(ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) ++ void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table mq_table; + memcpy(&mq_table, table, sizeof(mq_table)); + mq_table.data = get_mq(table); + +- return proc_dointvec_minmax(&mq_table, write, filp, buffer, ++ return proc_dointvec_minmax(&mq_table, write, buffer, + lenp, ppos); + } + #else diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c5e68ad..ee9d697 100644 --- a/ipc/mqueue.c @@ -1694538,10 +1774589,18 @@ index b8e4ba9..79ce84e 100644 .stop = sysvipc_proc_stop, .next = sysvipc_proc_next, diff --git a/kernel/Makefile b/kernel/Makefile -index 2093a69..bde5267 100644 +index 2093a69..7556faf 100644 --- a/kernel/Makefile +++ b/kernel/Makefile -@@ -69,10 +69,11 @@ obj-$(CONFIG_IKCONFIG) += configs.o +@@ -58,7 +58,6 @@ obj-$(CONFIG_KEXEC) += kexec.o + obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o + obj-$(CONFIG_COMPAT) += compat.o + obj-$(CONFIG_CGROUPS) += cgroup.o +-obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o + obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o + obj-$(CONFIG_CPUSETS) += cpuset.o + obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o +@@ -69,10 +68,11 @@ obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o @@ -1694555,7 +1774614,7 @@ index 2093a69..bde5267 100644 obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o -@@ -80,26 +81,22 @@ obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o +@@ -80,26 +80,22 @@ obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ obj-$(CONFIG_SECCOMP) += seccomp.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o @@ -1694584,7 +1774643,7 @@ index 2093a69..bde5267 100644 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is -@@ -119,7 +116,7 @@ $(obj)/config_data.gz: .config FORCE +@@ -119,7 +115,7 @@ $(obj)/config_data.gz: .config FORCE $(call if_changed,gzip) quiet_cmd_ikconfiggz = IKCFG $@ @@ -1694626,7 +1774685,7 @@ index 9f33910..9a4715a 100644 /** diff --git a/kernel/audit.c b/kernel/audit.c -index defc2e6..601e3f2 100644 +index defc2e6..057a3a4 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -55,7 +55,6 @@ @@ -1694637,6 +1774696,37 @@ index defc2e6..601e3f2 100644 #include #include +@@ -855,18 +854,24 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + break; + } + case AUDIT_SIGNAL_INFO: +- err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); +- if (err) +- return err; ++ len = 0; ++ if (audit_sig_sid) { ++ err = security_secid_to_secctx(audit_sig_sid, &ctx, &len); ++ if (err) ++ return err; ++ } + sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL); + if (!sig_data) { +- security_release_secctx(ctx, len); ++ if (audit_sig_sid) ++ security_release_secctx(ctx, len); + return -ENOMEM; + } + sig_data->uid = audit_sig_uid; + sig_data->pid = audit_sig_pid; +- memcpy(sig_data->ctx, ctx, len); +- security_release_secctx(ctx, len); ++ if (audit_sig_sid) { ++ memcpy(sig_data->ctx, ctx, len); ++ security_release_secctx(ctx, len); ++ } + audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, + 0, 0, sig_data, sizeof(*sig_data) + len); + kfree(sig_data); diff --git a/kernel/audit.h b/kernel/audit.h index 208687b..f7206db 100644 --- a/kernel/audit.h @@ -1695784,10 +1775874,373 @@ index 68d3c6a..ef0410c 100644 chunk = audit_tree_lookup(inode); if (chunk) { diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index b6eadfe..cd83d99 100644 +index b6eadfe..7ccba4b 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -596,10 +596,11 @@ void cgroup_unlock(void) +@@ -23,6 +23,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -48,6 +49,8 @@ + #include + #include + #include ++#include ++#include /* TODO: replace with more sophisticated array */ + + #include + +@@ -60,6 +63,8 @@ static struct cgroup_subsys *subsys[] = { + #include + }; + ++#define MAX_CGROUP_ROOT_NAMELEN 64 ++ + /* + * A cgroupfs_root represents the root of a cgroup hierarchy, + * and may be associated with a superblock to form an active +@@ -74,6 +79,9 @@ struct cgroupfs_root { + */ + unsigned long subsys_bits; + ++ /* Unique id for this hierarchy. */ ++ int hierarchy_id; ++ + /* The bitmask of subsystems currently attached to this hierarchy */ + unsigned long actual_subsys_bits; + +@@ -94,6 +102,9 @@ struct cgroupfs_root { + + /* The path to use for release notifications. */ + char release_agent_path[PATH_MAX]; ++ ++ /* The name for this hierarchy - may be empty */ ++ char name[MAX_CGROUP_ROOT_NAMELEN]; + }; + + /* +@@ -141,6 +152,10 @@ struct css_id { + static LIST_HEAD(roots); + static int root_count; + ++static DEFINE_IDA(hierarchy_ida); ++static int next_hierarchy_id; ++static DEFINE_SPINLOCK(hierarchy_id_lock); ++ + /* dummytop is a shorthand for the dummy hierarchy's top cgroup */ + #define dummytop (&rootnode.top_cgroup) + +@@ -201,6 +216,7 @@ struct cg_cgroup_link { + * cgroup, anchored on cgroup->css_sets + */ + struct list_head cgrp_link_list; ++ struct cgroup *cgrp; + /* + * List running through cg_cgroup_links pointing at a + * single css_set object, anchored on css_set->cg_links +@@ -227,8 +243,11 @@ static int cgroup_subsys_init_idr(struct cgroup_subsys *ss); + static DEFINE_RWLOCK(css_set_lock); + static int css_set_count; + +-/* hash table for cgroup groups. This improves the performance to +- * find an existing css_set */ ++/* ++ * hash table for cgroup groups. This improves the performance to find ++ * an existing css_set. This hash doesn't (currently) take into ++ * account cgroups in empty hierarchies. ++ */ + #define CSS_SET_HASH_BITS 7 + #define CSS_SET_TABLE_SIZE (1 << CSS_SET_HASH_BITS) + static struct hlist_head css_set_table[CSS_SET_TABLE_SIZE]; +@@ -248,48 +267,22 @@ static struct hlist_head *css_set_hash(struct cgroup_subsys_state *css[]) + return &css_set_table[index]; + } + ++static void free_css_set_rcu(struct rcu_head *obj) ++{ ++ struct css_set *cg = container_of(obj, struct css_set, rcu_head); ++ kfree(cg); ++} ++ + /* We don't maintain the lists running through each css_set to its + * task until after the first call to cgroup_iter_start(). This + * reduces the fork()/exit() overhead for people who have cgroups + * compiled into their kernel but not actually in use */ + static int use_task_css_set_links __read_mostly; + +-/* When we create or destroy a css_set, the operation simply +- * takes/releases a reference count on all the cgroups referenced +- * by subsystems in this css_set. This can end up multiple-counting +- * some cgroups, but that's OK - the ref-count is just a +- * busy/not-busy indicator; ensuring that we only count each cgroup +- * once would require taking a global lock to ensure that no +- * subsystems moved between hierarchies while we were doing so. +- * +- * Possible TODO: decide at boot time based on the number of +- * registered subsystems and the number of CPUs or NUMA nodes whether +- * it's better for performance to ref-count every subsystem, or to +- * take a global lock and only add one ref count to each hierarchy. +- */ +- +-/* +- * unlink a css_set from the list and free it +- */ +-static void unlink_css_set(struct css_set *cg) ++static void __put_css_set(struct css_set *cg, int taskexit) + { + struct cg_cgroup_link *link; + struct cg_cgroup_link *saved_link; +- +- hlist_del(&cg->hlist); +- css_set_count--; +- +- list_for_each_entry_safe(link, saved_link, &cg->cg_links, +- cg_link_list) { +- list_del(&link->cg_link_list); +- list_del(&link->cgrp_link_list); +- kfree(link); +- } +-} +- +-static void __put_css_set(struct css_set *cg, int taskexit) +-{ +- int i; + /* + * Ensure that the refcount doesn't hit zero while any readers + * can see it. Similar to atomic_dec_and_lock(), but for an +@@ -302,21 +295,28 @@ static void __put_css_set(struct css_set *cg, int taskexit) + write_unlock(&css_set_lock); + return; + } +- unlink_css_set(cg); +- write_unlock(&css_set_lock); + +- rcu_read_lock(); +- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { +- struct cgroup *cgrp = rcu_dereference(cg->subsys[i]->cgroup); ++ /* This css_set is dead. unlink it and release cgroup refcounts */ ++ hlist_del(&cg->hlist); ++ css_set_count--; ++ ++ list_for_each_entry_safe(link, saved_link, &cg->cg_links, ++ cg_link_list) { ++ struct cgroup *cgrp = link->cgrp; ++ list_del(&link->cg_link_list); ++ list_del(&link->cgrp_link_list); + if (atomic_dec_and_test(&cgrp->count) && + notify_on_release(cgrp)) { + if (taskexit) + set_bit(CGRP_RELEASABLE, &cgrp->flags); + check_for_release(cgrp); + } ++ ++ kfree(link); + } +- rcu_read_unlock(); +- kfree(cg); ++ ++ write_unlock(&css_set_lock); ++ call_rcu(&cg->rcu_head, free_css_set_rcu); + } + + /* +@@ -338,6 +338,78 @@ static inline void put_css_set_taskexit(struct css_set *cg) + } + + /* ++ * compare_css_sets - helper function for find_existing_css_set(). ++ * @cg: candidate css_set being tested ++ * @old_cg: existing css_set for a task ++ * @new_cgrp: cgroup that's being entered by the task ++ * @template: desired set of css pointers in css_set (pre-calculated) ++ * ++ * Returns true if "cg" matches "old_cg" except for the hierarchy ++ * which "new_cgrp" belongs to, for which it should match "new_cgrp". ++ */ ++static bool compare_css_sets(struct css_set *cg, ++ struct css_set *old_cg, ++ struct cgroup *new_cgrp, ++ struct cgroup_subsys_state *template[]) ++{ ++ struct list_head *l1, *l2; ++ ++ if (memcmp(template, cg->subsys, sizeof(cg->subsys))) { ++ /* Not all subsystems matched */ ++ return false; ++ } ++ ++ /* ++ * Compare cgroup pointers in order to distinguish between ++ * different cgroups in heirarchies with no subsystems. We ++ * could get by with just this check alone (and skip the ++ * memcmp above) but on most setups the memcmp check will ++ * avoid the need for this more expensive check on almost all ++ * candidates. ++ */ ++ ++ l1 = &cg->cg_links; ++ l2 = &old_cg->cg_links; ++ while (1) { ++ struct cg_cgroup_link *cgl1, *cgl2; ++ struct cgroup *cg1, *cg2; ++ ++ l1 = l1->next; ++ l2 = l2->next; ++ /* See if we reached the end - both lists are equal length. */ ++ if (l1 == &cg->cg_links) { ++ BUG_ON(l2 != &old_cg->cg_links); ++ break; ++ } else { ++ BUG_ON(l2 == &old_cg->cg_links); ++ } ++ /* Locate the cgroups associated with these links. */ ++ cgl1 = list_entry(l1, struct cg_cgroup_link, cg_link_list); ++ cgl2 = list_entry(l2, struct cg_cgroup_link, cg_link_list); ++ cg1 = cgl1->cgrp; ++ cg2 = cgl2->cgrp; ++ /* Hierarchies should be linked in the same order. */ ++ BUG_ON(cg1->root != cg2->root); ++ ++ /* ++ * If this hierarchy is the hierarchy of the cgroup ++ * that's changing, then we need to check that this ++ * css_set points to the new cgroup; if it's any other ++ * hierarchy, then this css_set should point to the ++ * same cgroup as the old css_set. ++ */ ++ if (cg1->root == new_cgrp->root) { ++ if (cg1 != new_cgrp) ++ return false; ++ } else { ++ if (cg1 != cg2) ++ return false; ++ } ++ } ++ return true; ++} ++ ++/* + * find_existing_css_set() is a helper for + * find_css_set(), and checks to see whether an existing + * css_set is suitable. +@@ -378,10 +450,11 @@ static struct css_set *find_existing_css_set( + + hhead = css_set_hash(template); + hlist_for_each_entry(cg, node, hhead, hlist) { +- if (!memcmp(template, cg->subsys, sizeof(cg->subsys))) { +- /* All subsystems matched */ +- return cg; +- } ++ if (!compare_css_sets(cg, oldcg, cgrp, template)) ++ continue; ++ ++ /* This css_set matches what we need */ ++ return cg; + } + + /* No existing cgroup group matched */ +@@ -435,8 +508,14 @@ static void link_css_set(struct list_head *tmp_cg_links, + link = list_first_entry(tmp_cg_links, struct cg_cgroup_link, + cgrp_link_list); + link->cg = cg; ++ link->cgrp = cgrp; ++ atomic_inc(&cgrp->count); + list_move(&link->cgrp_link_list, &cgrp->css_sets); +- list_add(&link->cg_link_list, &cg->cg_links); ++ /* ++ * Always add links to the tail of the list so that the list ++ * is sorted by order of hierarchy creation ++ */ ++ list_add_tail(&link->cg_link_list, &cg->cg_links); + } + + /* +@@ -451,11 +530,11 @@ static struct css_set *find_css_set( + { + struct css_set *res; + struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT]; +- int i; + + struct list_head tmp_cg_links; + + struct hlist_head *hhead; ++ struct cg_cgroup_link *link; + + /* First see if we already have a cgroup group that matches + * the desired set */ +@@ -489,20 +568,12 @@ static struct css_set *find_css_set( + + write_lock(&css_set_lock); + /* Add reference counts and links from the new css_set. */ +- for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { +- struct cgroup *cgrp = res->subsys[i]->cgroup; +- struct cgroup_subsys *ss = subsys[i]; +- atomic_inc(&cgrp->count); +- /* +- * We want to add a link once per cgroup, so we +- * only do it for the first subsystem in each +- * hierarchy +- */ +- if (ss->root->subsys_list.next == &ss->sibling) +- link_css_set(&tmp_cg_links, res, cgrp); ++ list_for_each_entry(link, &oldcg->cg_links, cg_link_list) { ++ struct cgroup *c = link->cgrp; ++ if (c->root == cgrp->root) ++ c = cgrp; ++ link_css_set(&tmp_cg_links, res, c); + } +- if (list_empty(&rootnode.subsys_list)) +- link_css_set(&tmp_cg_links, res, dummytop); + + BUG_ON(!list_empty(&tmp_cg_links)); + +@@ -518,6 +589,41 @@ static struct css_set *find_css_set( + } + + /* ++ * Return the cgroup for "task" from the given hierarchy. Must be ++ * called with cgroup_mutex held. ++ */ ++static struct cgroup *task_cgroup_from_root(struct task_struct *task, ++ struct cgroupfs_root *root) ++{ ++ struct css_set *css; ++ struct cgroup *res = NULL; ++ ++ BUG_ON(!mutex_is_locked(&cgroup_mutex)); ++ read_lock(&css_set_lock); ++ /* ++ * No need to lock the task - since we hold cgroup_mutex the ++ * task can't change groups, so the only thing that can happen ++ * is that it exits and its css is set back to init_css_set. ++ */ ++ css = task->cgroups; ++ if (css == &init_css_set) { ++ res = &root->top_cgroup; ++ } else { ++ struct cg_cgroup_link *link; ++ list_for_each_entry(link, &css->cg_links, cg_link_list) { ++ struct cgroup *c = link->cgrp; ++ if (c->root == root) { ++ res = c; ++ break; ++ } ++ } ++ } ++ read_unlock(&css_set_lock); ++ BUG_ON(!res); ++ return res; ++} ++ ++/* + * There is one global cgroup mutex. We also require taking + * task_lock() when dereferencing a task's cgroup subsys pointers. + * See "The task_lock() exception", at the end of this comment. +@@ -596,10 +702,11 @@ void cgroup_unlock(void) static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); static int cgroup_populate_dir(struct cgroup *cgrp); @@ -1695800,7 +1776253,147 @@ index b6eadfe..cd83d99 100644 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, }; -@@ -960,7 +961,7 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data) +@@ -676,6 +783,12 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) + */ + deactivate_super(cgrp->root->sb); + ++ /* ++ * if we're getting rid of the cgroup, refcount should ensure ++ * that there are no pidlists left. ++ */ ++ BUG_ON(!list_empty(&cgrp->pidlists)); ++ + call_rcu(&cgrp->rcu_head, free_cgroup_rcu); + } + iput(inode); +@@ -840,6 +953,8 @@ static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs) + seq_puts(seq, ",noprefix"); + if (strlen(root->release_agent_path)) + seq_printf(seq, ",release_agent=%s", root->release_agent_path); ++ if (strlen(root->name)) ++ seq_printf(seq, ",name=%s", root->name); + mutex_unlock(&cgroup_mutex); + return 0; + } +@@ -848,6 +963,12 @@ struct cgroup_sb_opts { + unsigned long subsys_bits; + unsigned long flags; + char *release_agent; ++ char *name; ++ /* User explicitly requested empty subsystem */ ++ bool none; ++ ++ struct cgroupfs_root *new_root; ++ + }; + + /* Convert a hierarchy specifier into a bitmask of subsystems and +@@ -862,9 +983,7 @@ static int parse_cgroupfs_options(char *data, + mask = ~(1UL << cpuset_subsys_id); + #endif + +- opts->subsys_bits = 0; +- opts->flags = 0; +- opts->release_agent = NULL; ++ memset(opts, 0, sizeof(*opts)); + + while ((token = strsep(&o, ",")) != NULL) { + if (!*token) +@@ -878,17 +997,42 @@ static int parse_cgroupfs_options(char *data, + if (!ss->disabled) + opts->subsys_bits |= 1ul << i; + } ++ } else if (!strcmp(token, "none")) { ++ /* Explicitly have no subsystems */ ++ opts->none = true; + } else if (!strcmp(token, "noprefix")) { + set_bit(ROOT_NOPREFIX, &opts->flags); + } else if (!strncmp(token, "release_agent=", 14)) { + /* Specifying two release agents is forbidden */ + if (opts->release_agent) + return -EINVAL; +- opts->release_agent = kzalloc(PATH_MAX, GFP_KERNEL); ++ opts->release_agent = ++ kstrndup(token + 14, PATH_MAX, GFP_KERNEL); + if (!opts->release_agent) + return -ENOMEM; +- strncpy(opts->release_agent, token + 14, PATH_MAX - 1); +- opts->release_agent[PATH_MAX - 1] = 0; ++ } else if (!strncmp(token, "name=", 5)) { ++ int i; ++ const char *name = token + 5; ++ /* Can't specify an empty name */ ++ if (!strlen(name)) ++ return -EINVAL; ++ /* Must match [\w.-]+ */ ++ for (i = 0; i < strlen(name); i++) { ++ char c = name[i]; ++ if (isalnum(c)) ++ continue; ++ if ((c == '.') || (c == '-') || (c == '_')) ++ continue; ++ return -EINVAL; ++ } ++ /* Specifying two names is forbidden */ ++ if (opts->name) ++ return -EINVAL; ++ opts->name = kstrndup(name, ++ MAX_CGROUP_ROOT_NAMELEN, ++ GFP_KERNEL); ++ if (!opts->name) ++ return -ENOMEM; + } else { + struct cgroup_subsys *ss; + int i; +@@ -905,6 +1049,8 @@ static int parse_cgroupfs_options(char *data, + } + } + ++ /* Consistency checks */ ++ + /* + * Option noprefix was introduced just for backward compatibility + * with the old cpuset, so we allow noprefix only if mounting just +@@ -914,8 +1060,16 @@ static int parse_cgroupfs_options(char *data, + (opts->subsys_bits & mask)) + return -EINVAL; + +- /* We can't have an empty hierarchy */ +- if (!opts->subsys_bits) ++ ++ /* Can't specify "none" and some subsystems */ ++ if (opts->subsys_bits && opts->none) ++ return -EINVAL; ++ ++ /* ++ * We either have to specify by name or by subsystems. (So all ++ * empty hierarchies must have a name). ++ */ ++ if (!opts->subsys_bits && !opts->name) + return -EINVAL; + + return 0; +@@ -943,6 +1097,12 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data) + goto out_unlock; + } + ++ /* Don't allow name to change at remount */ ++ if (opts.name && strcmp(opts.name, root->name)) { ++ ret = -EINVAL; ++ goto out_unlock; ++ } ++ + ret = rebind_subsystems(root, opts.subsys_bits); + if (ret) + goto out_unlock; +@@ -954,13 +1114,14 @@ static int cgroup_remount(struct super_block *sb, int *flags, char *data) + strcpy(root->release_agent_path, opts.release_agent); + out_unlock: + kfree(opts.release_agent); ++ kfree(opts.name); + mutex_unlock(&cgroup_mutex); + mutex_unlock(&cgrp->dentry->d_inode->i_mutex); + unlock_kernel(); return ret; } @@ -1695809,7 +1776402,352 @@ index b6eadfe..cd83d99 100644 .statfs = simple_statfs, .drop_inode = generic_delete_inode, .show_options = cgroup_show_options, -@@ -1710,7 +1711,7 @@ static struct file_operations cgroup_file_operations = { +@@ -973,9 +1134,10 @@ static void init_cgroup_housekeeping(struct cgroup *cgrp) + INIT_LIST_HEAD(&cgrp->children); + INIT_LIST_HEAD(&cgrp->css_sets); + INIT_LIST_HEAD(&cgrp->release_list); +- INIT_LIST_HEAD(&cgrp->pids_list); +- init_rwsem(&cgrp->pids_mutex); ++ INIT_LIST_HEAD(&cgrp->pidlists); ++ mutex_init(&cgrp->pidlist_mutex); + } ++ + static void init_cgroup_root(struct cgroupfs_root *root) + { + struct cgroup *cgrp = &root->top_cgroup; +@@ -987,33 +1149,106 @@ static void init_cgroup_root(struct cgroupfs_root *root) + init_cgroup_housekeeping(cgrp); + } + ++static bool init_root_id(struct cgroupfs_root *root) ++{ ++ int ret = 0; ++ ++ do { ++ if (!ida_pre_get(&hierarchy_ida, GFP_KERNEL)) ++ return false; ++ spin_lock(&hierarchy_id_lock); ++ /* Try to allocate the next unused ID */ ++ ret = ida_get_new_above(&hierarchy_ida, next_hierarchy_id, ++ &root->hierarchy_id); ++ if (ret == -ENOSPC) ++ /* Try again starting from 0 */ ++ ret = ida_get_new(&hierarchy_ida, &root->hierarchy_id); ++ if (!ret) { ++ next_hierarchy_id = root->hierarchy_id + 1; ++ } else if (ret != -EAGAIN) { ++ /* Can only get here if the 31-bit IDR is full ... */ ++ BUG_ON(ret); ++ } ++ spin_unlock(&hierarchy_id_lock); ++ } while (ret); ++ return true; ++} ++ + static int cgroup_test_super(struct super_block *sb, void *data) + { +- struct cgroupfs_root *new = data; ++ struct cgroup_sb_opts *opts = data; + struct cgroupfs_root *root = sb->s_fs_info; + +- /* First check subsystems */ +- if (new->subsys_bits != root->subsys_bits) +- return 0; ++ /* If we asked for a name then it must match */ ++ if (opts->name && strcmp(opts->name, root->name)) ++ return 0; + +- /* Next check flags */ +- if (new->flags != root->flags) ++ /* ++ * If we asked for subsystems (or explicitly for no ++ * subsystems) then they must match ++ */ ++ if ((opts->subsys_bits || opts->none) ++ && (opts->subsys_bits != root->subsys_bits)) + return 0; + + return 1; + } + ++static struct cgroupfs_root *cgroup_root_from_opts(struct cgroup_sb_opts *opts) ++{ ++ struct cgroupfs_root *root; ++ ++ if (!opts->subsys_bits && !opts->none) ++ return NULL; ++ ++ root = kzalloc(sizeof(*root), GFP_KERNEL); ++ if (!root) ++ return ERR_PTR(-ENOMEM); ++ ++ if (!init_root_id(root)) { ++ kfree(root); ++ return ERR_PTR(-ENOMEM); ++ } ++ init_cgroup_root(root); ++ ++ root->subsys_bits = opts->subsys_bits; ++ root->flags = opts->flags; ++ if (opts->release_agent) ++ strcpy(root->release_agent_path, opts->release_agent); ++ if (opts->name) ++ strcpy(root->name, opts->name); ++ return root; ++} ++ ++static void cgroup_drop_root(struct cgroupfs_root *root) ++{ ++ if (!root) ++ return; ++ ++ BUG_ON(!root->hierarchy_id); ++ spin_lock(&hierarchy_id_lock); ++ ida_remove(&hierarchy_ida, root->hierarchy_id); ++ spin_unlock(&hierarchy_id_lock); ++ kfree(root); ++} ++ + static int cgroup_set_super(struct super_block *sb, void *data) + { + int ret; +- struct cgroupfs_root *root = data; ++ struct cgroup_sb_opts *opts = data; ++ ++ /* If we don't have a new root, we can't set up a new sb */ ++ if (!opts->new_root) ++ return -EINVAL; ++ ++ BUG_ON(!opts->subsys_bits && !opts->none); + + ret = set_anon_super(sb, NULL); + if (ret) + return ret; + +- sb->s_fs_info = root; +- root->sb = sb; ++ sb->s_fs_info = opts->new_root; ++ opts->new_root->sb = sb; + + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +@@ -1050,48 +1285,43 @@ static int cgroup_get_sb(struct file_system_type *fs_type, + void *data, struct vfsmount *mnt) + { + struct cgroup_sb_opts opts; ++ struct cgroupfs_root *root; + int ret = 0; + struct super_block *sb; +- struct cgroupfs_root *root; +- struct list_head tmp_cg_links; ++ struct cgroupfs_root *new_root; + + /* First find the desired set of subsystems */ + ret = parse_cgroupfs_options(data, &opts); +- if (ret) { +- kfree(opts.release_agent); +- return ret; +- } +- +- root = kzalloc(sizeof(*root), GFP_KERNEL); +- if (!root) { +- kfree(opts.release_agent); +- return -ENOMEM; +- } ++ if (ret) ++ goto out_err; + +- init_cgroup_root(root); +- root->subsys_bits = opts.subsys_bits; +- root->flags = opts.flags; +- if (opts.release_agent) { +- strcpy(root->release_agent_path, opts.release_agent); +- kfree(opts.release_agent); ++ /* ++ * Allocate a new cgroup root. We may not need it if we're ++ * reusing an existing hierarchy. ++ */ ++ new_root = cgroup_root_from_opts(&opts); ++ if (IS_ERR(new_root)) { ++ ret = PTR_ERR(new_root); ++ goto out_err; + } ++ opts.new_root = new_root; + +- sb = sget(fs_type, cgroup_test_super, cgroup_set_super, root); +- ++ /* Locate an existing or new sb for this hierarchy */ ++ sb = sget(fs_type, cgroup_test_super, cgroup_set_super, &opts); + if (IS_ERR(sb)) { +- kfree(root); +- return PTR_ERR(sb); ++ ret = PTR_ERR(sb); ++ cgroup_drop_root(opts.new_root); ++ goto out_err; + } + +- if (sb->s_fs_info != root) { +- /* Reusing an existing superblock */ +- BUG_ON(sb->s_root == NULL); +- kfree(root); +- root = NULL; +- } else { +- /* New superblock */ ++ root = sb->s_fs_info; ++ BUG_ON(!root); ++ if (root == opts.new_root) { ++ /* We used the new root structure, so this is a new hierarchy */ ++ struct list_head tmp_cg_links; + struct cgroup *root_cgrp = &root->top_cgroup; + struct inode *inode; ++ struct cgroupfs_root *existing_root; + int i; + + BUG_ON(sb->s_root != NULL); +@@ -1104,6 +1334,18 @@ static int cgroup_get_sb(struct file_system_type *fs_type, + mutex_lock(&inode->i_mutex); + mutex_lock(&cgroup_mutex); + ++ if (strlen(root->name)) { ++ /* Check for name clashes with existing mounts */ ++ for_each_active_root(existing_root) { ++ if (!strcmp(existing_root->name, root->name)) { ++ ret = -EBUSY; ++ mutex_unlock(&cgroup_mutex); ++ mutex_unlock(&inode->i_mutex); ++ goto drop_new_super; ++ } ++ } ++ } ++ + /* + * We're accessing css_set_count without locking + * css_set_lock here, but that's OK - it can only be +@@ -1122,7 +1364,8 @@ static int cgroup_get_sb(struct file_system_type *fs_type, + if (ret == -EBUSY) { + mutex_unlock(&cgroup_mutex); + mutex_unlock(&inode->i_mutex); +- goto free_cg_links; ++ free_cg_links(&tmp_cg_links); ++ goto drop_new_super; + } + + /* EBUSY should be the only error here */ +@@ -1154,17 +1397,27 @@ static int cgroup_get_sb(struct file_system_type *fs_type, + BUG_ON(root->number_of_cgroups != 1); + + cgroup_populate_dir(root_cgrp); +- mutex_unlock(&inode->i_mutex); + mutex_unlock(&cgroup_mutex); ++ mutex_unlock(&inode->i_mutex); ++ } else { ++ /* ++ * We re-used an existing hierarchy - the new root (if ++ * any) is not needed ++ */ ++ cgroup_drop_root(opts.new_root); + } + + simple_set_mnt(mnt, sb); ++ kfree(opts.release_agent); ++ kfree(opts.name); + return 0; + +- free_cg_links: +- free_cg_links(&tmp_cg_links); + drop_new_super: + deactivate_locked_super(sb); ++ out_err: ++ kfree(opts.release_agent); ++ kfree(opts.name); ++ + return ret; + } + +@@ -1210,7 +1463,7 @@ static void cgroup_kill_sb(struct super_block *sb) { + mutex_unlock(&cgroup_mutex); + + kill_litter_super(sb); +- kfree(root); ++ cgroup_drop_root(root); + } + + static struct file_system_type cgroup_fs_type = { +@@ -1275,27 +1528,6 @@ int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) + return 0; + } + +-/* +- * Return the first subsystem attached to a cgroup's hierarchy, and +- * its subsystem id. +- */ +- +-static void get_first_subsys(const struct cgroup *cgrp, +- struct cgroup_subsys_state **css, int *subsys_id) +-{ +- const struct cgroupfs_root *root = cgrp->root; +- const struct cgroup_subsys *test_ss; +- BUG_ON(list_empty(&root->subsys_list)); +- test_ss = list_entry(root->subsys_list.next, +- struct cgroup_subsys, sibling); +- if (css) { +- *css = cgrp->subsys[test_ss->subsys_id]; +- BUG_ON(!*css); +- } +- if (subsys_id) +- *subsys_id = test_ss->subsys_id; +-} +- + /** + * cgroup_attach_task - attach task 'tsk' to cgroup 'cgrp' + * @cgrp: the cgroup the task is attaching to +@@ -1312,18 +1544,15 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) + struct css_set *cg; + struct css_set *newcg; + struct cgroupfs_root *root = cgrp->root; +- int subsys_id; +- +- get_first_subsys(cgrp, NULL, &subsys_id); + + /* Nothing to do if the task is already in that cgroup */ +- oldcgrp = task_cgroup(tsk, subsys_id); ++ oldcgrp = task_cgroup_from_root(tsk, root); + if (cgrp == oldcgrp) + return 0; + + for_each_subsys(root, ss) { + if (ss->can_attach) { +- retval = ss->can_attach(ss, cgrp, tsk); ++ retval = ss->can_attach(ss, cgrp, tsk, false); + if (retval) + return retval; + } +@@ -1361,7 +1590,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk) + + for_each_subsys(root, ss) { + if (ss->attach) +- ss->attach(ss, cgrp, oldcgrp, tsk); ++ ss->attach(ss, cgrp, oldcgrp, tsk, false); + } + set_bit(CGRP_RELEASABLE, &oldcgrp->flags); + synchronize_rcu(); +@@ -1422,15 +1651,6 @@ static int cgroup_tasks_write(struct cgroup *cgrp, struct cftype *cft, u64 pid) + return ret; + } + +-/* The various types of files and directories in a cgroup file system */ +-enum cgroup_filetype { +- FILE_ROOT, +- FILE_DIR, +- FILE_TASKLIST, +- FILE_NOTIFY_ON_RELEASE, +- FILE_RELEASE_AGENT, +-}; +- + /** + * cgroup_lock_live_group - take cgroup_mutex and check that cgrp is alive. + * @cgrp: the cgroup to be checked for liveness +@@ -1710,7 +1930,7 @@ static struct file_operations cgroup_file_operations = { .release = cgroup_file_release, }; @@ -1695818,15 +1776756,929 @@ index b6eadfe..cd83d99 100644 .lookup = simple_lookup, .mkdir = cgroup_mkdir, .rmdir = cgroup_rmdir, -@@ -2313,7 +2314,7 @@ static int cgroup_tasks_show(struct seq_file *s, void *v) +@@ -1875,7 +2095,7 @@ int cgroup_task_count(const struct cgroup *cgrp) + * the start of a css_set + */ + static void cgroup_advance_iter(struct cgroup *cgrp, +- struct cgroup_iter *it) ++ struct cgroup_iter *it) + { + struct list_head *l = it->cg_link; + struct cg_cgroup_link *link; +@@ -2128,7 +2348,7 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan) + } + + /* +- * Stuff for reading the 'tasks' file. ++ * Stuff for reading the 'tasks'/'procs' files. + * + * Reading this file can return large amounts of data if a cgroup has + * *lots* of attached tasks. So it may need several calls to read(), +@@ -2138,27 +2358,196 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan) + */ + + /* +- * Load into 'pidarray' up to 'npids' of the tasks using cgroup +- * 'cgrp'. Return actual number of pids loaded. No need to +- * task_lock(p) when reading out p->cgroup, since we're in an RCU +- * read section, so the css_set can't go away, and is +- * immutable after creation. ++ * The following two functions "fix" the issue where there are more pids ++ * than kmalloc will give memory for; in such cases, we use vmalloc/vfree. ++ * TODO: replace with a kernel-wide solution to this problem ++ */ ++#define PIDLIST_TOO_LARGE(c) ((c) * sizeof(pid_t) > (PAGE_SIZE * 2)) ++static void *pidlist_allocate(int count) ++{ ++ if (PIDLIST_TOO_LARGE(count)) ++ return vmalloc(count * sizeof(pid_t)); ++ else ++ return kmalloc(count * sizeof(pid_t), GFP_KERNEL); ++} ++static void pidlist_free(void *p) ++{ ++ if (is_vmalloc_addr(p)) ++ vfree(p); ++ else ++ kfree(p); ++} ++static void *pidlist_resize(void *p, int newcount) ++{ ++ void *newlist; ++ /* note: if new alloc fails, old p will still be valid either way */ ++ if (is_vmalloc_addr(p)) { ++ newlist = vmalloc(newcount * sizeof(pid_t)); ++ if (!newlist) ++ return NULL; ++ memcpy(newlist, p, newcount * sizeof(pid_t)); ++ vfree(p); ++ } else { ++ newlist = krealloc(p, newcount * sizeof(pid_t), GFP_KERNEL); ++ } ++ return newlist; ++} ++ ++/* ++ * pidlist_uniq - given a kmalloc()ed list, strip out all duplicate entries ++ * If the new stripped list is sufficiently smaller and there's enough memory ++ * to allocate a new buffer, will let go of the unneeded memory. Returns the ++ * number of unique elements. ++ */ ++/* is the size difference enough that we should re-allocate the array? */ ++#define PIDLIST_REALLOC_DIFFERENCE(old, new) ((old) - PAGE_SIZE >= (new)) ++static int pidlist_uniq(pid_t **p, int length) ++{ ++ int src, dest = 1; ++ pid_t *list = *p; ++ pid_t *newlist; ++ ++ /* ++ * we presume the 0th element is unique, so i starts at 1. trivial ++ * edge cases first; no work needs to be done for either ++ */ ++ if (length == 0 || length == 1) ++ return length; ++ /* src and dest walk down the list; dest counts unique elements */ ++ for (src = 1; src < length; src++) { ++ /* find next unique element */ ++ while (list[src] == list[src-1]) { ++ src++; ++ if (src == length) ++ goto after; ++ } ++ /* dest always points to where the next unique element goes */ ++ list[dest] = list[src]; ++ dest++; ++ } ++after: ++ /* ++ * if the length difference is large enough, we want to allocate a ++ * smaller buffer to save memory. if this fails due to out of memory, ++ * we'll just stay with what we've got. ++ */ ++ if (PIDLIST_REALLOC_DIFFERENCE(length, dest)) { ++ newlist = pidlist_resize(list, dest); ++ if (newlist) ++ *p = newlist; ++ } ++ return dest; ++} ++ ++static int cmppid(const void *a, const void *b) ++{ ++ return *(pid_t *)a - *(pid_t *)b; ++} ++ ++/* ++ * find the appropriate pidlist for our purpose (given procs vs tasks) ++ * returns with the lock on that pidlist already held, and takes care ++ * of the use count, or returns NULL with no locks held if we're out of ++ * memory. + */ +-static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp) ++static struct cgroup_pidlist *cgroup_pidlist_find(struct cgroup *cgrp, ++ enum cgroup_filetype type) + { +- int n = 0, pid; ++ struct cgroup_pidlist *l; ++ /* don't need task_nsproxy() if we're looking at ourself */ ++ struct pid_namespace *ns = get_pid_ns(current->nsproxy->pid_ns); ++ /* ++ * We can't drop the pidlist_mutex before taking the l->mutex in case ++ * the last ref-holder is trying to remove l from the list at the same ++ * time. Holding the pidlist_mutex precludes somebody taking whichever ++ * list we find out from under us - compare release_pid_array(). ++ */ ++ mutex_lock(&cgrp->pidlist_mutex); ++ list_for_each_entry(l, &cgrp->pidlists, links) { ++ if (l->key.type == type && l->key.ns == ns) { ++ /* found a matching list - drop the extra refcount */ ++ put_pid_ns(ns); ++ /* make sure l doesn't vanish out from under us */ ++ down_write(&l->mutex); ++ mutex_unlock(&cgrp->pidlist_mutex); ++ l->use_count++; ++ return l; ++ } ++ } ++ /* entry not found; create a new one */ ++ l = kmalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL); ++ if (!l) { ++ mutex_unlock(&cgrp->pidlist_mutex); ++ put_pid_ns(ns); ++ return l; ++ } ++ init_rwsem(&l->mutex); ++ down_write(&l->mutex); ++ l->key.type = type; ++ l->key.ns = ns; ++ l->use_count = 0; /* don't increment here */ ++ l->list = NULL; ++ l->owner = cgrp; ++ list_add(&l->links, &cgrp->pidlists); ++ mutex_unlock(&cgrp->pidlist_mutex); ++ return l; ++} ++ ++/* ++ * Load a cgroup's pidarray with either procs' tgids or tasks' pids ++ */ ++static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type, ++ struct cgroup_pidlist **lp) ++{ ++ pid_t *array; ++ int length; ++ int pid, n = 0; /* used for populating the array */ + struct cgroup_iter it; + struct task_struct *tsk; ++ struct cgroup_pidlist *l; ++ ++ /* ++ * If cgroup gets more users after we read count, we won't have ++ * enough space - tough. This race is indistinguishable to the ++ * caller from the case that the additional cgroup users didn't ++ * show up until sometime later on. ++ */ ++ length = cgroup_task_count(cgrp); ++ array = pidlist_allocate(length); ++ if (!array) ++ return -ENOMEM; ++ /* now, populate the array */ + cgroup_iter_start(cgrp, &it); + while ((tsk = cgroup_iter_next(cgrp, &it))) { +- if (unlikely(n == npids)) ++ if (unlikely(n == length)) + break; +- pid = task_pid_vnr(tsk); +- if (pid > 0) +- pidarray[n++] = pid; ++ /* get tgid or pid for procs or tasks file respectively */ ++ if (type == CGROUP_FILE_PROCS) ++ pid = task_tgid_vnr(tsk); ++ else ++ pid = task_pid_vnr(tsk); ++ if (pid > 0) /* make sure to only use valid results */ ++ array[n++] = pid; + } + cgroup_iter_end(cgrp, &it); +- return n; ++ length = n; ++ /* now sort & (if procs) strip out duplicates */ ++ sort(array, length, sizeof(pid_t), cmppid, NULL); ++ if (type == CGROUP_FILE_PROCS) ++ length = pidlist_uniq(&array, length); ++ l = cgroup_pidlist_find(cgrp, type); ++ if (!l) { ++ pidlist_free(array); ++ return -ENOMEM; ++ } ++ /* store array, freeing old if necessary - lock already held */ ++ pidlist_free(l->list); ++ l->list = array; ++ l->length = length; ++ l->use_count++; ++ up_write(&l->mutex); ++ *lp = l; ++ return 0; + } + + /** +@@ -2215,37 +2604,14 @@ err: + return ret; + } + +-/* +- * Cache pids for all threads in the same pid namespace that are +- * opening the same "tasks" file. +- */ +-struct cgroup_pids { +- /* The node in cgrp->pids_list */ +- struct list_head list; +- /* The cgroup those pids belong to */ +- struct cgroup *cgrp; +- /* The namepsace those pids belong to */ +- struct pid_namespace *ns; +- /* Array of process ids in the cgroup */ +- pid_t *tasks_pids; +- /* How many files are using the this tasks_pids array */ +- int use_count; +- /* Length of the current tasks_pids array */ +- int length; +-}; +- +-static int cmppid(const void *a, const void *b) +-{ +- return *(pid_t *)a - *(pid_t *)b; +-} + + /* +- * seq_file methods for the "tasks" file. The seq_file position is the ++ * seq_file methods for the tasks/procs files. The seq_file position is the + * next pid to display; the seq_file iterator is a pointer to the pid +- * in the cgroup->tasks_pids array. ++ * in the cgroup->l->list array. + */ + +-static void *cgroup_tasks_start(struct seq_file *s, loff_t *pos) ++static void *cgroup_pidlist_start(struct seq_file *s, loff_t *pos) + { + /* + * Initially we receive a position value that corresponds to +@@ -2253,48 +2619,45 @@ static void *cgroup_tasks_start(struct seq_file *s, loff_t *pos) + * after a seek to the start). Use a binary-search to find the + * next pid to display, if any + */ +- struct cgroup_pids *cp = s->private; +- struct cgroup *cgrp = cp->cgrp; ++ struct cgroup_pidlist *l = s->private; + int index = 0, pid = *pos; + int *iter; + +- down_read(&cgrp->pids_mutex); ++ down_read(&l->mutex); + if (pid) { +- int end = cp->length; ++ int end = l->length; + + while (index < end) { + int mid = (index + end) / 2; +- if (cp->tasks_pids[mid] == pid) { ++ if (l->list[mid] == pid) { + index = mid; + break; +- } else if (cp->tasks_pids[mid] <= pid) ++ } else if (l->list[mid] <= pid) + index = mid + 1; + else + end = mid; + } + } + /* If we're off the end of the array, we're done */ +- if (index >= cp->length) ++ if (index >= l->length) + return NULL; + /* Update the abstract position to be the actual pid that we found */ +- iter = cp->tasks_pids + index; ++ iter = l->list + index; + *pos = *iter; + return iter; + } + +-static void cgroup_tasks_stop(struct seq_file *s, void *v) ++static void cgroup_pidlist_stop(struct seq_file *s, void *v) + { +- struct cgroup_pids *cp = s->private; +- struct cgroup *cgrp = cp->cgrp; +- up_read(&cgrp->pids_mutex); ++ struct cgroup_pidlist *l = s->private; ++ up_read(&l->mutex); + } + +-static void *cgroup_tasks_next(struct seq_file *s, void *v, loff_t *pos) ++static void *cgroup_pidlist_next(struct seq_file *s, void *v, loff_t *pos) + { +- struct cgroup_pids *cp = s->private; +- int *p = v; +- int *end = cp->tasks_pids + cp->length; +- ++ struct cgroup_pidlist *l = s->private; ++ pid_t *p = v; ++ pid_t *end = l->list + l->length; + /* + * Advance to the next pid in the array. If this goes off the + * end, we're done +@@ -2308,124 +2671,107 @@ static void *cgroup_tasks_next(struct seq_file *s, void *v, loff_t *pos) + } + } + +-static int cgroup_tasks_show(struct seq_file *s, void *v) ++static int cgroup_pidlist_show(struct seq_file *s, void *v) + { return seq_printf(s, "%d\n", *(int *)v); } -static struct seq_operations cgroup_tasks_seq_operations = { -+static const struct seq_operations cgroup_tasks_seq_operations = { - .start = cgroup_tasks_start, - .stop = cgroup_tasks_stop, - .next = cgroup_tasks_next, +- .start = cgroup_tasks_start, +- .stop = cgroup_tasks_stop, +- .next = cgroup_tasks_next, +- .show = cgroup_tasks_show, ++/* ++ * seq_operations functions for iterating on pidlists through seq_file - ++ * independent of whether it's tasks or procs ++ */ ++static const struct seq_operations cgroup_pidlist_seq_operations = { ++ .start = cgroup_pidlist_start, ++ .stop = cgroup_pidlist_stop, ++ .next = cgroup_pidlist_next, ++ .show = cgroup_pidlist_show, + }; + +-static void release_cgroup_pid_array(struct cgroup_pids *cp) ++static void cgroup_release_pid_array(struct cgroup_pidlist *l) + { +- struct cgroup *cgrp = cp->cgrp; +- +- down_write(&cgrp->pids_mutex); +- BUG_ON(!cp->use_count); +- if (!--cp->use_count) { +- list_del(&cp->list); +- put_pid_ns(cp->ns); +- kfree(cp->tasks_pids); +- kfree(cp); ++ /* ++ * the case where we're the last user of this particular pidlist will ++ * have us remove it from the cgroup's list, which entails taking the ++ * mutex. since in pidlist_find the pidlist->lock depends on cgroup-> ++ * pidlist_mutex, we have to take pidlist_mutex first. ++ */ ++ mutex_lock(&l->owner->pidlist_mutex); ++ down_write(&l->mutex); ++ BUG_ON(!l->use_count); ++ if (!--l->use_count) { ++ /* we're the last user if refcount is 0; remove and free */ ++ list_del(&l->links); ++ mutex_unlock(&l->owner->pidlist_mutex); ++ pidlist_free(l->list); ++ put_pid_ns(l->key.ns); ++ up_write(&l->mutex); ++ kfree(l); ++ return; + } +- up_write(&cgrp->pids_mutex); ++ mutex_unlock(&l->owner->pidlist_mutex); ++ up_write(&l->mutex); + } + +-static int cgroup_tasks_release(struct inode *inode, struct file *file) ++static int cgroup_pidlist_release(struct inode *inode, struct file *file) + { +- struct seq_file *seq; +- struct cgroup_pids *cp; +- ++ struct cgroup_pidlist *l; + if (!(file->f_mode & FMODE_READ)) + return 0; +- +- seq = file->private_data; +- cp = seq->private; +- +- release_cgroup_pid_array(cp); ++ /* ++ * the seq_file will only be initialized if the file was opened for ++ * reading; hence we check if it's not null only in that case. ++ */ ++ l = ((struct seq_file *)file->private_data)->private; ++ cgroup_release_pid_array(l); + return seq_release(inode, file); + } + +-static struct file_operations cgroup_tasks_operations = { ++static const struct file_operations cgroup_pidlist_operations = { + .read = seq_read, + .llseek = seq_lseek, + .write = cgroup_file_write, +- .release = cgroup_tasks_release, ++ .release = cgroup_pidlist_release, + }; + + /* +- * Handle an open on 'tasks' file. Prepare an array containing the +- * process id's of tasks currently attached to the cgroup being opened. ++ * The following functions handle opens on a file that displays a pidlist ++ * (tasks or procs). Prepare an array of the process/thread IDs of whoever's ++ * in the cgroup. + */ +- +-static int cgroup_tasks_open(struct inode *unused, struct file *file) ++/* helper function for the two below it */ ++static int cgroup_pidlist_open(struct file *file, enum cgroup_filetype type) + { + struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); +- struct pid_namespace *ns = current->nsproxy->pid_ns; +- struct cgroup_pids *cp; +- pid_t *pidarray; +- int npids; ++ struct cgroup_pidlist *l; + int retval; + + /* Nothing to do for write-only files */ + if (!(file->f_mode & FMODE_READ)) + return 0; + +- /* +- * If cgroup gets more users after we read count, we won't have +- * enough space - tough. This race is indistinguishable to the +- * caller from the case that the additional cgroup users didn't +- * show up until sometime later on. +- */ +- npids = cgroup_task_count(cgrp); +- pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL); +- if (!pidarray) +- return -ENOMEM; +- npids = pid_array_load(pidarray, npids, cgrp); +- sort(pidarray, npids, sizeof(pid_t), cmppid, NULL); +- +- /* +- * Store the array in the cgroup, freeing the old +- * array if necessary +- */ +- down_write(&cgrp->pids_mutex); +- +- list_for_each_entry(cp, &cgrp->pids_list, list) { +- if (ns == cp->ns) +- goto found; +- } +- +- cp = kzalloc(sizeof(*cp), GFP_KERNEL); +- if (!cp) { +- up_write(&cgrp->pids_mutex); +- kfree(pidarray); +- return -ENOMEM; +- } +- cp->cgrp = cgrp; +- cp->ns = ns; +- get_pid_ns(ns); +- list_add(&cp->list, &cgrp->pids_list); +-found: +- kfree(cp->tasks_pids); +- cp->tasks_pids = pidarray; +- cp->length = npids; +- cp->use_count++; +- up_write(&cgrp->pids_mutex); +- +- file->f_op = &cgroup_tasks_operations; ++ /* have the array populated */ ++ retval = pidlist_array_load(cgrp, type, &l); ++ if (retval) ++ return retval; ++ /* configure file information */ ++ file->f_op = &cgroup_pidlist_operations; + +- retval = seq_open(file, &cgroup_tasks_seq_operations); ++ retval = seq_open(file, &cgroup_pidlist_seq_operations); + if (retval) { +- release_cgroup_pid_array(cp); ++ cgroup_release_pid_array(l); + return retval; + } +- ((struct seq_file *)file->private_data)->private = cp; ++ ((struct seq_file *)file->private_data)->private = l; + return 0; + } ++static int cgroup_tasks_open(struct inode *unused, struct file *file) ++{ ++ return cgroup_pidlist_open(file, CGROUP_FILE_TASKS); ++} ++static int cgroup_procs_open(struct inode *unused, struct file *file) ++{ ++ return cgroup_pidlist_open(file, CGROUP_FILE_PROCS); ++} + + static u64 cgroup_read_notify_on_release(struct cgroup *cgrp, + struct cftype *cft) +@@ -2448,21 +2794,27 @@ static int cgroup_write_notify_on_release(struct cgroup *cgrp, + /* + * for the common functions, 'private' gives the type of file + */ ++/* for hysterical raisins, we can't put this on the older files */ ++#define CGROUP_FILE_GENERIC_PREFIX "cgroup." + static struct cftype files[] = { + { + .name = "tasks", + .open = cgroup_tasks_open, + .write_u64 = cgroup_tasks_write, +- .release = cgroup_tasks_release, +- .private = FILE_TASKLIST, ++ .release = cgroup_pidlist_release, + .mode = S_IRUGO | S_IWUSR, + }, +- ++ { ++ .name = CGROUP_FILE_GENERIC_PREFIX "procs", ++ .open = cgroup_procs_open, ++ /* .write_u64 = cgroup_procs_write, TODO */ ++ .release = cgroup_pidlist_release, ++ .mode = S_IRUGO, ++ }, + { + .name = "notify_on_release", + .read_u64 = cgroup_read_notify_on_release, + .write_u64 = cgroup_write_notify_on_release, +- .private = FILE_NOTIFY_ON_RELEASE, + }, + }; + +@@ -2471,7 +2823,6 @@ static struct cftype cft_release_agent = { + .read_seq_string = cgroup_release_agent_show, + .write_string = cgroup_release_agent_write, + .max_write_len = PATH_MAX, +- .private = FILE_RELEASE_AGENT, + }; + + static int cgroup_populate_dir(struct cgroup *cgrp) +@@ -2878,6 +3229,7 @@ int __init cgroup_init_early(void) + init_task.cgroups = &init_css_set; + + init_css_set_link.cg = &init_css_set; ++ init_css_set_link.cgrp = dummytop; + list_add(&init_css_set_link.cgrp_link_list, + &rootnode.top_cgroup.css_sets); + list_add(&init_css_set_link.cg_link_list, +@@ -2932,7 +3284,7 @@ int __init cgroup_init(void) + /* Add init_css_set to the hash table */ + hhead = css_set_hash(init_css_set.subsys); + hlist_add_head(&init_css_set.hlist, hhead); +- ++ BUG_ON(!init_root_id(&rootnode)); + err = register_filesystem(&cgroup_fs_type); + if (err < 0) + goto out; +@@ -2985,15 +3337,16 @@ static int proc_cgroup_show(struct seq_file *m, void *v) + for_each_active_root(root) { + struct cgroup_subsys *ss; + struct cgroup *cgrp; +- int subsys_id; + int count = 0; + +- seq_printf(m, "%lu:", root->subsys_bits); ++ seq_printf(m, "%d:", root->hierarchy_id); + for_each_subsys(root, ss) + seq_printf(m, "%s%s", count++ ? "," : "", ss->name); ++ if (strlen(root->name)) ++ seq_printf(m, "%sname=%s", count ? "," : "", ++ root->name); + seq_putc(m, ':'); +- get_first_subsys(&root->top_cgroup, NULL, &subsys_id); +- cgrp = task_cgroup(tsk, subsys_id); ++ cgrp = task_cgroup_from_root(tsk, root); + retval = cgroup_path(cgrp, buf, PAGE_SIZE); + if (retval < 0) + goto out_unlock; +@@ -3032,8 +3385,8 @@ static int proc_cgroupstats_show(struct seq_file *m, void *v) + mutex_lock(&cgroup_mutex); + for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { + struct cgroup_subsys *ss = subsys[i]; +- seq_printf(m, "%s\t%lu\t%d\t%d\n", +- ss->name, ss->root->subsys_bits, ++ seq_printf(m, "%s\t%d\t%d\t%d\n", ++ ss->name, ss->root->hierarchy_id, + ss->root->number_of_cgroups, !ss->disabled); + } + mutex_unlock(&cgroup_mutex); +@@ -3319,13 +3672,11 @@ int cgroup_is_descendant(const struct cgroup *cgrp, struct task_struct *task) + { + int ret; + struct cgroup *target; +- int subsys_id; + + if (cgrp == dummytop) + return 1; + +- get_first_subsys(cgrp, NULL, &subsys_id); +- target = task_cgroup(task, subsys_id); ++ target = task_cgroup_from_root(task, cgrp->root); + while (cgrp != target && cgrp!= cgrp->top_cgroup) + cgrp = cgrp->parent; + ret = (cgrp == target); +@@ -3692,3 +4043,154 @@ css_get_next(struct cgroup_subsys *ss, int id, + return ret; + } + ++#ifdef CONFIG_CGROUP_DEBUG ++static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, ++ struct cgroup *cont) ++{ ++ struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL); ++ ++ if (!css) ++ return ERR_PTR(-ENOMEM); ++ ++ return css; ++} ++ ++static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont) ++{ ++ kfree(cont->subsys[debug_subsys_id]); ++} ++ ++static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft) ++{ ++ return atomic_read(&cont->count); ++} ++ ++static u64 debug_taskcount_read(struct cgroup *cont, struct cftype *cft) ++{ ++ return cgroup_task_count(cont); ++} ++ ++static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft) ++{ ++ return (u64)(unsigned long)current->cgroups; ++} ++ ++static u64 current_css_set_refcount_read(struct cgroup *cont, ++ struct cftype *cft) ++{ ++ u64 count; ++ ++ rcu_read_lock(); ++ count = atomic_read(¤t->cgroups->refcount); ++ rcu_read_unlock(); ++ return count; ++} ++ ++static int current_css_set_cg_links_read(struct cgroup *cont, ++ struct cftype *cft, ++ struct seq_file *seq) ++{ ++ struct cg_cgroup_link *link; ++ struct css_set *cg; ++ ++ read_lock(&css_set_lock); ++ rcu_read_lock(); ++ cg = rcu_dereference(current->cgroups); ++ list_for_each_entry(link, &cg->cg_links, cg_link_list) { ++ struct cgroup *c = link->cgrp; ++ const char *name; ++ ++ if (c->dentry) ++ name = c->dentry->d_name.name; ++ else ++ name = "?"; ++ seq_printf(seq, "Root %d group %s\n", ++ c->root->hierarchy_id, name); ++ } ++ rcu_read_unlock(); ++ read_unlock(&css_set_lock); ++ return 0; ++} ++ ++#define MAX_TASKS_SHOWN_PER_CSS 25 ++static int cgroup_css_links_read(struct cgroup *cont, ++ struct cftype *cft, ++ struct seq_file *seq) ++{ ++ struct cg_cgroup_link *link; ++ ++ read_lock(&css_set_lock); ++ list_for_each_entry(link, &cont->css_sets, cgrp_link_list) { ++ struct css_set *cg = link->cg; ++ struct task_struct *task; ++ int count = 0; ++ seq_printf(seq, "css_set %p\n", cg); ++ list_for_each_entry(task, &cg->tasks, cg_list) { ++ if (count++ > MAX_TASKS_SHOWN_PER_CSS) { ++ seq_puts(seq, " ...\n"); ++ break; ++ } else { ++ seq_printf(seq, " task %d\n", ++ task_pid_vnr(task)); ++ } ++ } ++ } ++ read_unlock(&css_set_lock); ++ return 0; ++} ++ ++static u64 releasable_read(struct cgroup *cgrp, struct cftype *cft) ++{ ++ return test_bit(CGRP_RELEASABLE, &cgrp->flags); ++} ++ ++static struct cftype debug_files[] = { ++ { ++ .name = "cgroup_refcount", ++ .read_u64 = cgroup_refcount_read, ++ }, ++ { ++ .name = "taskcount", ++ .read_u64 = debug_taskcount_read, ++ }, ++ ++ { ++ .name = "current_css_set", ++ .read_u64 = current_css_set_read, ++ }, ++ ++ { ++ .name = "current_css_set_refcount", ++ .read_u64 = current_css_set_refcount_read, ++ }, ++ ++ { ++ .name = "current_css_set_cg_links", ++ .read_seq_string = current_css_set_cg_links_read, ++ }, ++ ++ { ++ .name = "cgroup_css_links", ++ .read_seq_string = cgroup_css_links_read, ++ }, ++ ++ { ++ .name = "releasable", ++ .read_u64 = releasable_read, ++ }, ++}; ++ ++static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont) ++{ ++ return cgroup_add_files(cont, ss, debug_files, ++ ARRAY_SIZE(debug_files)); ++} ++ ++struct cgroup_subsys debug_subsys = { ++ .name = "debug", ++ .create = debug_create, ++ .destroy = debug_destroy, ++ .populate = debug_populate, ++ .subsys_id = debug_subsys_id, ++}; ++#endif /* CONFIG_CGROUP_DEBUG */ +diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c +deleted file mode 100644 +index 0c92d79..0000000 +--- a/kernel/cgroup_debug.c ++++ /dev/null +@@ -1,105 +0,0 @@ +-/* +- * kernel/cgroup_debug.c - Example cgroup subsystem that +- * exposes debug info +- * +- * Copyright (C) Google Inc, 2007 +- * +- * Developed by Paul Menage (menage@google.com) +- * +- */ +- +-#include +-#include +-#include +-#include +- +-#include +- +-static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, +- struct cgroup *cont) +-{ +- struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL); +- +- if (!css) +- return ERR_PTR(-ENOMEM); +- +- return css; +-} +- +-static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont) +-{ +- kfree(cont->subsys[debug_subsys_id]); +-} +- +-static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft) +-{ +- return atomic_read(&cont->count); +-} +- +-static u64 taskcount_read(struct cgroup *cont, struct cftype *cft) +-{ +- u64 count; +- +- count = cgroup_task_count(cont); +- return count; +-} +- +-static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft) +-{ +- return (u64)(long)current->cgroups; +-} +- +-static u64 current_css_set_refcount_read(struct cgroup *cont, +- struct cftype *cft) +-{ +- u64 count; +- +- rcu_read_lock(); +- count = atomic_read(¤t->cgroups->refcount); +- rcu_read_unlock(); +- return count; +-} +- +-static u64 releasable_read(struct cgroup *cgrp, struct cftype *cft) +-{ +- return test_bit(CGRP_RELEASABLE, &cgrp->flags); +-} +- +-static struct cftype files[] = { +- { +- .name = "cgroup_refcount", +- .read_u64 = cgroup_refcount_read, +- }, +- { +- .name = "taskcount", +- .read_u64 = taskcount_read, +- }, +- +- { +- .name = "current_css_set", +- .read_u64 = current_css_set_read, +- }, +- +- { +- .name = "current_css_set_refcount", +- .read_u64 = current_css_set_refcount_read, +- }, +- +- { +- .name = "releasable", +- .read_u64 = releasable_read, +- }, +-}; +- +-static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont) +-{ +- return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files)); +-} +- +-struct cgroup_subsys debug_subsys = { +- .name = "debug", +- .create = debug_create, +- .destroy = debug_destroy, +- .populate = debug_populate, +- .subsys_id = debug_subsys_id, +-}; +diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c +index fb249e2..59e9ef6 100644 +--- a/kernel/cgroup_freezer.c ++++ b/kernel/cgroup_freezer.c +@@ -159,7 +159,7 @@ static bool is_task_frozen_enough(struct task_struct *task) + */ + static int freezer_can_attach(struct cgroup_subsys *ss, + struct cgroup *new_cgroup, +- struct task_struct *task) ++ struct task_struct *task, bool threadgroup) + { + struct freezer *freezer; + +@@ -177,6 +177,19 @@ static int freezer_can_attach(struct cgroup_subsys *ss, + if (freezer->state == CGROUP_FROZEN) + return -EBUSY; + ++ if (threadgroup) { ++ struct task_struct *c; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &task->thread_group, thread_group) { ++ if (is_task_frozen_enough(c)) { ++ rcu_read_unlock(); ++ return -EBUSY; ++ } ++ } ++ rcu_read_unlock(); ++ } ++ + return 0; + } + diff --git a/kernel/cpu.c b/kernel/cpu.c index 8ce1004..6ba0f1e 100644 --- a/kernel/cpu.c @@ -1695875,10 +1777727,107 @@ index 8ce1004..6ba0f1e 100644 out: cpu_maps_update_done(); diff --git a/kernel/cpuset.c b/kernel/cpuset.c -index 7e75a41..b81f7f0 100644 +index 7e75a41..d247381 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c -@@ -2499,15 +2499,9 @@ const struct file_operations proc_cpuset_operations = { +@@ -1324,9 +1324,10 @@ static int fmeter_getrate(struct fmeter *fmp) + static cpumask_var_t cpus_attach; + + /* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */ +-static int cpuset_can_attach(struct cgroup_subsys *ss, +- struct cgroup *cont, struct task_struct *tsk) ++static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cont, ++ struct task_struct *tsk, bool threadgroup) + { ++ int ret; + struct cpuset *cs = cgroup_cs(cont); + + if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) +@@ -1343,18 +1344,51 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, + if (tsk->flags & PF_THREAD_BOUND) + return -EINVAL; + +- return security_task_setscheduler(tsk, 0, NULL); ++ ret = security_task_setscheduler(tsk, 0, NULL); ++ if (ret) ++ return ret; ++ if (threadgroup) { ++ struct task_struct *c; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { ++ ret = security_task_setscheduler(c, 0, NULL); ++ if (ret) { ++ rcu_read_unlock(); ++ return ret; ++ } ++ } ++ rcu_read_unlock(); ++ } ++ return 0; ++} ++ ++static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to, ++ struct cpuset *cs) ++{ ++ int err; ++ /* ++ * can_attach beforehand should guarantee that this doesn't fail. ++ * TODO: have a better way to handle failure here ++ */ ++ err = set_cpus_allowed_ptr(tsk, cpus_attach); ++ WARN_ON_ONCE(err); ++ ++ task_lock(tsk); ++ cpuset_change_task_nodemask(tsk, to); ++ task_unlock(tsk); ++ cpuset_update_task_spread_flag(cs, tsk); ++ + } + +-static void cpuset_attach(struct cgroup_subsys *ss, +- struct cgroup *cont, struct cgroup *oldcont, +- struct task_struct *tsk) ++static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont, ++ struct cgroup *oldcont, struct task_struct *tsk, ++ bool threadgroup) + { + nodemask_t from, to; + struct mm_struct *mm; + struct cpuset *cs = cgroup_cs(cont); + struct cpuset *oldcs = cgroup_cs(oldcont); +- int err; + + if (cs == &top_cpuset) { + cpumask_copy(cpus_attach, cpu_possible_mask); +@@ -1363,15 +1397,19 @@ static void cpuset_attach(struct cgroup_subsys *ss, + guarantee_online_cpus(cs, cpus_attach); + guarantee_online_mems(cs, &to); + } +- err = set_cpus_allowed_ptr(tsk, cpus_attach); +- if (err) +- return; + +- task_lock(tsk); +- cpuset_change_task_nodemask(tsk, &to); +- task_unlock(tsk); +- cpuset_update_task_spread_flag(cs, tsk); ++ /* do per-task migration stuff possibly for each in the threadgroup */ ++ cpuset_attach_task(tsk, &to, cs); ++ if (threadgroup) { ++ struct task_struct *c; ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { ++ cpuset_attach_task(c, &to, cs); ++ } ++ rcu_read_unlock(); ++ } + ++ /* change mm; only needs to be done once even if threadgroup */ + from = oldcs->mems_allowed; + to = cs->mems_allowed; + mm = get_task_mm(tsk); +@@ -2499,15 +2537,9 @@ const struct file_operations proc_cpuset_operations = { }; #endif /* CONFIG_PROC_PID_CPUSET */ @@ -1696581,7 +1778530,7 @@ index 962a3b5..0000000 -} -EXPORT_SYMBOL(dma_release_from_coherent); diff --git a/kernel/exit.c b/kernel/exit.c -index 869dc22..60d6fdc 100644 +index 869dc22..5859f59 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -47,7 +47,7 @@ @@ -1696634,7 +1778583,16 @@ index 869dc22..60d6fdc 100644 } acct_collect(code, group_dead); if (group_dead) -@@ -979,7 +985,7 @@ NORET_TYPE void do_exit(long code) +@@ -970,8 +976,6 @@ NORET_TYPE void do_exit(long code) + disassociate_ctty(1); + + module_put(task_thread_info(tsk)->exec_domain->module); +- if (tsk->binfmt) +- module_put(tsk->binfmt->module); + + proc_exit_connector(tsk); + +@@ -979,7 +983,7 @@ NORET_TYPE void do_exit(long code) * Flush inherited counters to the parent - before the parent * gets woken up by child-exit notifications. */ @@ -1696643,7 +1778601,7 @@ index 869dc22..60d6fdc 100644 exit_notify(tsk, group_dead); #ifdef CONFIG_NUMA -@@ -1009,7 +1015,10 @@ NORET_TYPE void do_exit(long code) +@@ -1009,7 +1013,10 @@ NORET_TYPE void do_exit(long code) if (tsk->splice_pipe) __free_pipe_info(tsk->splice_pipe); @@ -1696654,7 +1778612,94 @@ index 869dc22..60d6fdc 100644 /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; schedule(); -@@ -1203,6 +1212,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) +@@ -1088,28 +1095,28 @@ struct wait_opts { + int __user *wo_stat; + struct rusage __user *wo_rusage; + ++ wait_queue_t child_wait; + int notask_error; + }; + +-static struct pid *task_pid_type(struct task_struct *task, enum pid_type type) ++static inline ++struct pid *task_pid_type(struct task_struct *task, enum pid_type type) + { +- struct pid *pid = NULL; +- if (type == PIDTYPE_PID) +- pid = task->pids[type].pid; +- else if (type < PIDTYPE_MAX) +- pid = task->group_leader->pids[type].pid; +- return pid; ++ if (type != PIDTYPE_PID) ++ task = task->group_leader; ++ return task->pids[type].pid; + } + +-static int eligible_child(struct wait_opts *wo, struct task_struct *p) ++static int eligible_pid(struct wait_opts *wo, struct task_struct *p) + { +- int err; +- +- if (wo->wo_type < PIDTYPE_MAX) { +- if (task_pid_type(p, wo->wo_type) != wo->wo_pid) +- return 0; +- } ++ return wo->wo_type == PIDTYPE_MAX || ++ task_pid_type(p, wo->wo_type) == wo->wo_pid; ++} + ++static int eligible_child(struct wait_opts *wo, struct task_struct *p) ++{ ++ if (!eligible_pid(wo, p)) ++ return 0; + /* Wait for all children (clone and not) if __WALL is set; + * otherwise, wait for clone children *only* if __WCLONE is + * set; otherwise, wait for non-clone children *only*. (Note: +@@ -1119,10 +1126,6 @@ static int eligible_child(struct wait_opts *wo, struct task_struct *p) + && !(wo->wo_flags & __WALL)) + return 0; + +- err = security_task_wait(p); +- if (err) +- return err; +- + return 1; + } + +@@ -1135,18 +1138,20 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p, + + put_task_struct(p); + infop = wo->wo_info; +- if (!retval) +- retval = put_user(SIGCHLD, &infop->si_signo); +- if (!retval) +- retval = put_user(0, &infop->si_errno); +- if (!retval) +- retval = put_user((short)why, &infop->si_code); +- if (!retval) +- retval = put_user(pid, &infop->si_pid); +- if (!retval) +- retval = put_user(uid, &infop->si_uid); +- if (!retval) +- retval = put_user(status, &infop->si_status); ++ if (infop) { ++ if (!retval) ++ retval = put_user(SIGCHLD, &infop->si_signo); ++ if (!retval) ++ retval = put_user(0, &infop->si_errno); ++ if (!retval) ++ retval = put_user((short)why, &infop->si_code); ++ if (!retval) ++ retval = put_user(pid, &infop->si_pid); ++ if (!retval) ++ retval = put_user(uid, &infop->si_uid); ++ if (!retval) ++ retval = put_user(status, &infop->si_status); ++ } + if (!retval) + retval = pid; + return retval; +@@ -1203,6 +1208,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) if (likely(!traced) && likely(!task_detached(p))) { struct signal_struct *psig; struct signal_struct *sig; @@ -1696662,7 +1778707,7 @@ index 869dc22..60d6fdc 100644 /* * The resource counters for the group leader are in its -@@ -1251,6 +1261,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) +@@ -1251,6 +1257,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) psig->coublock += task_io_get_oublock(p) + sig->oublock + sig->coublock; @@ -1696672,8 +1778717,148 @@ index 869dc22..60d6fdc 100644 task_io_accounting_add(&psig->ioac, &p->ioac); task_io_accounting_add(&psig->ioac, &sig->ioac); spin_unlock_irq(&p->real_parent->sighand->siglock); +@@ -1472,13 +1481,14 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) + * then ->notask_error is 0 if @p is an eligible child, + * or another error from security_task_wait(), or still -ECHILD. + */ +-static int wait_consider_task(struct wait_opts *wo, struct task_struct *parent, +- int ptrace, struct task_struct *p) ++static int wait_consider_task(struct wait_opts *wo, int ptrace, ++ struct task_struct *p) + { + int ret = eligible_child(wo, p); + if (!ret) + return ret; + ++ ret = security_task_wait(p); + if (unlikely(ret < 0)) { + /* + * If we have not yet seen any eligible child, +@@ -1540,7 +1550,7 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk) + * Do not consider detached threads. + */ + if (!task_detached(p)) { +- int ret = wait_consider_task(wo, tsk, 0, p); ++ int ret = wait_consider_task(wo, 0, p); + if (ret) + return ret; + } +@@ -1554,7 +1564,7 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) + struct task_struct *p; + + list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { +- int ret = wait_consider_task(wo, tsk, 1, p); ++ int ret = wait_consider_task(wo, 1, p); + if (ret) + return ret; + } +@@ -1562,15 +1572,38 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) + return 0; + } + ++static int child_wait_callback(wait_queue_t *wait, unsigned mode, ++ int sync, void *key) ++{ ++ struct wait_opts *wo = container_of(wait, struct wait_opts, ++ child_wait); ++ struct task_struct *p = key; ++ ++ if (!eligible_pid(wo, p)) ++ return 0; ++ ++ if ((wo->wo_flags & __WNOTHREAD) && wait->private != p->parent) ++ return 0; ++ ++ return default_wake_function(wait, mode, sync, key); ++} ++ ++void __wake_up_parent(struct task_struct *p, struct task_struct *parent) ++{ ++ __wake_up_sync_key(&parent->signal->wait_chldexit, ++ TASK_INTERRUPTIBLE, 1, p); ++} ++ + static long do_wait(struct wait_opts *wo) + { +- DECLARE_WAITQUEUE(wait, current); + struct task_struct *tsk; + int retval; + + trace_sched_process_wait(wo->wo_pid); + +- add_wait_queue(¤t->signal->wait_chldexit,&wait); ++ init_waitqueue_func_entry(&wo->child_wait, child_wait_callback); ++ wo->child_wait.private = current; ++ add_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); + repeat: + /* + * If there is nothing that can match our critiera just get out. +@@ -1611,32 +1644,7 @@ notask: + } + end: + __set_current_state(TASK_RUNNING); +- remove_wait_queue(¤t->signal->wait_chldexit,&wait); +- if (wo->wo_info) { +- struct siginfo __user *infop = wo->wo_info; +- +- if (retval > 0) +- retval = 0; +- else { +- /* +- * For a WNOHANG return, clear out all the fields +- * we would set so the user can easily tell the +- * difference. +- */ +- if (!retval) +- retval = put_user(0, &infop->si_signo); +- if (!retval) +- retval = put_user(0, &infop->si_errno); +- if (!retval) +- retval = put_user(0, &infop->si_code); +- if (!retval) +- retval = put_user(0, &infop->si_pid); +- if (!retval) +- retval = put_user(0, &infop->si_uid); +- if (!retval) +- retval = put_user(0, &infop->si_status); +- } +- } ++ remove_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); + return retval; + } + +@@ -1681,6 +1689,29 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, + wo.wo_stat = NULL; + wo.wo_rusage = ru; + ret = do_wait(&wo); ++ ++ if (ret > 0) { ++ ret = 0; ++ } else if (infop) { ++ /* ++ * For a WNOHANG return, clear out all the fields ++ * we would set so the user can easily tell the ++ * difference. ++ */ ++ if (!ret) ++ ret = put_user(0, &infop->si_signo); ++ if (!ret) ++ ret = put_user(0, &infop->si_errno); ++ if (!ret) ++ ret = put_user(0, &infop->si_code); ++ if (!ret) ++ ret = put_user(0, &infop->si_pid); ++ if (!ret) ++ ret = put_user(0, &infop->si_uid); ++ if (!ret) ++ ret = put_user(0, &infop->si_status); ++ } ++ + put_pid(pid); + + /* avoid REGPARM breakage on x86: */ diff --git a/kernel/fork.c b/kernel/fork.c -index e6c04d4..51ad0b0 100644 +index e6c04d4..266c6af 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -49,6 +49,7 @@ @@ -1696742,7 +1778927,21 @@ index e6c04d4..51ad0b0 100644 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { struct file *file; -@@ -425,7 +440,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) +@@ -419,22 +434,30 @@ __setup("coredump_filter=", coredump_filter_setup); + + #include + ++static void mm_init_aio(struct mm_struct *mm) ++{ ++#ifdef CONFIG_AIO ++ spin_lock_init(&mm->ioctx_lock); ++ INIT_HLIST_HEAD(&mm->ioctx_list); ++#endif ++} ++ + static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) + { + atomic_set(&mm->mm_users, 1); atomic_set(&mm->mm_count, 1); init_rwsem(&mm->mmap_sem); INIT_LIST_HEAD(&mm->mmlist); @@ -1696752,7 +1778951,17 @@ index e6c04d4..51ad0b0 100644 mm->core_state = NULL; mm->nr_ptes = 0; set_mm_counter(mm, file_rss, 0); -@@ -486,6 +502,7 @@ void mmput(struct mm_struct *mm) + set_mm_counter(mm, anon_rss, 0); + spin_lock_init(&mm->page_table_lock); +- spin_lock_init(&mm->ioctx_lock); +- INIT_HLIST_HEAD(&mm->ioctx_list); + mm->free_area_cache = TASK_UNMAPPED_BASE; + mm->cached_hole_size = ~0UL; ++ mm_init_aio(mm); + mm_init_owner(mm, p); + + if (likely(!mm_alloc_pgd(mm))) { +@@ -486,6 +509,7 @@ void mmput(struct mm_struct *mm) if (atomic_dec_and_test(&mm->mm_users)) { exit_aio(mm); @@ -1696760,7 +1778969,31 @@ index e6c04d4..51ad0b0 100644 exit_mmap(mm); set_mm_exe_file(mm, NULL); if (!list_empty(&mm->mmlist)) { -@@ -789,10 +806,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) +@@ -494,6 +518,8 @@ void mmput(struct mm_struct *mm) + spin_unlock(&mmlist_lock); + } + put_swap_token(mm); ++ if (mm->binfmt) ++ module_put(mm->binfmt->module); + mmdrop(mm); + } + } +@@ -619,9 +645,14 @@ struct mm_struct *dup_mm(struct task_struct *tsk) + mm->hiwater_rss = get_mm_rss(mm); + mm->hiwater_vm = mm->total_vm; + ++ if (mm->binfmt && !try_module_get(mm->binfmt->module)) ++ goto free_pt; ++ + return mm; + + free_pt: ++ /* don't put binfmt in mmput, we haven't got module yet */ ++ mm->binfmt = NULL; + mmput(mm); + + fail_nomem: +@@ -789,10 +820,10 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig) thread_group_cputime_init(sig); /* Expiration times and increments. */ @@ -1696775,7 +1779008,7 @@ index e6c04d4..51ad0b0 100644 /* Cached expiration times. */ sig->cputime_expires.prof_exp = cputime_zero; -@@ -850,6 +867,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) +@@ -850,6 +881,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0; sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0; @@ -1696783,7 +1779016,7 @@ index e6c04d4..51ad0b0 100644 task_io_accounting_init(&sig->ioac); sig->sum_sched_runtime = 0; taskstats_tgid_init(sig); -@@ -864,6 +882,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) +@@ -864,6 +896,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) tty_audit_fork(sig); @@ -1696792,7 +1779025,32 @@ index e6c04d4..51ad0b0 100644 return 0; } -@@ -1008,10 +1028,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, +@@ -959,6 +993,16 @@ static struct task_struct *copy_process(unsigned long clone_flags, + if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM)) + return ERR_PTR(-EINVAL); + ++ /* ++ * Siblings of global init remain as zombies on exit since they are ++ * not reaped by their parent (swapper). To solve this and to avoid ++ * multi-rooted process trees, prevent global and container-inits ++ * from creating siblings. ++ */ ++ if ((clone_flags & CLONE_PARENT) && ++ current->signal->flags & SIGNAL_UNKILLABLE) ++ return ERR_PTR(-EINVAL); ++ + retval = security_task_create(clone_flags); + if (retval) + goto fork_out; +@@ -1000,18 +1044,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, + if (!try_module_get(task_thread_info(p)->exec_domain->module)) + goto bad_fork_cleanup_count; + +- if (p->binfmt && !try_module_get(p->binfmt->module)) +- goto bad_fork_cleanup_put_domain; +- + p->did_exec = 0; + delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ copy_flags(clone_flags, p); INIT_LIST_HEAD(&p->children); INIT_LIST_HEAD(&p->sibling); @@ -1696804,7 +1779062,7 @@ index e6c04d4..51ad0b0 100644 p->vfork_done = NULL; spin_lock_init(&p->alloc_lock); -@@ -1079,10 +1096,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, +@@ -1079,10 +1117,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->bts = NULL; @@ -1696818,7 +1779076,7 @@ index e6c04d4..51ad0b0 100644 if (retval) goto bad_fork_cleanup_policy; -@@ -1257,7 +1276,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, +@@ -1257,7 +1297,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, write_unlock_irq(&tasklist_lock); proc_fork_connector(p); cgroup_post_fork(p); @@ -1696827,7 +1779085,7 @@ index e6c04d4..51ad0b0 100644 return p; bad_fork_free_pid: -@@ -1284,7 +1303,7 @@ bad_fork_cleanup_semundo: +@@ -1284,21 +1324,17 @@ bad_fork_cleanup_semundo: bad_fork_cleanup_audit: audit_free(p); bad_fork_cleanup_policy: @@ -1696836,7 +1779094,12 @@ index e6c04d4..51ad0b0 100644 #ifdef CONFIG_NUMA mpol_put(p->mempolicy); bad_fork_cleanup_cgroup: -@@ -1297,8 +1316,7 @@ bad_fork_cleanup_put_domain: + #endif + cgroup_exit(p, cgroup_callbacks_done); + delayacct_tsk_free(p); +- if (p->binfmt) +- module_put(p->binfmt->module); +-bad_fork_cleanup_put_domain: module_put(task_thread_info(p)->exec_domain->module); bad_fork_cleanup_count: atomic_dec(&p->cred->user->processes); @@ -1697282,6 +1779545,25 @@ index 49da79a..6d70204 100644 /* * Mark it as STATE_MIGRATE not INACTIVE otherwise the +diff --git a/kernel/hung_task.c b/kernel/hung_task.c +index 022a492..d4e8417 100644 +--- a/kernel/hung_task.c ++++ b/kernel/hung_task.c +@@ -171,12 +171,12 @@ static unsigned long timeout_jiffies(unsigned long timeout) + * Process updating of timeout sysctl + */ + int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + int ret; + +- ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write) + goto out; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 13c68e7..c166019 100644 --- a/kernel/irq/chip.c @@ -1698052,7 +1780334,7 @@ index 9147a31..609cbde 100644 local_irq_restore(flags); diff --git a/kernel/kmod.c b/kernel/kmod.c -index 385c31a..689d20f 100644 +index 385c31a..9fcb53a 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -37,6 +37,8 @@ @@ -1698084,50 +1780366,7 @@ index 385c31a..689d20f 100644 ret = call_usermodehelper(modprobe_path, argv, envp, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); atomic_dec(&kmod_concurrent); -@@ -135,6 +143,7 @@ struct subprocess_info { - static int ____call_usermodehelper(void *data) - { - struct subprocess_info *sub_info = data; -+ enum umh_wait wait = sub_info->wait; - int retval; - - BUG_ON(atomic_read(&sub_info->cred->usage) != 1); -@@ -176,10 +185,14 @@ static int ____call_usermodehelper(void *data) - */ - set_user_nice(current, 0); - -+ if (wait == UMH_WAIT_EXEC) -+ complete(sub_info->complete); -+ - retval = kernel_execve(sub_info->path, sub_info->argv, sub_info->envp); - - /* Exec failed? */ -- sub_info->retval = retval; -+ if (wait != UMH_WAIT_EXEC) -+ sub_info->retval = retval; - do_exit(0); - } - -@@ -258,16 +271,14 @@ static void __call_usermodehelper(struct work_struct *work) - - switch (wait) { - case UMH_NO_WAIT: -+ case UMH_WAIT_EXEC: - break; - - case UMH_WAIT_PROC: - if (pid > 0) - break; - sub_info->retval = pid; -- /* FALLTHROUGH */ -- -- case UMH_WAIT_EXEC: -- complete(sub_info->complete); -+ break; - } - } - -@@ -462,6 +473,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, +@@ -462,6 +470,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int retval = 0; BUG_ON(atomic_read(&sub_info->cred->usage) != 1); @@ -1701056,6 +1783295,40 @@ index 2d53718..5a29397 100644 #ifdef CONFIG_TRACEPOINTS void module_update_tracepoints(void) { +diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c +index 5aa854f..2a5dfec 100644 +--- a/kernel/ns_cgroup.c ++++ b/kernel/ns_cgroup.c +@@ -42,8 +42,8 @@ int ns_cgroup_clone(struct task_struct *task, struct pid *pid) + * (hence either you are in the same cgroup as task, or in an + * ancestor cgroup thereof) + */ +-static int ns_can_attach(struct cgroup_subsys *ss, +- struct cgroup *new_cgroup, struct task_struct *task) ++static int ns_can_attach(struct cgroup_subsys *ss, struct cgroup *new_cgroup, ++ struct task_struct *task, bool threadgroup) + { + if (current != task) { + if (!capable(CAP_SYS_ADMIN)) +@@ -56,6 +56,18 @@ static int ns_can_attach(struct cgroup_subsys *ss, + if (!cgroup_is_descendant(new_cgroup, task)) + return -EPERM; + ++ if (threadgroup) { ++ struct task_struct *c; ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &task->thread_group, thread_group) { ++ if (!cgroup_is_descendant(new_cgroup, c)) { ++ rcu_read_unlock(); ++ return -EPERM; ++ } ++ } ++ rcu_read_unlock(); ++ } ++ + return 0; + } + diff --git a/kernel/panic.c b/kernel/panic.c index 512ab73..bcdef26 100644 --- a/kernel/panic.c @@ -1711017,6 +1793290,19 @@ index 31310b5..d3f722d 100644 for (i = 0; i < pidhash_size; i++) INIT_HLIST_HEAD(&pid_hash[i]); } +diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c +index 821722a..86b3796 100644 +--- a/kernel/pid_namespace.c ++++ b/kernel/pid_namespace.c +@@ -118,7 +118,7 @@ struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old + { + if (!(flags & CLONE_NEWPID)) + return get_pid_ns(old_ns); +- if (flags & CLONE_THREAD) ++ if (flags & (CLONE_THREAD|CLONE_PARENT)) + return ERR_PTR(-EINVAL); + return create_pid_namespace(old_ns); + } diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index e33a21c..5c9dc22 100644 --- a/kernel/posix-cpu-timers.c @@ -1712131,6 +1794417,18 @@ index 523a451..36cb168 100644 max_zone_pfn = zone->zone_start_pfn + zone->spanned_pages; for (pfn = zone->zone_start_pfn; pfn < max_zone_pfn; pfn++) if (pfn_valid(pfn)) +diff --git a/kernel/power/swap.c b/kernel/power/swap.c +index 8ba052c..b101cdc 100644 +--- a/kernel/power/swap.c ++++ b/kernel/power/swap.c +@@ -13,7 +13,6 @@ + + #include + #include +-#include + #include + #include + #include diff --git a/kernel/printk.c b/kernel/printk.c index b4d97b5..f38b07f 100644 --- a/kernel/printk.c @@ -1712598,7 +1794896,7 @@ index 419250e..a55d3a3 100644 /* diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index 082c320..307c285 100644 +index 082c320..23bd09c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -152,7 +152,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) @@ -1712610,6 +1794908,32 @@ index 082c320..307c285 100644 } bool ptrace_may_access(struct task_struct *task, unsigned int mode) +@@ -266,9 +266,10 @@ static int ignoring_children(struct sighand_struct *sigh) + * or self-reaping. Do notification now if it would have happened earlier. + * If it should reap itself, return true. + * +- * If it's our own child, there is no notification to do. +- * But if our normal children self-reap, then this child +- * was prevented by ptrace and we must reap it now. ++ * If it's our own child, there is no notification to do. But if our normal ++ * children self-reap, then this child was prevented by ptrace and we must ++ * reap it now, in that case we must also wake up sub-threads sleeping in ++ * do_wait(). + */ + static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) + { +@@ -278,8 +279,10 @@ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) + if (!task_detached(p) && thread_group_empty(p)) { + if (!same_thread_group(p->real_parent, tracer)) + do_notify_parent(p, p->exit_signal); +- else if (ignoring_children(tracer->sighand)) ++ else if (ignoring_children(tracer->sighand)) { ++ __wake_up_parent(p, tracer); + p->exit_signal = -1; ++ } + } + if (task_detached(p)) { + /* Mark it as in the process of being reaped. */ diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c deleted file mode 100644 index 0f2b0b3..0000000 @@ -1717673,6 +1799997,76 @@ index fe1dcdb..c89f5e9 100644 } +diff --git a/kernel/res_counter.c b/kernel/res_counter.c +index e1338f0..88faec2 100644 +--- a/kernel/res_counter.c ++++ b/kernel/res_counter.c +@@ -19,6 +19,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent) + { + spin_lock_init(&counter->lock); + counter->limit = RESOURCE_MAX; ++ counter->soft_limit = RESOURCE_MAX; + counter->parent = parent; + } + +@@ -36,17 +37,27 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val) + } + + int res_counter_charge(struct res_counter *counter, unsigned long val, +- struct res_counter **limit_fail_at) ++ struct res_counter **limit_fail_at, ++ struct res_counter **soft_limit_fail_at) + { + int ret; + unsigned long flags; + struct res_counter *c, *u; + + *limit_fail_at = NULL; ++ if (soft_limit_fail_at) ++ *soft_limit_fail_at = NULL; + local_irq_save(flags); + for (c = counter; c != NULL; c = c->parent) { + spin_lock(&c->lock); + ret = res_counter_charge_locked(c, val); ++ /* ++ * With soft limits, we return the highest ancestor ++ * that exceeds its soft limit ++ */ ++ if (soft_limit_fail_at && ++ !res_counter_soft_limit_check_locked(c)) ++ *soft_limit_fail_at = c; + spin_unlock(&c->lock); + if (ret < 0) { + *limit_fail_at = c; +@@ -74,7 +85,8 @@ void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val) + counter->usage -= val; + } + +-void res_counter_uncharge(struct res_counter *counter, unsigned long val) ++void res_counter_uncharge(struct res_counter *counter, unsigned long val, ++ bool *was_soft_limit_excess) + { + unsigned long flags; + struct res_counter *c; +@@ -82,6 +94,9 @@ void res_counter_uncharge(struct res_counter *counter, unsigned long val) + local_irq_save(flags); + for (c = counter; c != NULL; c = c->parent) { + spin_lock(&c->lock); ++ if (was_soft_limit_excess) ++ *was_soft_limit_excess = ++ !res_counter_soft_limit_check_locked(c); + res_counter_uncharge_locked(c, val); + spin_unlock(&c->lock); + } +@@ -101,6 +116,8 @@ res_counter_member(struct res_counter *counter, int member) + return &counter->limit; + case RES_FAILCNT: + return &counter->failcnt; ++ case RES_SOFT_LIMIT: ++ return &counter->soft_limit; + }; + + BUG(); diff --git a/kernel/resource.c b/kernel/resource.c index 78b0872..fb11a58 100644 --- a/kernel/resource.c @@ -1717735,7 +1800129,7 @@ index 78b0872..fb11a58 100644 len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT); ret = (*func)(pfn, len, arg); diff --git a/kernel/sched.c b/kernel/sched.c -index 1b59e26..2f76e06 100644 +index 1b59e26..ee61f45 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -39,7 +39,7 @@ @@ -1718396,12 +1800790,12 @@ index 1b59e26..2f76e06 100644 if (!sched_feat(SYNC_WAKEUPS)) - sync = 0; -- ++ wake_flags &= ~WF_SYNC; + -#ifdef CONFIG_SMP - if (sched_feat(LB_WAKEUP_UPDATE) && !root_task_group_empty()) { - struct sched_domain *sd; -+ wake_flags &= ~WF_SYNC; - +- - this_cpu = raw_smp_processor_id(); - cpu = task_cpu(p); - @@ -1719702,7 +1802096,7 @@ index 1b59e26..2f76e06 100644 - struct root_domain *rd; - cpumask_var_t nodemask, this_sibling_map, this_core_map, send_covered, - tmpmask; - #ifdef CONFIG_NUMA +-#ifdef CONFIG_NUMA - cpumask_var_t domainspan, covered, notcovered; - struct sched_group **sched_group_nodes = NULL; - int sd_allnodes = 0; @@ -1719726,7 +1802120,7 @@ index 1b59e26..2f76e06 100644 - if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL)) - goto free_send_covered; - --#ifdef CONFIG_NUMA + #ifdef CONFIG_NUMA - /* - * Allocate the per-node list of sched groups - */ @@ -1719780,7 +1802174,8 @@ index 1b59e26..2f76e06 100644 #ifdef CONFIG_NUMA - sched_group_nodes_bycpu[cpumask_first(cpu_map)] = sched_group_nodes; -#endif -- ++ struct sched_domain *parent; + - /* - * Set up domains for cpus specified by the cpu_map. - */ @@ -1719801,8 +1802196,7 @@ index 1b59e26..2f76e06 100644 - sd_allnodes = 1; - } else - p = NULL; -+ struct sched_domain *parent; - +- - sd = &per_cpu(node_domains, i).sd; - SD_INIT(sd, NODE); + d->sd_allnodes = 0; @@ -1720269,7 +1802663,82 @@ index 1b59e26..2f76e06 100644 return; if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) return; -@@ -10581,3 +10736,113 @@ struct cgroup_subsys cpuacct_subsys = { +@@ -10157,7 +10312,7 @@ static int sched_rt_global_constraints(void) + #endif /* CONFIG_RT_GROUP_SCHED */ + + int sched_rt_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int ret; +@@ -10168,7 +10323,7 @@ int sched_rt_handler(struct ctl_table *table, int write, + old_period = sysctl_sched_rt_period; + old_runtime = sysctl_sched_rt_runtime; + +- ret = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (!ret && write) { + ret = sched_rt_global_constraints(); +@@ -10222,8 +10377,7 @@ cpu_cgroup_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) + } + + static int +-cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, +- struct task_struct *tsk) ++cpu_cgroup_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk) + { + #ifdef CONFIG_RT_GROUP_SCHED + if (!sched_rt_can_attach(cgroup_tg(cgrp), tsk)) +@@ -10233,15 +10387,45 @@ cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, + if (tsk->sched_class != &fair_sched_class) + return -EINVAL; + #endif ++ return 0; ++} + ++static int ++cpu_cgroup_can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, ++ struct task_struct *tsk, bool threadgroup) ++{ ++ int retval = cpu_cgroup_can_attach_task(cgrp, tsk); ++ if (retval) ++ return retval; ++ if (threadgroup) { ++ struct task_struct *c; ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { ++ retval = cpu_cgroup_can_attach_task(cgrp, c); ++ if (retval) { ++ rcu_read_unlock(); ++ return retval; ++ } ++ } ++ rcu_read_unlock(); ++ } + return 0; + } + + static void + cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp, +- struct cgroup *old_cont, struct task_struct *tsk) ++ struct cgroup *old_cont, struct task_struct *tsk, ++ bool threadgroup) + { + sched_move_task(tsk); ++ if (threadgroup) { ++ struct task_struct *c; ++ rcu_read_lock(); ++ list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) { ++ sched_move_task(c); ++ } ++ rcu_read_unlock(); ++ } + } + + #ifdef CONFIG_FAIR_GROUP_SCHED +@@ -10581,3 +10765,113 @@ struct cgroup_subsys cpuacct_subsys = { .subsys_id = cpuacct_subsys_id, }; #endif /* CONFIG_CGROUP_CPUACCT */ @@ -1720654,7 +1803123,7 @@ index 70c7e0b..efb8440 100644 p->se.sum_sleep_runtime = 0; p->se.block_max = 0; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c -index 652e8bd..ecc637a 100644 +index 652e8bd..4e777b4 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -24,7 +24,7 @@ @@ -1720753,6 +1803222,19 @@ index 652e8bd..ecc637a 100644 static inline struct rq *rq_of(struct cfs_rq *cfs_rq) { +@@ -376,10 +384,10 @@ static struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq) + + #ifdef CONFIG_SCHED_DEBUG + int sched_nr_latency_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + + if (ret || !write) + return ret; @@ -505,6 +513,7 @@ static void update_curr(struct cfs_rq *cfs_rq) if (entity_is_task(curr)) { struct task_struct *curtask = task_of(curr); @@ -1721797,6 +1804279,344 @@ index 3918e01..a4d790c 100644 .prio_changed = prio_changed_rt, .switched_to = switched_to_rt, }; +diff --git a/kernel/signal.c b/kernel/signal.c +index 64c5dee..6705320 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -705,7 +705,7 @@ static int prepare_signal(int sig, struct task_struct *p, int from_ancestor_ns) + + if (why) { + /* +- * The first thread which returns from finish_stop() ++ * The first thread which returns from do_signal_stop() + * will take ->siglock, notice SIGNAL_CLD_MASK, and + * notify its parent. See get_signal_to_deliver(). + */ +@@ -971,6 +971,20 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) + return send_signal(sig, info, t, 0); + } + ++int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, ++ bool group) ++{ ++ unsigned long flags; ++ int ret = -ESRCH; ++ ++ if (lock_task_sighand(p, &flags)) { ++ ret = send_signal(sig, info, p, group); ++ unlock_task_sighand(p, &flags); ++ } ++ ++ return ret; ++} ++ + /* + * Force a signal that the process can't ignore: if necessary + * we unblock the signal and change any SIG_IGN to SIG_DFL. +@@ -1036,12 +1050,6 @@ void zap_other_threads(struct task_struct *p) + } + } + +-int __fatal_signal_pending(struct task_struct *tsk) +-{ +- return sigismember(&tsk->pending.signal, SIGKILL); +-} +-EXPORT_SYMBOL(__fatal_signal_pending); +- + struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long *flags) + { + struct sighand_struct *sighand; +@@ -1068,18 +1076,10 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long + */ + int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) + { +- unsigned long flags; +- int ret; ++ int ret = check_kill_permission(sig, info, p); + +- ret = check_kill_permission(sig, info, p); +- +- if (!ret && sig) { +- ret = -ESRCH; +- if (lock_task_sighand(p, &flags)) { +- ret = __group_send_sig_info(sig, info, p); +- unlock_task_sighand(p, &flags); +- } +- } ++ if (!ret && sig) ++ ret = do_send_sig_info(sig, info, p, true); + + return ret; + } +@@ -1224,15 +1224,9 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid) + * These are for backward compatibility with the rest of the kernel source. + */ + +-/* +- * The caller must ensure the task can't exit. +- */ + int + send_sig_info(int sig, struct siginfo *info, struct task_struct *p) + { +- int ret; +- unsigned long flags; +- + /* + * Make sure legacy kernel users don't send in bad values + * (normal paths check this in check_kill_permission). +@@ -1240,10 +1234,7 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p) + if (!valid_signal(sig)) + return -EINVAL; + +- spin_lock_irqsave(&p->sighand->siglock, flags); +- ret = specific_send_sig_info(sig, info, p); +- spin_unlock_irqrestore(&p->sighand->siglock, flags); +- return ret; ++ return do_send_sig_info(sig, info, p, false); + } + + #define __si_special(priv) \ +@@ -1383,15 +1374,6 @@ ret: + } + + /* +- * Wake up any threads in the parent blocked in wait* syscalls. +- */ +-static inline void __wake_up_parent(struct task_struct *p, +- struct task_struct *parent) +-{ +- wake_up_interruptible_sync(&parent->signal->wait_chldexit); +-} +- +-/* + * Let a parent know about the death of a child. + * For a stopped/continued status change, use do_notify_parent_cldstop instead. + * +@@ -1673,29 +1655,6 @@ void ptrace_notify(int exit_code) + spin_unlock_irq(¤t->sighand->siglock); + } + +-static void +-finish_stop(int stop_count) +-{ +- /* +- * If there are no other threads in the group, or if there is +- * a group stop in progress and we are the last to stop, +- * report to the parent. When ptraced, every thread reports itself. +- */ +- if (tracehook_notify_jctl(stop_count == 0, CLD_STOPPED)) { +- read_lock(&tasklist_lock); +- do_notify_parent_cldstop(current, CLD_STOPPED); +- read_unlock(&tasklist_lock); +- } +- +- do { +- schedule(); +- } while (try_to_freeze()); +- /* +- * Now we don't run again until continued. +- */ +- current->exit_code = 0; +-} +- + /* + * This performs the stopping for SIGSTOP and other stop signals. + * We have to stop all threads in the thread group. +@@ -1705,15 +1664,9 @@ finish_stop(int stop_count) + static int do_signal_stop(int signr) + { + struct signal_struct *sig = current->signal; +- int stop_count; ++ int notify; + +- if (sig->group_stop_count > 0) { +- /* +- * There is a group stop in progress. We don't need to +- * start another one. +- */ +- stop_count = --sig->group_stop_count; +- } else { ++ if (!sig->group_stop_count) { + struct task_struct *t; + + if (!likely(sig->flags & SIGNAL_STOP_DEQUEUED) || +@@ -1725,7 +1678,7 @@ static int do_signal_stop(int signr) + */ + sig->group_exit_code = signr; + +- stop_count = 0; ++ sig->group_stop_count = 1; + for (t = next_thread(current); t != current; t = next_thread(t)) + /* + * Setting state to TASK_STOPPED for a group +@@ -1734,19 +1687,44 @@ static int do_signal_stop(int signr) + */ + if (!(t->flags & PF_EXITING) && + !task_is_stopped_or_traced(t)) { +- stop_count++; ++ sig->group_stop_count++; + signal_wake_up(t, 0); + } +- sig->group_stop_count = stop_count; + } ++ /* ++ * If there are no other threads in the group, or if there is ++ * a group stop in progress and we are the last to stop, report ++ * to the parent. When ptraced, every thread reports itself. ++ */ ++ notify = sig->group_stop_count == 1 ? CLD_STOPPED : 0; ++ notify = tracehook_notify_jctl(notify, CLD_STOPPED); ++ /* ++ * tracehook_notify_jctl() can drop and reacquire siglock, so ++ * we keep ->group_stop_count != 0 before the call. If SIGCONT ++ * or SIGKILL comes in between ->group_stop_count == 0. ++ */ ++ if (sig->group_stop_count) { ++ if (!--sig->group_stop_count) ++ sig->flags = SIGNAL_STOP_STOPPED; ++ current->exit_code = sig->group_exit_code; ++ __set_current_state(TASK_STOPPED); ++ } ++ spin_unlock_irq(¤t->sighand->siglock); + +- if (stop_count == 0) +- sig->flags = SIGNAL_STOP_STOPPED; +- current->exit_code = sig->group_exit_code; +- __set_current_state(TASK_STOPPED); ++ if (notify) { ++ read_lock(&tasklist_lock); ++ do_notify_parent_cldstop(current, notify); ++ read_unlock(&tasklist_lock); ++ } ++ ++ /* Now we don't run again until woken by SIGCONT or SIGKILL */ ++ do { ++ schedule(); ++ } while (try_to_freeze()); ++ ++ tracehook_finish_jctl(); ++ current->exit_code = 0; + +- spin_unlock_irq(¤t->sighand->siglock); +- finish_stop(stop_count); + return 1; + } + +@@ -1815,14 +1793,15 @@ relock: + int why = (signal->flags & SIGNAL_STOP_CONTINUED) + ? CLD_CONTINUED : CLD_STOPPED; + signal->flags &= ~SIGNAL_CLD_MASK; +- spin_unlock_irq(&sighand->siglock); + +- if (unlikely(!tracehook_notify_jctl(1, why))) +- goto relock; ++ why = tracehook_notify_jctl(why, CLD_CONTINUED); ++ spin_unlock_irq(&sighand->siglock); + +- read_lock(&tasklist_lock); +- do_notify_parent_cldstop(current->group_leader, why); +- read_unlock(&tasklist_lock); ++ if (why) { ++ read_lock(&tasklist_lock); ++ do_notify_parent_cldstop(current->group_leader, why); ++ read_unlock(&tasklist_lock); ++ } + goto relock; + } + +@@ -1987,14 +1966,14 @@ void exit_signals(struct task_struct *tsk) + if (unlikely(tsk->signal->group_stop_count) && + !--tsk->signal->group_stop_count) { + tsk->signal->flags = SIGNAL_STOP_STOPPED; +- group_stop = 1; ++ group_stop = tracehook_notify_jctl(CLD_STOPPED, CLD_STOPPED); + } + out: + spin_unlock_irq(&tsk->sighand->siglock); + +- if (unlikely(group_stop) && tracehook_notify_jctl(1, CLD_STOPPED)) { ++ if (unlikely(group_stop)) { + read_lock(&tasklist_lock); +- do_notify_parent_cldstop(tsk, CLD_STOPPED); ++ do_notify_parent_cldstop(tsk, group_stop); + read_unlock(&tasklist_lock); + } + } +@@ -2290,7 +2269,6 @@ static int + do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) + { + struct task_struct *p; +- unsigned long flags; + int error = -ESRCH; + + rcu_read_lock(); +@@ -2300,14 +2278,16 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) + /* + * The null signal is a permissions and process existence + * probe. No signal is actually delivered. +- * +- * If lock_task_sighand() fails we pretend the task dies +- * after receiving the signal. The window is tiny, and the +- * signal is private anyway. + */ +- if (!error && sig && lock_task_sighand(p, &flags)) { +- error = specific_send_sig_info(sig, info, p); +- unlock_task_sighand(p, &flags); ++ if (!error && sig) { ++ error = do_send_sig_info(sig, info, p, false); ++ /* ++ * If lock_task_sighand() failed we pretend the task ++ * dies after receiving the signal. The window is tiny, ++ * and the signal is private anyway. ++ */ ++ if (unlikely(error == -ESRCH)) ++ error = 0; + } + } + rcu_read_unlock(); +diff --git a/kernel/slow-work.c b/kernel/slow-work.c +index 09d7519..0d31135 100644 +--- a/kernel/slow-work.c ++++ b/kernel/slow-work.c +@@ -26,10 +26,10 @@ static void slow_work_cull_timeout(unsigned long); + static void slow_work_oom_timeout(unsigned long); + + #ifdef CONFIG_SYSCTL +-static int slow_work_min_threads_sysctl(struct ctl_table *, int, struct file *, ++static int slow_work_min_threads_sysctl(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + +-static int slow_work_max_threads_sysctl(struct ctl_table *, int , struct file *, ++static int slow_work_max_threads_sysctl(struct ctl_table *, int , + void __user *, size_t *, loff_t *); + #endif + +@@ -493,10 +493,10 @@ static void slow_work_oom_timeout(unsigned long data) + * Handle adjustment of the minimum number of threads + */ + static int slow_work_min_threads_sysctl(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { +- int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + int n; + + if (ret == 0) { +@@ -521,10 +521,10 @@ static int slow_work_min_threads_sysctl(struct ctl_table *table, int write, + * Handle adjustment of the maximum number of threads + */ + static int slow_work_max_threads_sysctl(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { +- int ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + int n; + + if (ret == 0) { diff --git a/kernel/smp.c b/kernel/smp.c index 94188b8..c9d1c78 100644 --- a/kernel/smp.c @@ -1721996,7 +1804816,7 @@ index eb5e131..f8749e5 100644 preempt_enable(); set_current_state(TASK_INTERRUPTIBLE); diff --git a/kernel/softlockup.c b/kernel/softlockup.c -index 88796c3..0bad4f9 100644 +index 88796c3..a85ace2 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -79,6 +79,14 @@ void touch_softlockup_watchdog(void) @@ -1722014,6 +1804834,20 @@ index 88796c3..0bad4f9 100644 void touch_all_softlockup_watchdogs(void) { int cpu; +@@ -90,11 +98,11 @@ void touch_all_softlockup_watchdogs(void) + EXPORT_SYMBOL(touch_all_softlockup_watchdogs); + + int proc_dosoftlockup_thresh(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + touch_all_softlockup_watchdogs(); +- return proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ return proc_dointvec_minmax(table, write, buffer, lenp, ppos); + } + + /* @@ -118,6 +126,14 @@ void softlockup_tick(void) } @@ -1722547,10 +1805381,18 @@ index 68320f6..e06d0b8 100644 -cond_syscall(sys_perf_counter_open); +cond_syscall(sys_perf_event_open); diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index 58be760..ea4102c 100644 +index 58be760..0d949c5 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c -@@ -49,9 +49,8 @@ +@@ -26,7 +26,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -49,9 +48,8 @@ #include #include #include @@ -1722561,6 +1805403,14 @@ index 58be760..ea4102c 100644 #include #include +@@ -78,6 +76,7 @@ extern int max_threads; + extern int core_uses_pid; + extern int suid_dumpable; + extern char core_pattern[]; ++extern unsigned int core_pipe_limit; + extern int pid_max; + extern int min_free_kbytes; + extern int pid_max_min, pid_max_max; @@ -92,6 +91,9 @@ extern int sysctl_nr_trim_pages; #ifdef CONFIG_RCU_TORTURE_TEST extern int rcutorture_runnable; @@ -1722581,6 +1805431,18 @@ index 58be760..ea4102c 100644 /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */ static unsigned long dirty_bytes_min = 2 * PAGE_SIZE; +@@ -158,9 +163,9 @@ extern int max_lock_depth; + #endif + + #ifdef CONFIG_PROC_SYSCTL +-static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, ++static int proc_do_cad_pid(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); +-static int proc_taint(struct ctl_table *table, int write, struct file *filp, ++static int proc_taint(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + #endif + @@ -246,6 +251,14 @@ static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */ #endif @@ -1722626,7 +1805488,22 @@ index 58be760..ea4102c 100644 .procname = "timer_migration", .data = &sysctl_timer_migration, .maxlen = sizeof(unsigned int), -@@ -712,6 +725,17 @@ static struct ctl_table kern_table[] = { +@@ -411,6 +424,14 @@ static struct ctl_table kern_table[] = { + .proc_handler = &proc_dostring, + .strategy = &sysctl_string, + }, ++ { ++ .ctl_name = CTL_UNNUMBERED, ++ .procname = "core_pipe_limit", ++ .data = &core_pipe_limit, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = &proc_dointvec, ++ }, + #ifdef CONFIG_PROC_SYSCTL + { + .procname = "tainted", +@@ -712,6 +733,17 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, @@ -1722644,7 +1805521,7 @@ index 58be760..ea4102c 100644 #endif { .ctl_name = KERN_NGROUPS_MAX, -@@ -954,28 +978,28 @@ static struct ctl_table kern_table[] = { +@@ -954,28 +986,28 @@ static struct ctl_table kern_table[] = { .child = slow_work_sysctls, }, #endif @@ -1722683,7 +1805560,7 @@ index 58be760..ea4102c 100644 .mode = 0644, .proc_handler = &proc_dointvec, }, -@@ -990,7 +1014,16 @@ static struct ctl_table kern_table[] = { +@@ -990,7 +1022,16 @@ static struct ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, #endif @@ -1722701,7 +1805578,7 @@ index 58be760..ea4102c 100644 /* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt -@@ -1357,6 +1390,31 @@ static struct ctl_table vm_table[] = { +@@ -1357,6 +1398,31 @@ static struct ctl_table vm_table[] = { .mode = 0644, .proc_handler = &scan_unevictable_handler, }, @@ -1722733,6 +1805610,321 @@ index 58be760..ea4102c 100644 /* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt +@@ -2185,7 +2251,7 @@ void sysctl_head_put(struct ctl_table_header *head) + #ifdef CONFIG_PROC_SYSCTL + + static int _proc_do_string(void* data, int maxlen, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + size_t len; +@@ -2246,7 +2312,6 @@ static int _proc_do_string(void* data, int maxlen, int write, + * proc_dostring - read a string sysctl + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2260,10 +2325,10 @@ static int _proc_do_string(void* data, int maxlen, int write, + * + * Returns 0 on success. + */ +-int proc_dostring(struct ctl_table *table, int write, struct file *filp, ++int proc_dostring(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return _proc_do_string(table->data, table->maxlen, write, filp, ++ return _proc_do_string(table->data, table->maxlen, write, + buffer, lenp, ppos); + } + +@@ -2288,7 +2353,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, + } + + static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, +- int write, struct file *filp, void __user *buffer, ++ int write, void __user *buffer, + size_t *lenp, loff_t *ppos, + int (*conv)(int *negp, unsigned long *lvalp, int *valp, + int write, void *data), +@@ -2395,13 +2460,13 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, + #undef TMPBUFLEN + } + +-static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, ++static int do_proc_dointvec(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos, + int (*conv)(int *negp, unsigned long *lvalp, int *valp, + int write, void *data), + void *data) + { +- return __do_proc_dointvec(table->data, table, write, filp, ++ return __do_proc_dointvec(table->data, table, write, + buffer, lenp, ppos, conv, data); + } + +@@ -2409,7 +2474,6 @@ static int do_proc_dointvec(struct ctl_table *table, int write, struct file *fil + * proc_dointvec - read a vector of integers + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2419,10 +2483,10 @@ static int do_proc_dointvec(struct ctl_table *table, int write, struct file *fil + * + * Returns 0 on success. + */ +-int proc_dointvec(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, ++ return do_proc_dointvec(table,write,buffer,lenp,ppos, + NULL,NULL); + } + +@@ -2430,7 +2494,7 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp, + * Taint values can only be increased + * This means we can safely use a temporary. + */ +-static int proc_taint(struct ctl_table *table, int write, struct file *filp, ++static int proc_taint(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table t; +@@ -2442,7 +2506,7 @@ static int proc_taint(struct ctl_table *table, int write, struct file *filp, + + t = *table; + t.data = &tmptaint; +- err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos); ++ err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); + if (err < 0) + return err; + +@@ -2494,7 +2558,6 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, + * proc_dointvec_minmax - read a vector of integers with min/max values + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2507,19 +2570,18 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, + * + * Returns 0 on success. + */ +-int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct do_proc_dointvec_minmax_conv_param param = { + .min = (int *) table->extra1, + .max = (int *) table->extra2, + }; +- return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, ++ return do_proc_dointvec(table, write, buffer, lenp, ppos, + do_proc_dointvec_minmax_conv, ¶m); + } + + static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos, + unsigned long convmul, +@@ -2624,21 +2686,19 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int + } + + static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos, + unsigned long convmul, + unsigned long convdiv) + { + return __do_proc_doulongvec_minmax(table->data, table, write, +- filp, buffer, lenp, ppos, convmul, convdiv); ++ buffer, lenp, ppos, convmul, convdiv); + } + + /** + * proc_doulongvec_minmax - read a vector of long integers with min/max values + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2651,17 +2711,16 @@ static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, + * + * Returns 0 on success. + */ +-int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, ++int proc_doulongvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); ++ return do_proc_doulongvec_minmax(table, write, buffer, lenp, ppos, 1l, 1l); + } + + /** + * proc_doulongvec_ms_jiffies_minmax - read a vector of millisecond values with min/max values + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2676,11 +2735,10 @@ int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp + * Returns 0 on success. + */ + int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { +- return do_proc_doulongvec_minmax(table, write, filp, buffer, ++ return do_proc_doulongvec_minmax(table, write, buffer, + lenp, ppos, HZ, 1000l); + } + +@@ -2756,7 +2814,6 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, + * proc_dointvec_jiffies - read a vector of integers as seconds + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2768,10 +2825,10 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, + * + * Returns 0 on success. + */ +-int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, ++ return do_proc_dointvec(table,write,buffer,lenp,ppos, + do_proc_dointvec_jiffies_conv,NULL); + } + +@@ -2779,7 +2836,6 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, + * proc_dointvec_userhz_jiffies - read a vector of integers as 1/USER_HZ seconds + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: pointer to the file position +@@ -2791,10 +2847,10 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, + * + * Returns 0 on success. + */ +-int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, ++ return do_proc_dointvec(table,write,buffer,lenp,ppos, + do_proc_dointvec_userhz_jiffies_conv,NULL); + } + +@@ -2802,7 +2858,6 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file + * proc_dointvec_ms_jiffies - read a vector of integers as 1 milliseconds + * @table: the sysctl table + * @write: %TRUE if this is a write to the sysctl file +- * @filp: the file structure + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position +@@ -2815,14 +2870,14 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file + * + * Returns 0 on success. + */ +-int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, ++ return do_proc_dointvec(table, write, buffer, lenp, ppos, + do_proc_dointvec_ms_jiffies_conv, NULL); + } + +-static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, ++static int proc_do_cad_pid(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct pid *new_pid; +@@ -2831,7 +2886,7 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp + + tmp = pid_vnr(cad_pid); + +- r = __do_proc_dointvec(&tmp, table, write, filp, buffer, ++ r = __do_proc_dointvec(&tmp, table, write, buffer, + lenp, ppos, NULL, NULL); + if (r || !write) + return r; +@@ -2846,50 +2901,49 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp + + #else /* CONFIG_PROC_FS */ + +-int proc_dostring(struct ctl_table *table, int write, struct file *filp, ++int proc_dostring(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_dointvec(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, ++int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + +-int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, ++int proc_doulongvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + return -ENOSYS; + } + + int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 888adbc..ea8384d 100644 --- a/kernel/taskstats.c @@ -1722808,6 +1806000,16 @@ index 2951194..2e2e469 100644 nsec += NSEC_PER_SEC; --sec; } +diff --git a/kernel/time/Makefile b/kernel/time/Makefile +index 0b0a636..ee26662 100644 +--- a/kernel/time/Makefile ++++ b/kernel/time/Makefile +@@ -1,4 +1,4 @@ +-obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o ++obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o timecompare.o timeconv.o + + obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o + obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 7466cb8..0911334 100644 --- a/kernel/time/clocksource.c @@ -1723613,6 +1806815,139 @@ index 7fc6437..4800f93 100644 write_sequnlock(&xtime_lock); +diff --git a/kernel/time/timeconv.c b/kernel/time/timeconv.c +new file mode 100644 +index 0000000..86628e7 +--- /dev/null ++++ b/kernel/time/timeconv.c +@@ -0,0 +1,127 @@ ++/* ++ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. ++ * This file is part of the GNU C Library. ++ * Contributed by Paul Eggert (eggert@twinsun.com). ++ * ++ * The GNU C Library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Library General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * The GNU C Library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public ++ * License along with the GNU C Library; see the file COPYING.LIB. If not, ++ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, ++ * Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * Converts the calendar time to broken-down time representation ++ * Based on code from glibc-2.6 ++ * ++ * 2009-7-14: ++ * Moved from glibc-2.6 to kernel by Zhaolei ++ */ ++ ++#include ++#include ++ ++/* ++ * Nonzero if YEAR is a leap year (every 4 years, ++ * except every 100th isn't, and every 400th is). ++ */ ++static int __isleap(long year) ++{ ++ return (year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0); ++} ++ ++/* do a mathdiv for long type */ ++static long math_div(long a, long b) ++{ ++ return a / b - (a % b < 0); ++} ++ ++/* How many leap years between y1 and y2, y1 must less or equal to y2 */ ++static long leaps_between(long y1, long y2) ++{ ++ long leaps1 = math_div(y1 - 1, 4) - math_div(y1 - 1, 100) ++ + math_div(y1 - 1, 400); ++ long leaps2 = math_div(y2 - 1, 4) - math_div(y2 - 1, 100) ++ + math_div(y2 - 1, 400); ++ return leaps2 - leaps1; ++} ++ ++/* How many days come before each month (0-12). */ ++static const unsigned short __mon_yday[2][13] = { ++ /* Normal years. */ ++ {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, ++ /* Leap years. */ ++ {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} ++}; ++ ++#define SECS_PER_HOUR (60 * 60) ++#define SECS_PER_DAY (SECS_PER_HOUR * 24) ++ ++/** ++ * time_to_tm - converts the calendar time to local broken-down time ++ * ++ * @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970, ++ * Coordinated Universal Time (UTC). ++ * @offset offset seconds adding to totalsecs. ++ * @result pointer to struct tm variable to receive broken-down time ++ */ ++void time_to_tm(time_t totalsecs, int offset, struct tm *result) ++{ ++ long days, rem, y; ++ const unsigned short *ip; ++ ++ days = totalsecs / SECS_PER_DAY; ++ rem = totalsecs % SECS_PER_DAY; ++ rem += offset; ++ while (rem < 0) { ++ rem += SECS_PER_DAY; ++ --days; ++ } ++ while (rem >= SECS_PER_DAY) { ++ rem -= SECS_PER_DAY; ++ ++days; ++ } ++ ++ result->tm_hour = rem / SECS_PER_HOUR; ++ rem %= SECS_PER_HOUR; ++ result->tm_min = rem / 60; ++ result->tm_sec = rem % 60; ++ ++ /* January 1, 1970 was a Thursday. */ ++ result->tm_wday = (4 + days) % 7; ++ if (result->tm_wday < 0) ++ result->tm_wday += 7; ++ ++ y = 1970; ++ ++ while (days < 0 || days >= (__isleap(y) ? 366 : 365)) { ++ /* Guess a corrected year, assuming 365 days per year. */ ++ long yg = y + math_div(days, 365); ++ ++ /* Adjust DAYS and Y to match the guessed year. */ ++ days -= (yg - y) * 365 + leaps_between(y, yg); ++ y = yg; ++ } ++ ++ result->tm_year = y - 1900; ++ ++ result->tm_yday = days; ++ ++ ip = __mon_yday[__isleap(y)]; ++ for (y = 11; days < ip[y]; y--) ++ continue; ++ days -= ip[y]; ++ ++ result->tm_mon = y; ++ result->tm_mday = days + 1; ++} ++EXPORT_SYMBOL(time_to_tm); diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e8c77d9..fb0f46f 100644 --- a/kernel/time/timekeeping.c @@ -1724901,7 +1808236,7 @@ index 7a34cb5..8787739 100644 unregister_trace_block_split(blk_add_trace_split); unregister_trace_block_unplug_io(blk_add_trace_unplug_io); diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c -index 25edd5c..23df777 100644 +index 25edd5c..a142579 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1016,71 +1016,35 @@ static int @@ -1725392,6 +1808727,24 @@ index 25edd5c..23df777 100644 mutex_unlock(&graph_lock); return ret; +@@ -3161,7 +3015,7 @@ int unregister_ftrace_function(struct ftrace_ops *ops) + + int + ftrace_enable_sysctl(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int ret; +@@ -3171,7 +3025,7 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, + + mutex_lock(&ftrace_lock); + +- ret = proc_dointvec(table, write, file, buffer, lenp, ppos); ++ ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled)) + goto out; diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c index 1edaa95..81b1645 100644 --- a/kernel/trace/kmemtrace.c @@ -1732773,7 +1816126,7 @@ index 00dd648..d2cdbab 100644 &trace_graph_entry_watchdog); if (ret) { diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c -index 6a2a9d4..0f6facb 100644 +index 6a2a9d4..8504ac7 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -186,43 +186,33 @@ static const struct file_operations stack_max_size_fops = { @@ -1732849,6 +1816202,23 @@ index 6a2a9d4..0f6facb 100644 } static void print_disabled(struct seq_file *m) +@@ -313,14 +296,14 @@ static const struct file_operations stack_trace_fops = { + + int + stack_trace_sysctl(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int ret; + + mutex_lock(&stack_sysctl_mutex); + +- ret = proc_dointvec(table, write, file, buffer, lenp, ppos); ++ ret = proc_dointvec(table, write, buffer, lenp, ppos); + + if (ret || !write || + (last_stack_tracer_enabled == !!stack_tracer_enabled)) diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index aea321c..a4bb239 100644 --- a/kernel/trace/trace_stat.c @@ -1733803,6 +1817173,39 @@ index 1ef5d3a..cc89be5 100644 + } +} +#endif +diff --git a/kernel/uid16.c b/kernel/uid16.c +index 0314501..4192098 100644 +--- a/kernel/uid16.c ++++ b/kernel/uid16.c +@@ -4,7 +4,6 @@ + */ + + #include +-#include + #include + #include + #include +diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c +index 92359cc..69eae35 100644 +--- a/kernel/utsname_sysctl.c ++++ b/kernel/utsname_sysctl.c +@@ -42,14 +42,14 @@ static void put_uts(ctl_table *table, int write, void *which) + * Special case of dostring for the UTS structure. This has locks + * to observe. Should this be in kernel/sys.c ???? + */ +-static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, ++static int proc_do_uts_string(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct ctl_table uts_table; + int r; + memcpy(&uts_table, table, sizeof(uts_table)); + uts_table.data = get_uts(table, write); +- r = proc_dostring(&uts_table,write,filp,buffer,lenp, ppos); ++ r = proc_dostring(&uts_table,write,buffer,lenp, ppos); + put_uts(table, write, uts_table.data); + return r; + } diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 0668795..addfe2d 100644 --- a/kernel/workqueue.c @@ -1734030,6 +1817433,60 @@ index b2e2fd4..0975087 100644 /* * This is a version of ip_compute_csum() optimized for IP headers, +diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c +index 68dfce5..fc686c7 100644 +--- a/lib/decompress_inflate.c ++++ b/lib/decompress_inflate.c +@@ -27,6 +27,11 @@ + + #define GZIP_IOBUF_SIZE (16*1024) + ++static int nofill(void *buffer, unsigned int len) ++{ ++ return -1; ++} ++ + /* Included from initramfs et al code */ + STATIC int INIT gunzip(unsigned char *buf, int len, + int(*fill)(void*, unsigned int), +@@ -76,6 +81,9 @@ STATIC int INIT gunzip(unsigned char *buf, int len, + goto gunzip_nomem4; + } + ++ if (!fill) ++ fill = nofill; ++ + if (len == 0) + len = fill(zbuf, GZIP_IOBUF_SIZE); + +diff --git a/lib/decompress_unlzma.c b/lib/decompress_unlzma.c +index 0b954e0..ca82fde 100644 +--- a/lib/decompress_unlzma.c ++++ b/lib/decompress_unlzma.c +@@ -82,6 +82,11 @@ struct rc { + #define RC_MODEL_TOTAL_BITS 11 + + ++static int nofill(void *buffer, unsigned int len) ++{ ++ return -1; ++} ++ + /* Called twice: once at startup and once in rc_normalize() */ + static void INIT rc_read(struct rc *rc) + { +@@ -97,7 +102,10 @@ static inline void INIT rc_init(struct rc *rc, + int (*fill)(void*, unsigned int), + char *buffer, int buffer_size) + { +- rc->fill = fill; ++ if (fill) ++ rc->fill = fill; ++ else ++ rc->fill = nofill; + rc->buffer = (uint8_t *)buffer; + rc->buffer_size = buffer_size; + rc->buffer_end = rc->buffer + rc->buffer_size; diff --git a/lib/flex_array.c b/lib/flex_array.c index 7baed2f..66eef2e 100644 --- a/lib/flex_array.c @@ -1735163,7 +1818620,7 @@ index bffe6d7..ac25cd2 100644 sg->length, dir); if (!map) { diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 756ccaf..73a14b8 100644 +index 756ccaf..b91839e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -25,6 +25,7 @@ @@ -1735183,7 +1818640,7 @@ index 756ccaf..73a14b8 100644 sprint_symbol(sym, value); else kallsyms_lookup(value, NULL, NULL, NULL, sym); -@@ -630,60 +631,156 @@ static char *resource_string(char *buf, char *end, struct resource *res, +@@ -630,60 +631,161 @@ static char *resource_string(char *buf, char *end, struct resource *res, } static char *mac_address_string(char *buf, char *end, u8 *addr, @@ -1735235,7 +1818692,7 @@ index 756ccaf..73a14b8 100644 + return p; +} + -+static char *ip6_compressed_string(char *p, const struct in6_addr *addr) ++static char *ip6_compressed_string(char *p, const char *addr) +{ + int i; + int j; @@ -1735247,7 +1818704,12 @@ index 756ccaf..73a14b8 100644 + u8 hi; + u8 lo; + bool needcolon = false; -+ bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr); ++ bool useIPv4; ++ struct in6_addr in6; ++ ++ memcpy(&in6, addr, sizeof(struct in6_addr)); ++ ++ useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); + + memset(zerolength, 0, sizeof(zerolength)); + @@ -1735259,7 +1818721,7 @@ index 756ccaf..73a14b8 100644 + /* find position of longest 0 run */ + for (i = 0; i < range; i++) { + for (j = i; j < range; j++) { -+ if (addr->s6_addr16[j] != 0) ++ if (in6.s6_addr16[j] != 0) + break; + zerolength[i]++; + } @@ -1735286,7 +1818748,7 @@ index 756ccaf..73a14b8 100644 + needcolon = false; + } + /* hex u16 without leading 0s */ -+ word = ntohs(addr->s6_addr16[i]); ++ word = ntohs(in6.s6_addr16[i]); + hi = word >> 8; + lo = word & 0xff; + if (hi) { @@ -1735305,22 +1818767,22 @@ index 756ccaf..73a14b8 100644 + if (useIPv4) { + if (needcolon) + *p++ = ':'; -+ p = ip4_string(p, &addr->s6_addr[12], false); ++ p = ip4_string(p, &in6.s6_addr[12], false); + } + + *p = '\0'; + return p; +} + -+static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt) ++static char *ip6_string(char *p, const char *addr, const char *fmt) +{ + int i; for (i = 0; i < 8; i++) { - p = pack_hex_byte(p, addr[2 * i]); - p = pack_hex_byte(p, addr[2 * i + 1]); - if (!(spec.flags & SPECIAL) && i != 7) -+ p = pack_hex_byte(p, addr->s6_addr[2 * i]); -+ p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]); ++ p = pack_hex_byte(p, *addr++); ++ p = pack_hex_byte(p, *addr++); + if (fmt[0] == 'I' && i != 7) *p++ = ':'; } @@ -1735336,9 +1818798,9 @@ index 756ccaf..73a14b8 100644 + char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; + + if (fmt[0] == 'I' && fmt[2] == 'c') -+ ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr); ++ ip6_compressed_string(ip6_addr, addr); + else -+ ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt); ++ ip6_string(ip6_addr, addr, fmt); return string(buf, end, ip6_addr, spec); } @@ -1735368,7 +1818830,7 @@ index 756ccaf..73a14b8 100644 return string(buf, end, ip4_addr, spec); } -@@ -697,16 +794,21 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, +@@ -697,16 +799,21 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, * * - 'F' For symbolic function descriptor pointers with offset * - 'f' For simple symbolic function names without offset @@ -1735396,7 +1818858,7 @@ index 756ccaf..73a14b8 100644 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a * pointer to the real address. -@@ -721,25 +823,30 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, +@@ -721,25 +828,30 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'F': case 'f': ptr = dereference_function_descriptor(ptr); @@ -1735441,7 +1818903,7 @@ index 756ccaf..73a14b8 100644 break; } spec.flags |= SMALL; -@@ -958,10 +1065,12 @@ qualifier: +@@ -958,10 +1070,12 @@ qualifier: * @args: Arguments for the format string * * This function follows C99 vsnprintf, but has some extensions: @@ -1735455,7 +1818917,7 @@ index 756ccaf..73a14b8 100644 * * The return value is the number of characters which would * be generated for the given input, excluding the trailing -@@ -983,13 +1092,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) +@@ -983,13 +1097,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) /* Reject out-of-range values early. Large positive sizes are used for unknown buffer sizes. */ @@ -1735470,7 +1818932,7 @@ index 756ccaf..73a14b8 100644 str = buf; end = buf + size; -@@ -1417,11 +1521,7 @@ EXPORT_SYMBOL_GPL(vbin_printf); +@@ -1417,11 +1526,7 @@ EXPORT_SYMBOL_GPL(vbin_printf); * a binary buffer that generated by vbin_printf. * * The format follows C99 vsnprintf, but has some extensions: @@ -1735483,7 +1818945,7 @@ index 756ccaf..73a14b8 100644 * * The return value is the number of characters which would * be generated for the given input, excluding the trailing -@@ -1439,13 +1539,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) +@@ -1439,13 +1544,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf) struct printf_spec spec = {0}; @@ -1735522,11 +1818984,11 @@ index c3e4a2b..46a31e5 100644 */ diff --git a/localversion-next b/localversion-next new file mode 100644 -index 0000000..21754dc +index 0000000..ff53159 --- /dev/null +++ b/localversion-next @@ -0,0 +1 @@ -+-next-20090924 ++-next-20090925 diff --git a/mm/Kconfig b/mm/Kconfig index fe5f674..2477607 100644 --- a/mm/Kconfig @@ -1736244,7 +1819706,7 @@ index 701740c..555d5d2 100644 } diff --git a/mm/filemap.c b/mm/filemap.c -index ccea3b6..c1fc205 100644 +index ccea3b6..6c84e59 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -39,11 +39,10 @@ @@ -1736260,6 +1819722,15 @@ index ccea3b6..c1fc205 100644 /* * Shared mappings implemented 30.11.1994. It's not fully working yet, * though. +@@ -59,7 +58,7 @@ + /* + * Lock ordering: + * +- * ->i_mmap_lock (vmtruncate) ++ * ->i_mmap_lock (truncate_pagecache) + * ->private_lock (__free_pte->__set_page_dirty_buffers) + * ->swap_lock (exclusive_swap_page, others) + * ->mapping->tree_lock @@ -105,6 +104,10 @@ * * ->task->proc_lock @@ -1736519,7 +1819990,7 @@ index ccea3b6..c1fc205 100644 } return ret; diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index cafdcee..815dbd4 100644 +index cafdcee..6f048fc 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -234,6 +234,7 @@ unsigned long vma_kernel_pagesize(struct vm_area_struct *vma) @@ -1736825,6 +1820296,55 @@ index cafdcee..815dbd4 100644 snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB", huge_page_size(h)/1024); +@@ -1505,7 +1537,7 @@ static unsigned int cpuset_mems_nr(unsigned int *array) + + #ifdef CONFIG_SYSCTL + int hugetlb_sysctl_handler(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, ++ void __user *buffer, + size_t *length, loff_t *ppos) + { + struct hstate *h = &default_hstate; +@@ -1516,7 +1548,7 @@ int hugetlb_sysctl_handler(struct ctl_table *table, int write, + + table->data = &tmp; + table->maxlen = sizeof(unsigned long); +- proc_doulongvec_minmax(table, write, file, buffer, length, ppos); ++ proc_doulongvec_minmax(table, write, buffer, length, ppos); + + if (write) + h->max_huge_pages = set_max_huge_pages(h, tmp); +@@ -1525,10 +1557,10 @@ int hugetlb_sysctl_handler(struct ctl_table *table, int write, + } + + int hugetlb_treat_movable_handler(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, ++ void __user *buffer, + size_t *length, loff_t *ppos) + { +- proc_dointvec(table, write, file, buffer, length, ppos); ++ proc_dointvec(table, write, buffer, length, ppos); + if (hugepages_treat_as_movable) + htlb_alloc_mask = GFP_HIGHUSER_MOVABLE; + else +@@ -1537,7 +1569,7 @@ int hugetlb_treat_movable_handler(struct ctl_table *table, int write, + } + + int hugetlb_overcommit_handler(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, ++ void __user *buffer, + size_t *length, loff_t *ppos) + { + struct hstate *h = &default_hstate; +@@ -1548,7 +1580,7 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, + + table->data = &tmp; + table->maxlen = sizeof(unsigned long); +- proc_doulongvec_minmax(table, write, file, buffer, length, ppos); ++ proc_doulongvec_minmax(table, write, buffer, length, ppos); + + if (write) { + spin_lock(&hugetlb_lock); @@ -1984,6 +2016,26 @@ static struct page *hugetlbfs_pagecache_page(struct hstate *h, return find_lock_page(mapping, idx); } @@ -1737736,10 +1821256,10 @@ index 4872673..4ea4510 100644 diff --git a/mm/ksm.c b/mm/ksm.c new file mode 100644 -index 0000000..37cc373 +index 0000000..f7edac3 --- /dev/null +++ b/mm/ksm.c -@@ -0,0 +1,1703 @@ +@@ -0,0 +1,1711 @@ +/* + * Memory merging support. + * @@ -1737772,6 +1821292,7 @@ index 0000000..37cc373 +#include +#include +#include ++#include +#include + +#include @@ -1737904,10 +1821425,10 @@ index 0000000..37cc373 +static unsigned long ksm_rmap_items; + +/* Limit on the number of unswappable pages used */ -+static unsigned long ksm_max_kernel_pages = 2000; ++static unsigned long ksm_max_kernel_pages; + +/* Number of pages ksmd should scan in one batch */ -+static unsigned int ksm_thread_pages_to_scan = 200; ++static unsigned int ksm_thread_pages_to_scan = 100; + +/* Milliseconds ksmd should sleep between batches */ +static unsigned int ksm_thread_sleep_millisecs = 20; @@ -1737915,7 +1821436,7 @@ index 0000000..37cc373 +#define KSM_RUN_STOP 0 +#define KSM_RUN_MERGE 1 +#define KSM_RUN_UNMERGE 2 -+static unsigned int ksm_run = KSM_RUN_MERGE; ++static unsigned int ksm_run = KSM_RUN_STOP; + +static DECLARE_WAIT_QUEUE_HEAD(ksm_thread_wait); +static DEFINE_MUTEX(ksm_thread_mutex); @@ -1737925,6 +1821446,11 @@ index 0000000..37cc373 + sizeof(struct __struct), __alignof__(struct __struct),\ + (__flags), NULL) + ++static void __init ksm_init_max_kernel_pages(void) ++{ ++ ksm_max_kernel_pages = nr_free_buffer_pages() / 4; ++} ++ +static int __init ksm_slab_init(void) +{ + rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0); @@ -1739409,6 +1822935,8 @@ index 0000000..37cc373 + struct task_struct *ksm_thread; + int err; + ++ ksm_init_max_kernel_pages(); ++ + err = ksm_slab_init(); + if (err) + goto out; @@ -1739598,10 +1823126,485 @@ index 76eb419..35b1479 100644 return error; diff --git a/mm/memcontrol.c b/mm/memcontrol.c -index fd4529d..9b10d87 100644 +index fd4529d..e2b98a6 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -648,7 +648,7 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -43,6 +44,7 @@ + + struct cgroup_subsys mem_cgroup_subsys __read_mostly; + #define MEM_CGROUP_RECLAIM_RETRIES 5 ++struct mem_cgroup *root_mem_cgroup __read_mostly; + + #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP + /* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */ +@@ -53,6 +55,7 @@ static int really_do_swap_account __initdata = 1; /* for remember boot option*/ + #endif + + static DEFINE_MUTEX(memcg_tasklist); /* can be hold under cgroup_mutex */ ++#define SOFTLIMIT_EVENTS_THRESH (1000) + + /* + * Statistics for memory cgroup. +@@ -66,6 +69,8 @@ enum mem_cgroup_stat_index { + MEM_CGROUP_STAT_MAPPED_FILE, /* # of pages charged as file rss */ + MEM_CGROUP_STAT_PGPGIN_COUNT, /* # of pages paged in */ + MEM_CGROUP_STAT_PGPGOUT_COUNT, /* # of pages paged out */ ++ MEM_CGROUP_STAT_EVENTS, /* sum of pagein + pageout for internal use */ ++ MEM_CGROUP_STAT_SWAPOUT, /* # of pages, swapped out */ + + MEM_CGROUP_STAT_NSTATS, + }; +@@ -78,6 +83,20 @@ struct mem_cgroup_stat { + struct mem_cgroup_stat_cpu cpustat[0]; + }; + ++static inline void ++__mem_cgroup_stat_reset_safe(struct mem_cgroup_stat_cpu *stat, ++ enum mem_cgroup_stat_index idx) ++{ ++ stat->count[idx] = 0; ++} ++ ++static inline s64 ++__mem_cgroup_stat_read_local(struct mem_cgroup_stat_cpu *stat, ++ enum mem_cgroup_stat_index idx) ++{ ++ return stat->count[idx]; ++} ++ + /* + * For accounting under irq disable, no need for increment preempt count. + */ +@@ -117,6 +136,12 @@ struct mem_cgroup_per_zone { + unsigned long count[NR_LRU_LISTS]; + + struct zone_reclaim_stat reclaim_stat; ++ struct rb_node tree_node; /* RB tree node */ ++ unsigned long long usage_in_excess;/* Set to the value by which */ ++ /* the soft limit is exceeded*/ ++ bool on_tree; ++ struct mem_cgroup *mem; /* Back pointer, we cannot */ ++ /* use container_of */ + }; + /* Macro for accessing counter */ + #define MEM_CGROUP_ZSTAT(mz, idx) ((mz)->count[(idx)]) +@@ -130,6 +155,26 @@ struct mem_cgroup_lru_info { + }; + + /* ++ * Cgroups above their limits are maintained in a RB-Tree, independent of ++ * their hierarchy representation ++ */ ++ ++struct mem_cgroup_tree_per_zone { ++ struct rb_root rb_root; ++ spinlock_t lock; ++}; ++ ++struct mem_cgroup_tree_per_node { ++ struct mem_cgroup_tree_per_zone rb_tree_per_zone[MAX_NR_ZONES]; ++}; ++ ++struct mem_cgroup_tree { ++ struct mem_cgroup_tree_per_node *rb_tree_per_node[MAX_NUMNODES]; ++}; ++ ++static struct mem_cgroup_tree soft_limit_tree __read_mostly; ++ ++/* + * The memory controller data structure. The memory controller controls both + * page cache and RSS per cgroup. We would eventually like to provide + * statistics based on the statistics developed by Rik Van Riel for clock-pro, +@@ -186,6 +231,13 @@ struct mem_cgroup { + struct mem_cgroup_stat stat; + }; + ++/* ++ * Maximum loops in mem_cgroup_hierarchical_reclaim(), used for soft ++ * limit reclaim to prevent infinite loops, if they ever occur. ++ */ ++#define MEM_CGROUP_MAX_RECLAIM_LOOPS (100) ++#define MEM_CGROUP_MAX_SOFT_LIMIT_RECLAIM_LOOPS (2) ++ + enum charge_type { + MEM_CGROUP_CHARGE_TYPE_CACHE = 0, + MEM_CGROUP_CHARGE_TYPE_MAPPED, +@@ -200,13 +252,8 @@ enum charge_type { + #define PCGF_CACHE (1UL << PCG_CACHE) + #define PCGF_USED (1UL << PCG_USED) + #define PCGF_LOCK (1UL << PCG_LOCK) +-static const unsigned long +-pcg_default_flags[NR_CHARGE_TYPE] = { +- PCGF_CACHE | PCGF_USED | PCGF_LOCK, /* File Cache */ +- PCGF_USED | PCGF_LOCK, /* Anon */ +- PCGF_CACHE | PCGF_USED | PCGF_LOCK, /* Shmem */ +- 0, /* FORCE */ +-}; ++/* Not used, but added here for completeness */ ++#define PCGF_ACCT (1UL << PCG_ACCT) + + /* for encoding cft->private value on file */ + #define _MEM (0) +@@ -215,15 +262,241 @@ pcg_default_flags[NR_CHARGE_TYPE] = { + #define MEMFILE_TYPE(val) (((val) >> 16) & 0xffff) + #define MEMFILE_ATTR(val) ((val) & 0xffff) + ++/* ++ * Reclaim flags for mem_cgroup_hierarchical_reclaim ++ */ ++#define MEM_CGROUP_RECLAIM_NOSWAP_BIT 0x0 ++#define MEM_CGROUP_RECLAIM_NOSWAP (1 << MEM_CGROUP_RECLAIM_NOSWAP_BIT) ++#define MEM_CGROUP_RECLAIM_SHRINK_BIT 0x1 ++#define MEM_CGROUP_RECLAIM_SHRINK (1 << MEM_CGROUP_RECLAIM_SHRINK_BIT) ++#define MEM_CGROUP_RECLAIM_SOFT_BIT 0x2 ++#define MEM_CGROUP_RECLAIM_SOFT (1 << MEM_CGROUP_RECLAIM_SOFT_BIT) ++ + static void mem_cgroup_get(struct mem_cgroup *mem); + static void mem_cgroup_put(struct mem_cgroup *mem); + static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *mem); + ++static struct mem_cgroup_per_zone * ++mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid) ++{ ++ return &mem->info.nodeinfo[nid]->zoneinfo[zid]; ++} ++ ++static struct mem_cgroup_per_zone * ++page_cgroup_zoneinfo(struct page_cgroup *pc) ++{ ++ struct mem_cgroup *mem = pc->mem_cgroup; ++ int nid = page_cgroup_nid(pc); ++ int zid = page_cgroup_zid(pc); ++ ++ if (!mem) ++ return NULL; ++ ++ return mem_cgroup_zoneinfo(mem, nid, zid); ++} ++ ++static struct mem_cgroup_tree_per_zone * ++soft_limit_tree_node_zone(int nid, int zid) ++{ ++ return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid]; ++} ++ ++static struct mem_cgroup_tree_per_zone * ++soft_limit_tree_from_page(struct page *page) ++{ ++ int nid = page_to_nid(page); ++ int zid = page_zonenum(page); ++ ++ return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid]; ++} ++ ++static void ++__mem_cgroup_insert_exceeded(struct mem_cgroup *mem, ++ struct mem_cgroup_per_zone *mz, ++ struct mem_cgroup_tree_per_zone *mctz) ++{ ++ struct rb_node **p = &mctz->rb_root.rb_node; ++ struct rb_node *parent = NULL; ++ struct mem_cgroup_per_zone *mz_node; ++ ++ if (mz->on_tree) ++ return; ++ ++ mz->usage_in_excess = res_counter_soft_limit_excess(&mem->res); ++ while (*p) { ++ parent = *p; ++ mz_node = rb_entry(parent, struct mem_cgroup_per_zone, ++ tree_node); ++ if (mz->usage_in_excess < mz_node->usage_in_excess) ++ p = &(*p)->rb_left; ++ /* ++ * We can't avoid mem cgroups that are over their soft ++ * limit by the same amount ++ */ ++ else if (mz->usage_in_excess >= mz_node->usage_in_excess) ++ p = &(*p)->rb_right; ++ } ++ rb_link_node(&mz->tree_node, parent, p); ++ rb_insert_color(&mz->tree_node, &mctz->rb_root); ++ mz->on_tree = true; ++} ++ ++static void ++__mem_cgroup_remove_exceeded(struct mem_cgroup *mem, ++ struct mem_cgroup_per_zone *mz, ++ struct mem_cgroup_tree_per_zone *mctz) ++{ ++ if (!mz->on_tree) ++ return; ++ rb_erase(&mz->tree_node, &mctz->rb_root); ++ mz->on_tree = false; ++} ++ ++static void ++mem_cgroup_insert_exceeded(struct mem_cgroup *mem, ++ struct mem_cgroup_per_zone *mz, ++ struct mem_cgroup_tree_per_zone *mctz) ++{ ++ spin_lock(&mctz->lock); ++ __mem_cgroup_insert_exceeded(mem, mz, mctz); ++ spin_unlock(&mctz->lock); ++} ++ ++static void ++mem_cgroup_remove_exceeded(struct mem_cgroup *mem, ++ struct mem_cgroup_per_zone *mz, ++ struct mem_cgroup_tree_per_zone *mctz) ++{ ++ spin_lock(&mctz->lock); ++ __mem_cgroup_remove_exceeded(mem, mz, mctz); ++ spin_unlock(&mctz->lock); ++} ++ ++static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem) ++{ ++ bool ret = false; ++ int cpu; ++ s64 val; ++ struct mem_cgroup_stat_cpu *cpustat; ++ ++ cpu = get_cpu(); ++ cpustat = &mem->stat.cpustat[cpu]; ++ val = __mem_cgroup_stat_read_local(cpustat, MEM_CGROUP_STAT_EVENTS); ++ if (unlikely(val > SOFTLIMIT_EVENTS_THRESH)) { ++ __mem_cgroup_stat_reset_safe(cpustat, MEM_CGROUP_STAT_EVENTS); ++ ret = true; ++ } ++ put_cpu(); ++ return ret; ++} ++ ++static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page) ++{ ++ unsigned long long prev_usage_in_excess, new_usage_in_excess; ++ bool updated_tree = false; ++ struct mem_cgroup_per_zone *mz; ++ struct mem_cgroup_tree_per_zone *mctz; ++ ++ mz = mem_cgroup_zoneinfo(mem, page_to_nid(page), page_zonenum(page)); ++ mctz = soft_limit_tree_from_page(page); ++ ++ /* ++ * We do updates in lazy mode, mem's are removed ++ * lazily from the per-zone, per-node rb tree ++ */ ++ prev_usage_in_excess = mz->usage_in_excess; ++ ++ new_usage_in_excess = res_counter_soft_limit_excess(&mem->res); ++ if (prev_usage_in_excess) { ++ mem_cgroup_remove_exceeded(mem, mz, mctz); ++ updated_tree = true; ++ } ++ if (!new_usage_in_excess) ++ goto done; ++ mem_cgroup_insert_exceeded(mem, mz, mctz); ++ ++done: ++ if (updated_tree) { ++ spin_lock(&mctz->lock); ++ mz->usage_in_excess = new_usage_in_excess; ++ spin_unlock(&mctz->lock); ++ } ++} ++ ++static void mem_cgroup_remove_from_trees(struct mem_cgroup *mem) ++{ ++ int node, zone; ++ struct mem_cgroup_per_zone *mz; ++ struct mem_cgroup_tree_per_zone *mctz; ++ ++ for_each_node_state(node, N_POSSIBLE) { ++ for (zone = 0; zone < MAX_NR_ZONES; zone++) { ++ mz = mem_cgroup_zoneinfo(mem, node, zone); ++ mctz = soft_limit_tree_node_zone(node, zone); ++ mem_cgroup_remove_exceeded(mem, mz, mctz); ++ } ++ } ++} ++ ++static inline unsigned long mem_cgroup_get_excess(struct mem_cgroup *mem) ++{ ++ return res_counter_soft_limit_excess(&mem->res) >> PAGE_SHIFT; ++} ++ ++static struct mem_cgroup_per_zone * ++__mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) ++{ ++ struct rb_node *rightmost = NULL; ++ struct mem_cgroup_per_zone *mz = NULL; ++ ++retry: ++ rightmost = rb_last(&mctz->rb_root); ++ if (!rightmost) ++ goto done; /* Nothing to reclaim from */ ++ ++ mz = rb_entry(rightmost, struct mem_cgroup_per_zone, tree_node); ++ /* ++ * Remove the node now but someone else can add it back, ++ * we will to add it back at the end of reclaim to its correct ++ * position in the tree. ++ */ ++ __mem_cgroup_remove_exceeded(mz->mem, mz, mctz); ++ if (!res_counter_soft_limit_excess(&mz->mem->res) || ++ !css_tryget(&mz->mem->css)) ++ goto retry; ++done: ++ return mz; ++} ++ ++static struct mem_cgroup_per_zone * ++mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) ++{ ++ struct mem_cgroup_per_zone *mz; ++ ++ spin_lock(&mctz->lock); ++ mz = __mem_cgroup_largest_soft_limit_node(mctz); ++ spin_unlock(&mctz->lock); ++ return mz; ++} ++ ++static void mem_cgroup_swap_statistics(struct mem_cgroup *mem, ++ bool charge) ++{ ++ int val = (charge) ? 1 : -1; ++ struct mem_cgroup_stat *stat = &mem->stat; ++ struct mem_cgroup_stat_cpu *cpustat; ++ int cpu = get_cpu(); ++ ++ cpustat = &stat->cpustat[cpu]; ++ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_SWAPOUT, val); ++ put_cpu(); ++} ++ + static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, + struct page_cgroup *pc, + bool charge) + { +- int val = (charge)? 1 : -1; ++ int val = (charge) ? 1 : -1; + struct mem_cgroup_stat *stat = &mem->stat; + struct mem_cgroup_stat_cpu *cpustat; + int cpu = get_cpu(); +@@ -240,28 +513,10 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, + else + __mem_cgroup_stat_add_safe(cpustat, + MEM_CGROUP_STAT_PGPGOUT_COUNT, 1); ++ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_EVENTS, 1); + put_cpu(); + } + +-static struct mem_cgroup_per_zone * +-mem_cgroup_zoneinfo(struct mem_cgroup *mem, int nid, int zid) +-{ +- return &mem->info.nodeinfo[nid]->zoneinfo[zid]; +-} +- +-static struct mem_cgroup_per_zone * +-page_cgroup_zoneinfo(struct page_cgroup *pc) +-{ +- struct mem_cgroup *mem = pc->mem_cgroup; +- int nid = page_cgroup_nid(pc); +- int zid = page_cgroup_zid(pc); +- +- if (!mem) +- return NULL; +- +- return mem_cgroup_zoneinfo(mem, nid, zid); +-} +- + static unsigned long mem_cgroup_get_local_zonestat(struct mem_cgroup *mem, + enum lru_list idx) + { +@@ -354,6 +609,11 @@ static int mem_cgroup_walk_tree(struct mem_cgroup *root, void *data, + return ret; + } + ++static inline bool mem_cgroup_is_root(struct mem_cgroup *mem) ++{ ++ return (mem == root_mem_cgroup); ++} ++ + /* + * Following LRU functions are allowed to be used without PCG_LOCK. + * Operations are called by routine of global LRU independently from memcg. +@@ -371,22 +631,24 @@ static int mem_cgroup_walk_tree(struct mem_cgroup *root, void *data, + void mem_cgroup_del_lru_list(struct page *page, enum lru_list lru) + { + struct page_cgroup *pc; +- struct mem_cgroup *mem; + struct mem_cgroup_per_zone *mz; + + if (mem_cgroup_disabled()) + return; + pc = lookup_page_cgroup(page); + /* can happen while we handle swapcache. */ +- if (list_empty(&pc->lru) || !pc->mem_cgroup) ++ if (!TestClearPageCgroupAcctLRU(pc)) + return; ++ VM_BUG_ON(!pc->mem_cgroup); + /* + * We don't check PCG_USED bit. It's cleared when the "page" is finally + * removed from global LRU. + */ + mz = page_cgroup_zoneinfo(pc); +- mem = pc->mem_cgroup; + MEM_CGROUP_ZSTAT(mz, lru) -= 1; ++ if (mem_cgroup_is_root(pc->mem_cgroup)) ++ return; ++ VM_BUG_ON(list_empty(&pc->lru)); + list_del_init(&pc->lru); + return; + } +@@ -410,8 +672,8 @@ void mem_cgroup_rotate_lru_list(struct page *page, enum lru_list lru) + * For making pc->mem_cgroup visible, insert smp_rmb() here. + */ + smp_rmb(); +- /* unused page is not rotated. */ +- if (!PageCgroupUsed(pc)) ++ /* unused or root page is not rotated. */ ++ if (!PageCgroupUsed(pc) || mem_cgroup_is_root(pc->mem_cgroup)) + return; + mz = page_cgroup_zoneinfo(pc); + list_move(&pc->lru, &mz->lists[lru]); +@@ -425,6 +687,7 @@ void mem_cgroup_add_lru_list(struct page *page, enum lru_list lru) + if (mem_cgroup_disabled()) + return; + pc = lookup_page_cgroup(page); ++ VM_BUG_ON(PageCgroupAcctLRU(pc)); + /* + * Used bit is set without atomic ops but after smp_wmb(). + * For making pc->mem_cgroup visible, insert smp_rmb() here. +@@ -435,6 +698,9 @@ void mem_cgroup_add_lru_list(struct page *page, enum lru_list lru) + + mz = page_cgroup_zoneinfo(pc); + MEM_CGROUP_ZSTAT(mz, lru) += 1; ++ SetPageCgroupAcctLRU(pc); ++ if (mem_cgroup_is_root(pc->mem_cgroup)) ++ return; + list_add(&pc->lru, &mz->lists[lru]); + } + +@@ -469,7 +735,7 @@ static void mem_cgroup_lru_add_after_commit_swapcache(struct page *page) + + spin_lock_irqsave(&zone->lru_lock, flags); + /* link when the page is linked to LRU but page_cgroup isn't */ +- if (PageLRU(page) && list_empty(&pc->lru)) ++ if (PageLRU(page) && !PageCgroupAcctLRU(pc)) + mem_cgroup_add_lru_list(page, page_lru(page)); + spin_unlock_irqrestore(&zone->lru_lock, flags); + } +@@ -648,7 +914,7 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, int nid = z->zone_pgdat->node_id; int zid = zone_idx(z); struct mem_cgroup_per_zone *mz; @@ -1739610,6 +1823613,745 @@ index fd4529d..9b10d87 100644 int ret; BUG_ON(!mem_cont); +@@ -855,28 +1121,62 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) + * If shrink==true, for avoiding to free too much, this returns immedieately. + */ + static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, +- gfp_t gfp_mask, bool noswap, bool shrink) ++ struct zone *zone, ++ gfp_t gfp_mask, ++ unsigned long reclaim_options) + { + struct mem_cgroup *victim; + int ret, total = 0; + int loop = 0; ++ bool noswap = reclaim_options & MEM_CGROUP_RECLAIM_NOSWAP; ++ bool shrink = reclaim_options & MEM_CGROUP_RECLAIM_SHRINK; ++ bool check_soft = reclaim_options & MEM_CGROUP_RECLAIM_SOFT; ++ unsigned long excess = mem_cgroup_get_excess(root_mem); + + /* If memsw_is_minimum==1, swap-out is of-no-use. */ + if (root_mem->memsw_is_minimum) + noswap = true; + +- while (loop < 2) { ++ while (1) { + victim = mem_cgroup_select_victim(root_mem); +- if (victim == root_mem) ++ if (victim == root_mem) { + loop++; ++ if (loop >= 2) { ++ /* ++ * If we have not been able to reclaim ++ * anything, it might because there are ++ * no reclaimable pages under this hierarchy ++ */ ++ if (!check_soft || !total) { ++ css_put(&victim->css); ++ break; ++ } ++ /* ++ * We want to do more targetted reclaim. ++ * excess >> 2 is not to excessive so as to ++ * reclaim too much, nor too less that we keep ++ * coming back to reclaim from this cgroup ++ */ ++ if (total >= (excess >> 2) || ++ (loop > MEM_CGROUP_MAX_RECLAIM_LOOPS)) { ++ css_put(&victim->css); ++ break; ++ } ++ } ++ } + if (!mem_cgroup_local_usage(&victim->stat)) { + /* this cgroup's local usage == 0 */ + css_put(&victim->css); + continue; + } + /* we use swappiness of local cgroup */ +- ret = try_to_free_mem_cgroup_pages(victim, gfp_mask, noswap, +- get_swappiness(victim)); ++ if (check_soft) ++ ret = mem_cgroup_shrink_node_zone(victim, gfp_mask, ++ noswap, get_swappiness(victim), zone, ++ zone->zone_pgdat->node_id); ++ else ++ ret = try_to_free_mem_cgroup_pages(victim, gfp_mask, ++ noswap, get_swappiness(victim)); + css_put(&victim->css); + /* + * At shrinking usage, we can't check we should stop here or +@@ -886,7 +1186,10 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, + if (shrink) + return ret; + total += ret; +- if (mem_cgroup_check_under_limit(root_mem)) ++ if (check_soft) { ++ if (res_counter_check_under_soft_limit(&root_mem->res)) ++ return total; ++ } else if (mem_cgroup_check_under_limit(root_mem)) + return 1 + total; + } + return total; +@@ -965,11 +1268,11 @@ done: + */ + static int __mem_cgroup_try_charge(struct mm_struct *mm, + gfp_t gfp_mask, struct mem_cgroup **memcg, +- bool oom) ++ bool oom, struct page *page) + { +- struct mem_cgroup *mem, *mem_over_limit; ++ struct mem_cgroup *mem, *mem_over_limit, *mem_over_soft_limit; + int nr_retries = MEM_CGROUP_RECLAIM_RETRIES; +- struct res_counter *fail_res; ++ struct res_counter *fail_res, *soft_fail_res = NULL; + + if (unlikely(test_thread_flag(TIF_MEMDIE))) { + /* Don't account this! */ +@@ -996,20 +1299,23 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, + VM_BUG_ON(css_is_removed(&mem->css)); + + while (1) { +- int ret; +- bool noswap = false; ++ int ret = 0; ++ unsigned long flags = 0; + +- ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res); ++ if (mem_cgroup_is_root(mem)) ++ goto done; ++ ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res, ++ &soft_fail_res); + if (likely(!ret)) { + if (!do_swap_account) + break; + ret = res_counter_charge(&mem->memsw, PAGE_SIZE, +- &fail_res); ++ &fail_res, NULL); + if (likely(!ret)) + break; + /* mem+swap counter fails */ +- res_counter_uncharge(&mem->res, PAGE_SIZE); +- noswap = true; ++ res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); ++ flags |= MEM_CGROUP_RECLAIM_NOSWAP; + mem_over_limit = mem_cgroup_from_res_counter(fail_res, + memsw); + } else +@@ -1020,8 +1326,8 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, + if (!(gfp_mask & __GFP_WAIT)) + goto nomem; + +- ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, gfp_mask, +- noswap, false); ++ ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, ++ gfp_mask, flags); + if (ret) + continue; + +@@ -1046,13 +1352,24 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, + goto nomem; + } + } ++ /* ++ * Insert just the ancestor, we should trickle down to the correct ++ * cgroup for reclaim, since the other nodes will be below their ++ * soft limit ++ */ ++ if (soft_fail_res) { ++ mem_over_soft_limit = ++ mem_cgroup_from_res_counter(soft_fail_res, res); ++ if (mem_cgroup_soft_limit_check(mem_over_soft_limit)) ++ mem_cgroup_update_tree(mem_over_soft_limit, page); ++ } ++done: + return 0; + nomem: + css_put(&mem->css); + return -ENOMEM; + } + +- + /* + * A helper function to get mem_cgroup from ID. must be called under + * rcu_read_lock(). The caller must check css_is_removed() or some if +@@ -1119,15 +1436,38 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem, + lock_page_cgroup(pc); + if (unlikely(PageCgroupUsed(pc))) { + unlock_page_cgroup(pc); +- res_counter_uncharge(&mem->res, PAGE_SIZE); +- if (do_swap_account) +- res_counter_uncharge(&mem->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(mem)) { ++ res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); ++ if (do_swap_account) ++ res_counter_uncharge(&mem->memsw, PAGE_SIZE, ++ NULL); ++ } + css_put(&mem->css); + return; + } ++ + pc->mem_cgroup = mem; ++ /* ++ * We access a page_cgroup asynchronously without lock_page_cgroup(). ++ * Especially when a page_cgroup is taken from a page, pc->mem_cgroup ++ * is accessed after testing USED bit. To make pc->mem_cgroup visible ++ * before USED bit, we need memory barrier here. ++ * See mem_cgroup_add_lru_list(), etc. ++ */ + smp_wmb(); +- pc->flags = pcg_default_flags[ctype]; ++ switch (ctype) { ++ case MEM_CGROUP_CHARGE_TYPE_CACHE: ++ case MEM_CGROUP_CHARGE_TYPE_SHMEM: ++ SetPageCgroupCache(pc); ++ SetPageCgroupUsed(pc); ++ break; ++ case MEM_CGROUP_CHARGE_TYPE_MAPPED: ++ ClearPageCgroupCache(pc); ++ SetPageCgroupUsed(pc); ++ break; ++ default: ++ break; ++ } + + mem_cgroup_charge_statistics(mem, pc, true); + +@@ -1178,7 +1518,8 @@ static int mem_cgroup_move_account(struct page_cgroup *pc, + if (pc->mem_cgroup != from) + goto out; + +- res_counter_uncharge(&from->res, PAGE_SIZE); ++ if (!mem_cgroup_is_root(from)) ++ res_counter_uncharge(&from->res, PAGE_SIZE, NULL); + mem_cgroup_charge_statistics(from, pc, false); + + page = pc->page; +@@ -1197,8 +1538,8 @@ static int mem_cgroup_move_account(struct page_cgroup *pc, + 1); + } + +- if (do_swap_account) +- res_counter_uncharge(&from->memsw, PAGE_SIZE); ++ if (do_swap_account && !mem_cgroup_is_root(from)) ++ res_counter_uncharge(&from->memsw, PAGE_SIZE, NULL); + css_put(&from->css); + + css_get(&to->css); +@@ -1238,7 +1579,7 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc, + parent = mem_cgroup_from_cont(pcg); + + +- ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false); ++ ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false, page); + if (ret || !parent) + return ret; + +@@ -1268,9 +1609,11 @@ uncharge: + /* drop extra refcnt by try_charge() */ + css_put(&parent->css); + /* uncharge if move fails */ +- res_counter_uncharge(&parent->res, PAGE_SIZE); +- if (do_swap_account) +- res_counter_uncharge(&parent->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(parent)) { ++ res_counter_uncharge(&parent->res, PAGE_SIZE, NULL); ++ if (do_swap_account) ++ res_counter_uncharge(&parent->memsw, PAGE_SIZE, NULL); ++ } + return ret; + } + +@@ -1295,7 +1638,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, + prefetchw(pc); + + mem = memcg; +- ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true); ++ ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page); + if (ret || !mem) + return ret; + +@@ -1414,14 +1757,14 @@ int mem_cgroup_try_charge_swapin(struct mm_struct *mm, + if (!mem) + goto charge_cur_mm; + *ptr = mem; +- ret = __mem_cgroup_try_charge(NULL, mask, ptr, true); ++ ret = __mem_cgroup_try_charge(NULL, mask, ptr, true, page); + /* drop extra refcnt from tryget */ + css_put(&mem->css); + return ret; + charge_cur_mm: + if (unlikely(!mm)) + mm = &init_mm; +- return __mem_cgroup_try_charge(mm, mask, ptr, true); ++ return __mem_cgroup_try_charge(mm, mask, ptr, true, page); + } + + static void +@@ -1459,7 +1802,10 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr, + * This recorded memcg can be obsolete one. So, avoid + * calling css_tryget + */ +- res_counter_uncharge(&memcg->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(memcg)) ++ res_counter_uncharge(&memcg->memsw, PAGE_SIZE, ++ NULL); ++ mem_cgroup_swap_statistics(memcg, false); + mem_cgroup_put(memcg); + } + rcu_read_unlock(); +@@ -1484,9 +1830,11 @@ void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *mem) + return; + if (!mem) + return; +- res_counter_uncharge(&mem->res, PAGE_SIZE); +- if (do_swap_account) +- res_counter_uncharge(&mem->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(mem)) { ++ res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); ++ if (do_swap_account) ++ res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL); ++ } + css_put(&mem->css); + } + +@@ -1500,6 +1848,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype) + struct page_cgroup *pc; + struct mem_cgroup *mem = NULL; + struct mem_cgroup_per_zone *mz; ++ bool soft_limit_excess = false; + + if (mem_cgroup_disabled()) + return NULL; +@@ -1538,9 +1887,14 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype) + break; + } + +- res_counter_uncharge(&mem->res, PAGE_SIZE); +- if (do_swap_account && (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)) +- res_counter_uncharge(&mem->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(mem)) { ++ res_counter_uncharge(&mem->res, PAGE_SIZE, &soft_limit_excess); ++ if (do_swap_account && ++ (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)) ++ res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL); ++ } ++ if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT) ++ mem_cgroup_swap_statistics(mem, true); + mem_cgroup_charge_statistics(mem, pc, false); + + ClearPageCgroupUsed(pc); +@@ -1554,6 +1908,8 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype) + mz = page_cgroup_zoneinfo(pc); + unlock_page_cgroup(pc); + ++ if (soft_limit_excess && mem_cgroup_soft_limit_check(mem)) ++ mem_cgroup_update_tree(mem, page); + /* at swapout, this memcg will be accessed to record to swap */ + if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT) + css_put(&mem->css); +@@ -1629,7 +1985,9 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent) + * We uncharge this because swap is freed. + * This memcg can be obsolete one. We avoid calling css_tryget + */ +- res_counter_uncharge(&memcg->memsw, PAGE_SIZE); ++ if (!mem_cgroup_is_root(memcg)) ++ res_counter_uncharge(&memcg->memsw, PAGE_SIZE, NULL); ++ mem_cgroup_swap_statistics(memcg, false); + mem_cgroup_put(memcg); + } + rcu_read_unlock(); +@@ -1658,7 +2016,8 @@ int mem_cgroup_prepare_migration(struct page *page, struct mem_cgroup **ptr) + unlock_page_cgroup(pc); + + if (mem) { +- ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false); ++ ret = __mem_cgroup_try_charge(NULL, GFP_KERNEL, &mem, false, ++ page); + css_put(&mem->css); + } + *ptr = mem; +@@ -1798,8 +2157,9 @@ static int mem_cgroup_resize_limit(struct mem_cgroup *memcg, + if (!ret) + break; + +- progress = mem_cgroup_hierarchical_reclaim(memcg, GFP_KERNEL, +- false, true); ++ progress = mem_cgroup_hierarchical_reclaim(memcg, NULL, ++ GFP_KERNEL, ++ MEM_CGROUP_RECLAIM_SHRINK); + curusage = res_counter_read_u64(&memcg->res, RES_USAGE); + /* Usage is reduced ? */ + if (curusage >= oldusage) +@@ -1851,7 +2211,9 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, + if (!ret) + break; + +- mem_cgroup_hierarchical_reclaim(memcg, GFP_KERNEL, true, true); ++ mem_cgroup_hierarchical_reclaim(memcg, NULL, GFP_KERNEL, ++ MEM_CGROUP_RECLAIM_NOSWAP | ++ MEM_CGROUP_RECLAIM_SHRINK); + curusage = res_counter_read_u64(&memcg->memsw, RES_USAGE); + /* Usage is reduced ? */ + if (curusage >= oldusage) +@@ -1862,6 +2224,97 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, + return ret; + } + ++unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, ++ gfp_t gfp_mask, int nid, ++ int zid) ++{ ++ unsigned long nr_reclaimed = 0; ++ struct mem_cgroup_per_zone *mz, *next_mz = NULL; ++ unsigned long reclaimed; ++ int loop = 0; ++ struct mem_cgroup_tree_per_zone *mctz; ++ ++ if (order > 0) ++ return 0; ++ ++ mctz = soft_limit_tree_node_zone(nid, zid); ++ /* ++ * This loop can run a while, specially if mem_cgroup's continuously ++ * keep exceeding their soft limit and putting the system under ++ * pressure ++ */ ++ do { ++ if (next_mz) ++ mz = next_mz; ++ else ++ mz = mem_cgroup_largest_soft_limit_node(mctz); ++ if (!mz) ++ break; ++ ++ reclaimed = mem_cgroup_hierarchical_reclaim(mz->mem, zone, ++ gfp_mask, ++ MEM_CGROUP_RECLAIM_SOFT); ++ nr_reclaimed += reclaimed; ++ spin_lock(&mctz->lock); ++ ++ /* ++ * If we failed to reclaim anything from this memory cgroup ++ * it is time to move on to the next cgroup ++ */ ++ next_mz = NULL; ++ if (!reclaimed) { ++ do { ++ /* ++ * Loop until we find yet another one. ++ * ++ * By the time we get the soft_limit lock ++ * again, someone might have aded the ++ * group back on the RB tree. Iterate to ++ * make sure we get a different mem. ++ * mem_cgroup_largest_soft_limit_node returns ++ * NULL if no other cgroup is present on ++ * the tree ++ */ ++ next_mz = ++ __mem_cgroup_largest_soft_limit_node(mctz); ++ if (next_mz == mz) { ++ css_put(&next_mz->mem->css); ++ next_mz = NULL; ++ } else /* next_mz == NULL or other memcg */ ++ break; ++ } while (1); ++ } ++ mz->usage_in_excess = ++ res_counter_soft_limit_excess(&mz->mem->res); ++ __mem_cgroup_remove_exceeded(mz->mem, mz, mctz); ++ /* ++ * One school of thought says that we should not add ++ * back the node to the tree if reclaim returns 0. ++ * But our reclaim could return 0, simply because due ++ * to priority we are exposing a smaller subset of ++ * memory to reclaim from. Consider this as a longer ++ * term TODO. ++ */ ++ if (mz->usage_in_excess) ++ __mem_cgroup_insert_exceeded(mz->mem, mz, mctz); ++ spin_unlock(&mctz->lock); ++ css_put(&mz->mem->css); ++ loop++; ++ /* ++ * Could not reclaim anything and there are no more ++ * mem cgroups to try or we seem to be looping without ++ * reclaiming anything. ++ */ ++ if (!nr_reclaimed && ++ (next_mz == NULL || ++ loop > MEM_CGROUP_MAX_SOFT_LIMIT_RECLAIM_LOOPS)) ++ break; ++ } while (!nr_reclaimed); ++ if (next_mz) ++ css_put(&next_mz->mem->css); ++ return nr_reclaimed; ++} ++ + /* + * This routine traverse page_cgroup in given list and drop them all. + * *And* this routine doesn't reclaim page itself, just removes page_cgroup. +@@ -2046,20 +2499,64 @@ static int mem_cgroup_hierarchy_write(struct cgroup *cont, struct cftype *cft, + return retval; + } + ++struct mem_cgroup_idx_data { ++ s64 val; ++ enum mem_cgroup_stat_index idx; ++}; ++ ++static int ++mem_cgroup_get_idx_stat(struct mem_cgroup *mem, void *data) ++{ ++ struct mem_cgroup_idx_data *d = data; ++ d->val += mem_cgroup_read_stat(&mem->stat, d->idx); ++ return 0; ++} ++ ++static void ++mem_cgroup_get_recursive_idx_stat(struct mem_cgroup *mem, ++ enum mem_cgroup_stat_index idx, s64 *val) ++{ ++ struct mem_cgroup_idx_data d; ++ d.idx = idx; ++ d.val = 0; ++ mem_cgroup_walk_tree(mem, &d, mem_cgroup_get_idx_stat); ++ *val = d.val; ++} ++ + static u64 mem_cgroup_read(struct cgroup *cont, struct cftype *cft) + { + struct mem_cgroup *mem = mem_cgroup_from_cont(cont); +- u64 val = 0; ++ u64 idx_val, val; + int type, name; + + type = MEMFILE_TYPE(cft->private); + name = MEMFILE_ATTR(cft->private); + switch (type) { + case _MEM: +- val = res_counter_read_u64(&mem->res, name); ++ if (name == RES_USAGE && mem_cgroup_is_root(mem)) { ++ mem_cgroup_get_recursive_idx_stat(mem, ++ MEM_CGROUP_STAT_CACHE, &idx_val); ++ val = idx_val; ++ mem_cgroup_get_recursive_idx_stat(mem, ++ MEM_CGROUP_STAT_RSS, &idx_val); ++ val += idx_val; ++ val <<= PAGE_SHIFT; ++ } else ++ val = res_counter_read_u64(&mem->res, name); + break; + case _MEMSWAP: +- val = res_counter_read_u64(&mem->memsw, name); ++ if (name == RES_USAGE && mem_cgroup_is_root(mem)) { ++ mem_cgroup_get_recursive_idx_stat(mem, ++ MEM_CGROUP_STAT_CACHE, &idx_val); ++ val = idx_val; ++ mem_cgroup_get_recursive_idx_stat(mem, ++ MEM_CGROUP_STAT_RSS, &idx_val); ++ val += idx_val; ++ mem_cgroup_get_recursive_idx_stat(mem, ++ MEM_CGROUP_STAT_SWAPOUT, &idx_val); ++ val <<= PAGE_SHIFT; ++ } else ++ val = res_counter_read_u64(&mem->memsw, name); + break; + default: + BUG(); +@@ -2083,6 +2580,10 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, + name = MEMFILE_ATTR(cft->private); + switch (name) { + case RES_LIMIT: ++ if (mem_cgroup_is_root(memcg)) { /* Can't set limit on root */ ++ ret = -EINVAL; ++ break; ++ } + /* This function does all necessary parse...reuse it */ + ret = res_counter_memparse_write_strategy(buffer, &val); + if (ret) +@@ -2092,6 +2593,20 @@ static int mem_cgroup_write(struct cgroup *cont, struct cftype *cft, + else + ret = mem_cgroup_resize_memsw_limit(memcg, val); + break; ++ case RES_SOFT_LIMIT: ++ ret = res_counter_memparse_write_strategy(buffer, &val); ++ if (ret) ++ break; ++ /* ++ * For memsw, soft limits are hard to implement in terms ++ * of semantics, for now, we support soft limits for ++ * control without swap ++ */ ++ if (type == _MEM) ++ ret = res_counter_set_soft_limit(&memcg->res, val); ++ else ++ ret = -EINVAL; ++ break; + default: + ret = -EINVAL; /* should be BUG() ? */ + break; +@@ -2149,6 +2664,7 @@ static int mem_cgroup_reset(struct cgroup *cont, unsigned int event) + res_counter_reset_failcnt(&mem->memsw); + break; + } ++ + return 0; + } + +@@ -2160,6 +2676,7 @@ enum { + MCS_MAPPED_FILE, + MCS_PGPGIN, + MCS_PGPGOUT, ++ MCS_SWAP, + MCS_INACTIVE_ANON, + MCS_ACTIVE_ANON, + MCS_INACTIVE_FILE, +@@ -2181,6 +2698,7 @@ struct { + {"mapped_file", "total_mapped_file"}, + {"pgpgin", "total_pgpgin"}, + {"pgpgout", "total_pgpgout"}, ++ {"swap", "total_swap"}, + {"inactive_anon", "total_inactive_anon"}, + {"active_anon", "total_active_anon"}, + {"inactive_file", "total_inactive_file"}, +@@ -2205,6 +2723,10 @@ static int mem_cgroup_get_local_stat(struct mem_cgroup *mem, void *data) + s->stat[MCS_PGPGIN] += val; + val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_PGPGOUT_COUNT); + s->stat[MCS_PGPGOUT] += val; ++ if (do_swap_account) { ++ val = mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_SWAPOUT); ++ s->stat[MCS_SWAP] += val * PAGE_SIZE; ++ } + + /* per zone stat */ + val = mem_cgroup_get_local_zonestat(mem, LRU_INACTIVE_ANON); +@@ -2236,8 +2758,11 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, + memset(&mystat, 0, sizeof(mystat)); + mem_cgroup_get_local_stat(mem_cont, &mystat); + +- for (i = 0; i < NR_MCS_STAT; i++) ++ for (i = 0; i < NR_MCS_STAT; i++) { ++ if (i == MCS_SWAP && !do_swap_account) ++ continue; + cb->fill(cb, memcg_stat_strings[i].local_name, mystat.stat[i]); ++ } + + /* Hierarchical information */ + { +@@ -2250,9 +2775,11 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft, + + memset(&mystat, 0, sizeof(mystat)); + mem_cgroup_get_total_stat(mem_cont, &mystat); +- for (i = 0; i < NR_MCS_STAT; i++) ++ for (i = 0; i < NR_MCS_STAT; i++) { ++ if (i == MCS_SWAP && !do_swap_account) ++ continue; + cb->fill(cb, memcg_stat_strings[i].total_name, mystat.stat[i]); +- ++ } + + #ifdef CONFIG_DEBUG_VM + cb->fill(cb, "inactive_ratio", calc_inactive_ratio(mem_cont, NULL)); +@@ -2345,6 +2872,12 @@ static struct cftype mem_cgroup_files[] = { + .read_u64 = mem_cgroup_read, + }, + { ++ .name = "soft_limit_in_bytes", ++ .private = MEMFILE_PRIVATE(_MEM, RES_SOFT_LIMIT), ++ .write_string = mem_cgroup_write, ++ .read_u64 = mem_cgroup_read, ++ }, ++ { + .name = "failcnt", + .private = MEMFILE_PRIVATE(_MEM, RES_FAILCNT), + .trigger = mem_cgroup_reset, +@@ -2438,6 +2971,9 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node) + mz = &pn->zoneinfo[zone]; + for_each_lru(l) + INIT_LIST_HEAD(&mz->lists[l]); ++ mz->usage_in_excess = 0; ++ mz->on_tree = false; ++ mz->mem = mem; + } + return 0; + } +@@ -2483,6 +3019,7 @@ static void __mem_cgroup_free(struct mem_cgroup *mem) + { + int node; + ++ mem_cgroup_remove_from_trees(mem); + free_css_id(&mem_cgroup_subsys, &mem->css); + + for_each_node_state(node, N_POSSIBLE) +@@ -2531,6 +3068,31 @@ static void __init enable_swap_cgroup(void) + } + #endif + ++static int mem_cgroup_soft_limit_tree_init(void) ++{ ++ struct mem_cgroup_tree_per_node *rtpn; ++ struct mem_cgroup_tree_per_zone *rtpz; ++ int tmp, node, zone; ++ ++ for_each_node_state(node, N_POSSIBLE) { ++ tmp = node; ++ if (!node_state(node, N_NORMAL_MEMORY)) ++ tmp = -1; ++ rtpn = kzalloc_node(sizeof(*rtpn), GFP_KERNEL, tmp); ++ if (!rtpn) ++ return 1; ++ ++ soft_limit_tree.rb_tree_per_node[node] = rtpn; ++ ++ for (zone = 0; zone < MAX_NR_ZONES; zone++) { ++ rtpz = &rtpn->rb_tree_per_zone[zone]; ++ rtpz->rb_root = RB_ROOT; ++ spin_lock_init(&rtpz->lock); ++ } ++ } ++ return 0; ++} ++ + static struct cgroup_subsys_state * __ref + mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) + { +@@ -2545,10 +3107,15 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) + for_each_node_state(node, N_POSSIBLE) + if (alloc_mem_cgroup_per_zone_info(mem, node)) + goto free_out; ++ + /* root ? */ + if (cont->parent == NULL) { + enable_swap_cgroup(); + parent = NULL; ++ root_mem_cgroup = mem; ++ if (mem_cgroup_soft_limit_tree_init()) ++ goto free_out; ++ + } else { + parent = mem_cgroup_from_cont(cont->parent); + mem->use_hierarchy = parent->use_hierarchy; +@@ -2577,6 +3144,7 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) + return &mem->css; + free_out: + __mem_cgroup_free(mem); ++ root_mem_cgroup = NULL; + return ERR_PTR(error); + } + +@@ -2612,7 +3180,8 @@ static int mem_cgroup_populate(struct cgroup_subsys *ss, + static void mem_cgroup_move_task(struct cgroup_subsys *ss, + struct cgroup *cont, + struct cgroup *old_cont, +- struct task_struct *p) ++ struct task_struct *p, ++ bool threadgroup) + { + mutex_lock(&memcg_tasklist); + /* diff --git a/mm/memory-failure.c b/mm/memory-failure.c new file mode 100644 index 0000000..729d4b1 @@ -1740449,7 +1825191,7 @@ index 0000000..729d4b1 + __memory_failure(pfn, trapno, 0); +} diff --git a/mm/memory.c b/mm/memory.c -index aede2ce..987389a 100644 +index aede2ce..7e91b5f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -45,6 +45,7 @@ @@ -1740487,7 +1825229,17 @@ index aede2ce..987389a 100644 /* * If a p?d_bad entry is found while walking page tables, report -@@ -442,6 +456,20 @@ static inline int is_cow_mapping(unsigned int flags) +@@ -283,7 +297,8 @@ void free_pgtables(struct mmu_gather *tlb, struct vm_area_struct *vma, + unsigned long addr = vma->vm_start; + + /* +- * Hide vma from rmap and vmtruncate before freeing pgtables ++ * Hide vma from rmap and truncate_pagecache before freeing ++ * pgtables + */ + anon_vma_unlink(vma); + unlink_file_vma(vma); +@@ -442,6 +457,20 @@ static inline int is_cow_mapping(unsigned int flags) return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; } @@ -1740508,7 +1825260,7 @@ index aede2ce..987389a 100644 /* * vm_normal_page -- This function gets the "struct page" associated with a pte. * -@@ -497,7 +525,9 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, +@@ -497,7 +526,9 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, if (HAVE_PTE_SPECIAL) { if (likely(!pte_special(pte))) goto check_pfn; @@ -1740519,7 +1825271,7 @@ index aede2ce..987389a 100644 print_bad_pte(vma, addr, pte, NULL); return NULL; } -@@ -519,6 +549,8 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, +@@ -519,6 +550,8 @@ struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, } } @@ -1740528,7 +1825280,7 @@ index aede2ce..987389a 100644 check_pfn: if (unlikely(pfn > highest_memmap_pfn)) { print_bad_pte(vma, addr, pte, NULL); -@@ -596,8 +628,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, +@@ -596,8 +629,8 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, page = vm_normal_page(vma, addr, pte); if (page) { get_page(page); @@ -1740539,7 +1825291,7 @@ index aede2ce..987389a 100644 } out_set_pte: -@@ -1142,9 +1174,14 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, +@@ -1142,9 +1175,14 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, goto no_page; if ((flags & FOLL_WRITE) && !pte_write(pte)) goto unlock; @@ -1740556,7 +1825308,7 @@ index aede2ce..987389a 100644 if (flags & FOLL_GET) get_page(page); -@@ -1172,65 +1209,46 @@ no_page: +@@ -1172,65 +1210,46 @@ no_page: pte_unmap_unlock(ptep, ptl); if (!pte_none(pte)) return page; @@ -1740641,7 +1825393,7 @@ index aede2ce..987389a 100644 vma = find_extend_vma(mm, start); if (!vma && in_gate_area(tsk, start)) { -@@ -1242,7 +1260,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1242,7 +1261,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, pte_t *pte; /* user gate pages are read-only */ @@ -1740650,7 +1825402,7 @@ index aede2ce..987389a 100644 return i ? : -EFAULT; if (pg > TASK_SIZE) pgd = pgd_offset_k(pg); -@@ -1276,38 +1294,26 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1276,38 +1295,26 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP)) || @@ -1740694,7 +1825446,7 @@ index aede2ce..987389a 100644 cond_resched(); while (!(page = follow_page(vma, start, foll_flags))) { int ret; -@@ -1319,7 +1325,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1319,7 +1326,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (ret & VM_FAULT_ERROR) { if (ret & VM_FAULT_OOM) return i ? i : -ENOMEM; @@ -1740704,7 +1825456,7 @@ index aede2ce..987389a 100644 return i ? i : -EFAULT; BUG(); } -@@ -1418,18 +1425,47 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -1418,18 +1426,47 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int nr_pages, int write, int force, struct page **pages, struct vm_area_struct **vmas) { @@ -1740756,7 +1825508,7 @@ index aede2ce..987389a 100644 pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) { -@@ -1607,7 +1643,8 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, +@@ -1607,7 +1644,8 @@ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr, * If we don't have pte special, then we have to use the pfn_valid() * based VM_MIXEDMAP scheme (see vm_normal_page), and thus we *must* * refcount the page if pfn_valid is true (hence insert_page rather @@ -1740766,7 +1825518,7 @@ index aede2ce..987389a 100644 */ if (!HAVE_PTE_SPECIAL && pfn_valid(pfn)) { struct page *page; -@@ -1973,7 +2010,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -1973,7 +2011,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, * Take out anonymous pages first, anonymous shared vmas are * not dirty accountable. */ @@ -1740775,7 +1825527,7 @@ index aede2ce..987389a 100644 if (!trylock_page(old_page)) { page_cache_get(old_page); pte_unmap_unlock(page_table, ptl); -@@ -2074,10 +2111,19 @@ gotten: +@@ -2074,10 +2112,19 @@ gotten: if (unlikely(anon_vma_prepare(vma))) goto oom; @@ -1740799,7 +1825551,7 @@ index aede2ce..987389a 100644 /* * Don't let another task, with possibly unlocked vma, * keep the mlocked page. -@@ -2087,8 +2133,6 @@ gotten: +@@ -2087,8 +2134,6 @@ gotten: clear_page_mlock(old_page); unlock_page(old_page); } @@ -1740808,7 +1825560,7 @@ index aede2ce..987389a 100644 if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL)) goto oom_free_new; -@@ -2114,9 +2158,14 @@ gotten: +@@ -2114,9 +2159,14 @@ gotten: * seen in the presence of one thread doing SMC and another * thread doing COW. */ @@ -1740825,7 +1825577,80 @@ index aede2ce..987389a 100644 update_mmu_cache(vma, address, entry); if (old_page) { /* -@@ -2511,8 +2560,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2359,7 +2409,7 @@ restart: + * @mapping: the address space containing mmaps to be unmapped. + * @holebegin: byte in first page to unmap, relative to the start of + * the underlying file. This will be rounded down to a PAGE_SIZE +- * boundary. Note that this is different from vmtruncate(), which ++ * boundary. Note that this is different from truncate_pagecache(), which + * must keep the partial page. In contrast, we must get rid of + * partial pages. + * @holelen: size of prospective hole in bytes. This will be rounded +@@ -2410,63 +2460,6 @@ void unmap_mapping_range(struct address_space *mapping, + } + EXPORT_SYMBOL(unmap_mapping_range); + +-/** +- * vmtruncate - unmap mappings "freed" by truncate() syscall +- * @inode: inode of the file used +- * @offset: file offset to start truncating +- * +- * NOTE! We have to be ready to update the memory sharing +- * between the file and the memory map for a potential last +- * incomplete page. Ugly, but necessary. +- */ +-int vmtruncate(struct inode * inode, loff_t offset) +-{ +- if (inode->i_size < offset) { +- unsigned long limit; +- +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && offset > limit) +- goto out_sig; +- if (offset > inode->i_sb->s_maxbytes) +- goto out_big; +- i_size_write(inode, offset); +- } else { +- struct address_space *mapping = inode->i_mapping; +- +- /* +- * truncation of in-use swapfiles is disallowed - it would +- * cause subsequent swapout to scribble on the now-freed +- * blocks. +- */ +- if (IS_SWAPFILE(inode)) +- return -ETXTBSY; +- i_size_write(inode, offset); +- +- /* +- * unmap_mapping_range is called twice, first simply for +- * efficiency so that truncate_inode_pages does fewer +- * single-page unmaps. However after this first call, and +- * before truncate_inode_pages finishes, it is possible for +- * private pages to be COWed, which remain after +- * truncate_inode_pages finishes, hence the second +- * unmap_mapping_range call must be made for correctness. +- */ +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- truncate_inode_pages(mapping, offset); +- unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); +- } +- +- if (inode->i_op->truncate) +- inode->i_op->truncate(inode); +- return 0; +- +-out_sig: +- send_sig(SIGXFSZ, current, 0); +-out_big: +- return -EFBIG; +-} +-EXPORT_SYMBOL(vmtruncate); +- + int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end) + { + struct address_space *mapping = inode->i_mapping; +@@ -2511,8 +2504,15 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, goto out; entry = pte_to_swp_entry(orig_pte); @@ -1740843,7 +1825668,7 @@ index aede2ce..987389a 100644 goto out; } delayacct_set_flag(DELAYACCT_PF_SWAPIN); -@@ -2536,6 +2592,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2536,6 +2536,10 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, /* Had to read the page from swap area: Major fault */ ret = VM_FAULT_MAJOR; count_vm_event(PGMAJFAULT); @@ -1740854,7 +1825679,7 @@ index aede2ce..987389a 100644 } lock_page(page); -@@ -2624,6 +2684,16 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2624,6 +2628,16 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, spinlock_t *ptl; pte_t entry; @@ -1740871,7 +1825696,7 @@ index aede2ce..987389a 100644 /* Allocate our own private page. */ pte_unmap(page_table); -@@ -2638,13 +2708,16 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2638,13 +2652,16 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, goto oom_free_page; entry = mk_pte(page, vma->vm_page_prot); @@ -1740889,7 +1825714,7 @@ index aede2ce..987389a 100644 set_pte_at(mm, address, page_table, entry); /* No need to invalidate - it was non-present before */ -@@ -2699,6 +2772,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2699,6 +2716,12 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (unlikely(ret & (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) return ret; @@ -1741549,7 +1826374,7 @@ index d80311b..8bc969d 100644 if (nstart < prev->vm_end) diff --git a/mm/mremap.c b/mm/mremap.c -index a39b7b9..20a07db 100644 +index a39b7b9..97bff25 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -11,6 +11,7 @@ @@ -1741560,6 +1826385,17 @@ index a39b7b9..20a07db 100644 #include #include #include +@@ -85,8 +86,8 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, + if (vma->vm_file) { + /* + * Subtle point from Rajesh Venkatasubramanian: before +- * moving file-based ptes, we must lock vmtruncate out, +- * since it might clean the dst vma before the src vma, ++ * moving file-based ptes, we must lock truncate_pagecache ++ * out, since it might clean the dst vma before the src vma, + * and we propagate stale pages into the dst afterward. + */ + mapping = vma->vm_file->f_mapping; @@ -174,6 +175,7 @@ static unsigned long move_vma(struct vm_area_struct *vma, unsigned long excess = 0; unsigned long hiwater_vm; @@ -1741588,7 +1826424,7 @@ index a39b7b9..20a07db 100644 new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff); if (!new_vma) diff --git a/mm/nommu.c b/mm/nommu.c -index 66e81e7..8d48424 100644 +index 66e81e7..56a446f 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -33,6 +33,7 @@ @@ -1741613,7 +1826449,54 @@ index 66e81e7..8d48424 100644 struct percpu_counter vm_committed_as; int sysctl_overcommit_memory = OVERCOMMIT_GUESS; /* heuristic overcommit */ int sysctl_overcommit_ratio = 50; /* default is 50% */ -@@ -170,21 +170,20 @@ unsigned int kobjsize(const void *objp) +@@ -83,46 +83,6 @@ struct vm_operations_struct generic_file_vm_ops = { + }; + + /* +- * Handle all mappings that got truncated by a "truncate()" +- * system call. +- * +- * NOTE! We have to be ready to update the memory sharing +- * between the file and the memory map for a potential last +- * incomplete page. Ugly, but necessary. +- */ +-int vmtruncate(struct inode *inode, loff_t offset) +-{ +- struct address_space *mapping = inode->i_mapping; +- unsigned long limit; +- +- if (inode->i_size < offset) +- goto do_expand; +- i_size_write(inode, offset); +- +- truncate_inode_pages(mapping, offset); +- goto out_truncate; +- +-do_expand: +- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; +- if (limit != RLIM_INFINITY && offset > limit) +- goto out_sig; +- if (offset > inode->i_sb->s_maxbytes) +- goto out; +- i_size_write(inode, offset); +- +-out_truncate: +- if (inode->i_op->truncate) +- inode->i_op->truncate(inode); +- return 0; +-out_sig: +- send_sig(SIGXFSZ, current, 0); +-out: +- return -EFBIG; +-} +- +-EXPORT_SYMBOL(vmtruncate); +- +-/* + * Return the total memory allocated for this pointer, not + * just what the caller asked for. + * +@@ -170,21 +130,20 @@ unsigned int kobjsize(const void *objp) } int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, @@ -1741641,7 +1826524,7 @@ index 66e81e7..8d48424 100644 for (i = 0; i < nr_pages; i++) { vma = find_vma(mm, start); -@@ -192,8 +191,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -192,8 +151,8 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, goto finish_or_fault; /* protect what we can, including chardevs */ @@ -1741652,7 +1826535,7 @@ index 66e81e7..8d48424 100644 goto finish_or_fault; if (pages) { -@@ -212,7 +211,6 @@ finish_or_fault: +@@ -212,7 +171,6 @@ finish_or_fault: return i ? : -EFAULT; } @@ -1741660,7 +1826543,7 @@ index 66e81e7..8d48424 100644 /* * get a list of pages in an address range belonging to the specified process * and indicate the VMA that covers each page -@@ -227,9 +225,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, +@@ -227,9 +185,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, int flags = 0; if (write) @@ -1741672,7 +1826555,7 @@ index 66e81e7..8d48424 100644 return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas); } -@@ -627,6 +625,22 @@ static void put_nommu_region(struct vm_region *region) +@@ -627,6 +585,22 @@ static void put_nommu_region(struct vm_region *region) } /* @@ -1741695,7 +1826578,7 @@ index 66e81e7..8d48424 100644 * add a VMA into a process's mm_struct in the appropriate place in the list * and tree and add to the address space's page tree also if not an anonymous * page -@@ -645,6 +659,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -645,6 +619,8 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma) mm->map_count++; vma->vm_mm = mm; @@ -1741704,7 +1826587,7 @@ index 66e81e7..8d48424 100644 /* add the VMA to the mapping */ if (vma->vm_file) { mapping = vma->vm_file->f_mapping; -@@ -707,6 +723,8 @@ static void delete_vma_from_mm(struct vm_area_struct *vma) +@@ -707,6 +683,8 @@ static void delete_vma_from_mm(struct vm_area_struct *vma) kenter("%p", vma); @@ -1741904,7 +1826787,7 @@ index a7b2460..ea2147d 100644 cpuset_print_task_mems_allowed(current); task_unlock(current); diff --git a/mm/page-writeback.c b/mm/page-writeback.c -index 81627eb..12ab293 100644 +index 81627eb..69b5fba 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -36,15 +36,6 @@ @@ -1741958,6 +1826841,66 @@ index 81627eb..12ab293 100644 /* * Scale the writeback cache size proportional to the relative writeout speeds. * +@@ -166,37 +158,37 @@ static void update_completion_period(void) + } + + int dirty_background_ratio_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int ret; + +- ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (ret == 0 && write) + dirty_background_bytes = 0; + return ret; + } + + int dirty_background_bytes_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int ret; + +- ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + if (ret == 0 && write) + dirty_background_ratio = 0; + return ret; + } + + int dirty_ratio_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int old_ratio = vm_dirty_ratio; + int ret; + +- ret = proc_dointvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); + if (ret == 0 && write && vm_dirty_ratio != old_ratio) { + update_completion_period(); + vm_dirty_bytes = 0; +@@ -206,13 +198,13 @@ int dirty_ratio_handler(struct ctl_table *table, int write, + + + int dirty_bytes_handler(struct ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + unsigned long old_bytes = vm_dirty_bytes; + int ret; + +- ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + if (ret == 0 && write && vm_dirty_bytes != old_bytes) { + update_completion_period(); + vm_dirty_ratio = 0; @@ -320,15 +312,13 @@ static void task_dirty_limit(struct task_struct *tsk, unsigned long *pdirty) /* * @@ -1742257,14 +1827200,16 @@ index 81627eb..12ab293 100644 * sysctl handler for /proc/sys/vm/dirty_writeback_centisecs */ int dirty_writeback_centisecs_handler(ctl_table *table, int write, - struct file *file, void __user *buffer, size_t *length, loff_t *ppos) +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) { - proc_dointvec(table, write, file, buffer, length, ppos); +- proc_dointvec(table, write, file, buffer, length, ppos); - if (dirty_writeback_interval) - mod_timer(&wb_timer, jiffies + - msecs_to_jiffies(dirty_writeback_interval * 10)); - else - del_timer(&wb_timer); ++ proc_dointvec(table, write, buffer, length, ppos); return 0; } @@ -1742332,7 +1827277,7 @@ index 81627eb..12ab293 100644 * just fall through and assume that it wants buffer_heads. */ diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index a0de15f..83476a5 100644 +index a0de15f..bf72055 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -48,6 +48,7 @@ @@ -1742825,6 +1827770,24 @@ index a0de15f..83476a5 100644 zone->pages_scanned, (zone_is_all_unreclaimable(zone) ? "yes" : "no") ); +@@ -2305,7 +2391,7 @@ early_param("numa_zonelist_order", setup_numa_zonelist_order); + * sysctl handler for numa_zonelist_order + */ + int numa_zonelist_order_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, ++ void __user *buffer, size_t *length, + loff_t *ppos) + { + char saved_string[NUMA_ZONELIST_ORDER_LEN]; +@@ -2314,7 +2400,7 @@ int numa_zonelist_order_handler(ctl_table *table, int write, + if (write) + strncpy(saved_string, (char*)table->data, + NUMA_ZONELIST_ORDER_LEN); +- ret = proc_dostring(table, write, file, buffer, length, ppos); ++ ret = proc_dostring(table, write, buffer, length, ppos); + if (ret) + return ret; + if (write) { @@ -2783,7 +2869,8 @@ static void setup_zone_migrate_reserve(struct zone *zone) { unsigned long start_pfn, pfn, end_pfn; @@ -1742920,6 +1827883,76 @@ index a0de15f..83476a5 100644 * The inactive anon list should be small enough that the VM never has to * do too much work, but large enough that each inactive page has a chance * to be referenced again before it is swapped out. +@@ -4600,9 +4724,9 @@ module_init(init_per_zone_wmark_min) + * changes. + */ + int min_free_kbytes_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { +- proc_dointvec(table, write, file, buffer, length, ppos); ++ proc_dointvec(table, write, buffer, length, ppos); + if (write) + setup_per_zone_wmarks(); + return 0; +@@ -4610,12 +4734,12 @@ int min_free_kbytes_sysctl_handler(ctl_table *table, int write, + + #ifdef CONFIG_NUMA + int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { + struct zone *zone; + int rc; + +- rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); ++ rc = proc_dointvec_minmax(table, write, buffer, length, ppos); + if (rc) + return rc; + +@@ -4626,12 +4750,12 @@ int sysctl_min_unmapped_ratio_sysctl_handler(ctl_table *table, int write, + } + + int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { + struct zone *zone; + int rc; + +- rc = proc_dointvec_minmax(table, write, file, buffer, length, ppos); ++ rc = proc_dointvec_minmax(table, write, buffer, length, ppos); + if (rc) + return rc; + +@@ -4652,9 +4776,9 @@ int sysctl_min_slab_ratio_sysctl_handler(ctl_table *table, int write, + * if in function of the boot time zone sizes. + */ + int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { +- proc_dointvec_minmax(table, write, file, buffer, length, ppos); ++ proc_dointvec_minmax(table, write, buffer, length, ppos); + setup_per_zone_lowmem_reserve(); + return 0; + } +@@ -4666,13 +4790,13 @@ int lowmem_reserve_ratio_sysctl_handler(ctl_table *table, int write, + */ + + int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write, +- struct file *file, void __user *buffer, size_t *length, loff_t *ppos) ++ void __user *buffer, size_t *length, loff_t *ppos) + { + struct zone *zone; + unsigned int cpu; + int ret; + +- ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos); ++ ret = proc_dointvec_minmax(table, write, buffer, length, ppos); + if (!write || (ret == -EINVAL)) + return ret; + for_each_populated_zone(zone) { @@ -4732,7 +4856,14 @@ void *__init alloc_large_system_hash(const char *tablename, numentries <<= (PAGE_SHIFT - scale); @@ -1749905,7 +1834938,7 @@ index 8ffdc0d..4de7f02 100644 type = swp_type(entry); diff --git a/mm/truncate.c b/mm/truncate.c -index ccc3ecf..a17b397 100644 +index ccc3ecf..450cebd 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -93,11 +93,11 @@ EXPORT_SYMBOL(cancel_dirty_page); @@ -1750028,6 +1835061,74 @@ index ccc3ecf..a17b397 100644 unlock_page(page); if (next > end) break; +@@ -465,3 +497,67 @@ int invalidate_inode_pages2(struct address_space *mapping) + return invalidate_inode_pages2_range(mapping, 0, -1); + } + EXPORT_SYMBOL_GPL(invalidate_inode_pages2); ++ ++/** ++ * truncate_pagecache - unmap and remove pagecache that has been truncated ++ * @inode: inode ++ * @old: old file offset ++ * @new: new file offset ++ * ++ * inode's new i_size must already be written before truncate_pagecache ++ * is called. ++ * ++ * This function should typically be called before the filesystem ++ * releases resources associated with the freed range (eg. deallocates ++ * blocks). This way, pagecache will always stay logically coherent ++ * with on-disk format, and the filesystem would not have to deal with ++ * situations such as writepage being called for a page that has already ++ * had its underlying blocks deallocated. ++ */ ++void truncate_pagecache(struct inode *inode, loff_t old, loff_t new) ++{ ++ if (new < old) { ++ struct address_space *mapping = inode->i_mapping; ++ ++ /* ++ * unmap_mapping_range is called twice, first simply for ++ * efficiency so that truncate_inode_pages does fewer ++ * single-page unmaps. However after this first call, and ++ * before truncate_inode_pages finishes, it is possible for ++ * private pages to be COWed, which remain after ++ * truncate_inode_pages finishes, hence the second ++ * unmap_mapping_range call must be made for correctness. ++ */ ++ unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1); ++ truncate_inode_pages(mapping, new); ++ unmap_mapping_range(mapping, new + PAGE_SIZE - 1, 0, 1); ++ } ++} ++EXPORT_SYMBOL(truncate_pagecache); ++ ++/** ++ * vmtruncate - unmap mappings "freed" by truncate() syscall ++ * @inode: inode of the file used ++ * @offset: file offset to start truncating ++ * ++ * NOTE! We have to be ready to update the memory sharing ++ * between the file and the memory map for a potential last ++ * incomplete page. Ugly, but necessary. ++ */ ++int vmtruncate(struct inode *inode, loff_t offset) ++{ ++ loff_t oldsize; ++ int error; ++ ++ error = inode_newsize_ok(inode, offset); ++ if (error) ++ return error; ++ oldsize = inode->i_size; ++ i_size_write(inode, offset); ++ truncate_pagecache(inode, oldsize, offset); ++ if (inode->i_op->truncate) ++ inode->i_op->truncate(inode); ++ ++ return error; ++} ++EXPORT_SYMBOL(vmtruncate); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index f8189a4..69511e6 100644 --- a/mm/vmalloc.c @@ -1750748,7 +1835849,7 @@ index f8189a4..69511e6 100644 #ifdef CONFIG_PROC_FS static void *s_start(struct seq_file *m, loff_t *pos) diff --git a/mm/vmscan.c b/mm/vmscan.c -index 94e86dd..3e38d79 100644 +index 94e86dd..64e4388 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -148,8 +148,8 @@ static struct zone_reclaim_stat *get_reclaim_stat(struct zone *zone, @@ -1751151,7 +1836252,61 @@ index 94e86dd..3e38d79 100644 sc->may_writepage = 1; } -@@ -1902,7 +1959,7 @@ loop_again: +@@ -1779,11 +1836,45 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, + + #ifdef CONFIG_CGROUP_MEM_RES_CTLR + ++unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem, ++ gfp_t gfp_mask, bool noswap, ++ unsigned int swappiness, ++ struct zone *zone, int nid) ++{ ++ struct scan_control sc = { ++ .may_writepage = !laptop_mode, ++ .may_unmap = 1, ++ .may_swap = !noswap, ++ .swap_cluster_max = SWAP_CLUSTER_MAX, ++ .swappiness = swappiness, ++ .order = 0, ++ .mem_cgroup = mem, ++ .isolate_pages = mem_cgroup_isolate_pages, ++ }; ++ nodemask_t nm = nodemask_of_node(nid); ++ ++ sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | ++ (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); ++ sc.nodemask = &nm; ++ sc.nr_reclaimed = 0; ++ sc.nr_scanned = 0; ++ /* ++ * NOTE: Although we can get the priority field, using it ++ * here is not a good idea, since it limits the pages we can scan. ++ * if we don't reclaim here, the shrink_zone from balance_pgdat ++ * will pick up pages from other mem cgroup's as well. We hack ++ * the priority and make it zero. ++ */ ++ shrink_zone(0, zone, &sc); ++ return sc.nr_reclaimed; ++} ++ + unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, + gfp_t gfp_mask, + bool noswap, + unsigned int swappiness) + { ++ struct zonelist *zonelist; + struct scan_control sc = { + .may_writepage = !laptop_mode, + .may_unmap = 1, +@@ -1795,7 +1886,6 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem_cont, + .isolate_pages = mem_cgroup_isolate_pages, + .nodemask = NULL, /* we don't care the placement */ + }; +- struct zonelist *zonelist; + + sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) | + (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK); +@@ -1902,7 +1992,7 @@ loop_again: for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; @@ -1751160,7 +1836315,31 @@ index 94e86dd..3e38d79 100644 } /* -@@ -1946,7 +2003,7 @@ loop_again: +@@ -1917,6 +2007,7 @@ loop_again: + for (i = 0; i <= end_zone; i++) { + struct zone *zone = pgdat->node_zones + i; + int nr_slab; ++ int nid, zid; + + if (!populated_zone(zone)) + continue; +@@ -1931,6 +2022,15 @@ loop_again: + temp_priority[i] = priority; + sc.nr_scanned = 0; + note_zone_scanning_priority(zone, priority); ++ ++ nid = pgdat->node_id; ++ zid = zone_idx(zone); ++ /* ++ * Call soft limit reclaim before calling shrink_zone. ++ * For now we ignore the return value ++ */ ++ mem_cgroup_soft_limit_reclaim(zone, order, sc.gfp_mask, ++ nid, zid); + /* + * We put equal pressure on every zone, unless one + * zone has way too many pages free already. +@@ -1946,7 +2046,7 @@ loop_again: if (zone_is_all_unreclaimable(zone)) continue; if (nr_slab == 0 && zone->pages_scanned >= @@ -1751169,7 +1836348,7 @@ index 94e86dd..3e38d79 100644 zone_set_flag(zone, ZONE_ALL_UNRECLAIMABLE); /* -@@ -2113,12 +2170,39 @@ void wakeup_kswapd(struct zone *zone, int order) +@@ -2113,12 +2213,39 @@ void wakeup_kswapd(struct zone *zone, int order) wake_up_interruptible(&pgdat->kswapd_wait); } @@ -1751214,7 +1836393,7 @@ index 94e86dd..3e38d79 100644 } #ifdef CONFIG_HIBERNATION -@@ -2133,6 +2217,7 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, +@@ -2133,6 +2260,7 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, { struct zone *zone; unsigned long nr_reclaimed = 0; @@ -1751222,7 +1836401,7 @@ index 94e86dd..3e38d79 100644 for_each_populated_zone(zone) { enum lru_list l; -@@ -2149,11 +2234,14 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, +@@ -2149,11 +2277,14 @@ static void shrink_all_zones(unsigned long nr_pages, int prio, l == LRU_ACTIVE_FILE)) continue; @@ -1751240,7 +1836419,7 @@ index 94e86dd..3e38d79 100644 nr_to_scan = min(nr_pages, lru_pages); nr_reclaimed += shrink_list(l, nr_to_scan, zone, sc, prio); -@@ -2190,7 +2278,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) +@@ -2190,7 +2321,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) current->reclaim_state = &reclaim_state; @@ -1751249,7 +1836428,7 @@ index 94e86dd..3e38d79 100644 nr_slab = global_page_state(NR_SLAB_RECLAIMABLE); /* If slab caches are huge, it's better to hit them first */ while (nr_slab >= lru_pages) { -@@ -2232,7 +2320,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) +@@ -2232,7 +2363,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages) reclaim_state.reclaimed_slab = 0; shrink_slab(sc.nr_scanned, sc.gfp_mask, @@ -1751258,7 +1836437,7 @@ index 94e86dd..3e38d79 100644 sc.nr_reclaimed += reclaim_state.reclaimed_slab; if (sc.nr_reclaimed >= nr_pages) goto out; -@@ -2249,7 +2337,8 @@ unsigned long shrink_all_memory(unsigned long nr_pages) +@@ -2249,7 +2380,8 @@ unsigned long shrink_all_memory(unsigned long nr_pages) if (!sc.nr_reclaimed) { do { reclaim_state.reclaimed_slab = 0; @@ -1751268,7 +1836447,7 @@ index 94e86dd..3e38d79 100644 sc.nr_reclaimed += reclaim_state.reclaimed_slab; } while (sc.nr_reclaimed < nr_pages && reclaim_state.reclaimed_slab > 0); -@@ -2569,7 +2658,7 @@ static void check_move_unevictable_page(struct page *page, struct zone *zone) +@@ -2569,7 +2701,7 @@ static void check_move_unevictable_page(struct page *page, struct zone *zone) retry: ClearPageUnevictable(page); if (page_evictable(page, NULL)) { @@ -1751277,6 +1836456,19 @@ index 94e86dd..3e38d79 100644 __dec_zone_state(zone, NR_UNEVICTABLE); list_move(&page->lru, &zone->lru[l].list); +@@ -2712,10 +2844,10 @@ static void scan_all_zones_unevictable_pages(void) + unsigned long scan_unevictable_pages; + + int scan_unevictable_handler(struct ctl_table *table, int write, +- struct file *file, void __user *buffer, ++ void __user *buffer, + size_t *length, loff_t *ppos) + { +- proc_doulongvec_minmax(table, write, file, buffer, length, ppos); ++ proc_doulongvec_minmax(table, write, buffer, length, ppos); + + if (write && *(unsigned long *)table->data) + scan_all_zones_unevictable_pages(); diff --git a/mm/vmstat.c b/mm/vmstat.c index 138bed5..c81321f 100644 --- a/mm/vmstat.c @@ -1752217,6 +1837409,21 @@ index 38de5ff..ab8419a 100644 "Itf VPI VCI State Remote\n"; if (v == SEQ_START_TOKEN) +diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c +index da0f64f..d6b1b05 100644 +--- a/net/ax25/af_ax25.c ++++ b/net/ax25/af_ax25.c +@@ -1781,8 +1781,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) + ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ); + ax25_info.n2count = ax25->n2count; + ax25_info.state = ax25->state; +- ax25_info.rcv_q = sk_wmem_alloc_get(sk); +- ax25_info.snd_q = sk_rmem_alloc_get(sk); ++ ax25_info.rcv_q = sk_rmem_alloc_get(sk); ++ ax25_info.snd_q = sk_wmem_alloc_get(sk); + ax25_info.vs = ax25->vs; + ax25_info.vr = ax25->vr; + ax25_info.va = ax25->va; diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 59fdb1d..ed37168 100644 --- a/net/bluetooth/Kconfig @@ -1754578,7 +1839785,7 @@ index eb404dc..142ebac 100644 if (ret) goto out_free; diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c -index d22f611..907a82e 100644 +index d22f611..a16a234 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -359,7 +359,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) @@ -1754590,7 +1839797,7 @@ index d22f611..907a82e 100644 /* If err equals -EHOSTUNREACH the error is due to a * martian destination or due to the fact that -@@ -905,46 +905,62 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb, +@@ -905,56 +905,72 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb, * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because * ip_refrag() can return NF_STOLEN. */ static struct nf_hook_ops br_nf_ops[] __read_mostly = { @@ -1754693,6 +1839900,18 @@ index d22f611..907a82e 100644 }; #ifdef CONFIG_SYSCTL + static +-int brnf_sysctl_call_tables(ctl_table * ctl, int write, struct file *filp, ++int brnf_sysctl_call_tables(ctl_table * ctl, int write, + void __user * buffer, size_t * lenp, loff_t * ppos) + { + int ret; + +- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write && *(int *)(ctl->data)) + *(int *)(ctl->data) = 1; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index d5b5537..2114e45 100644 --- a/net/bridge/br_private.h @@ -1759562,6 +1844781,36 @@ index 1bca920..bc44670 100644 if (thash_entries) goal = (thash_entries * +diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c +index 1c6a5bb..6e1f085 100644 +--- a/net/decnet/dn_dev.c ++++ b/net/decnet/dn_dev.c +@@ -164,7 +164,7 @@ static int max_t3[] = { 8191 }; /* Must fit in 16 bits when multiplied by BCT3MU + static int min_priority[1]; + static int max_priority[] = { 127 }; /* From DECnet spec */ + +-static int dn_forwarding_proc(ctl_table *, int, struct file *, ++static int dn_forwarding_proc(ctl_table *, int, + void __user *, size_t *, loff_t *); + static int dn_forwarding_sysctl(ctl_table *table, + void __user *oldval, size_t __user *oldlenp, +@@ -274,7 +274,6 @@ static void dn_dev_sysctl_unregister(struct dn_dev_parms *parms) + } + + static int dn_forwarding_proc(ctl_table *table, int write, +- struct file *filep, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { +@@ -290,7 +289,7 @@ static int dn_forwarding_proc(ctl_table *table, int write, + dn_db = dev->dn_ptr; + old = dn_db->parms.forwarding; + +- err = proc_dointvec(table, write, filep, buffer, lenp, ppos); ++ err = proc_dointvec(table, write, buffer, lenp, ppos); + + if ((err >= 0) && write) { + if (dn_db->parms.forwarding < 0) diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 923786b..794b5bf 100644 --- a/net/decnet/dn_neigh.c @@ -1759615,6 +1844864,26 @@ index 1d6ca8a..57662ca 100644 for(order = 0; (1UL << order) < goal; order++) /* NOTHING */; +diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c +index 5bcd592..26b0ab1 100644 +--- a/net/decnet/sysctl_net_decnet.c ++++ b/net/decnet/sysctl_net_decnet.c +@@ -165,7 +165,6 @@ static int dn_node_address_strategy(ctl_table *table, + } + + static int dn_node_address_handler(ctl_table *table, int write, +- struct file *filp, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { +@@ -276,7 +275,6 @@ static int dn_def_dev_strategy(ctl_table *table, + + + static int dn_def_dev_handler(ctl_table *table, int write, +- struct file * filp, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 41055f3..4b0ea05 100644 --- a/net/dsa/dsa_priv.h @@ -1760834,7 +1846103,7 @@ index 090e999..4e80f33 100644 .solicit = arp_solicit, .error_report = arp_error_report, diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c -index 3863c3a..07336c6 100644 +index 3863c3a..e92f1fd 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1087,6 +1087,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, @@ -1760850,6 +1846119,49 @@ index 3863c3a..07336c6 100644 case NETDEV_CHANGEMTU: if (inetdev_valid_mtu(dev->mtu)) break; +@@ -1264,10 +1270,10 @@ static void inet_forward_change(struct net *net) + } + + static int devinet_conf_proc(ctl_table *ctl, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { +- int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) { + struct ipv4_devconf *cnf = ctl->extra1; +@@ -1336,12 +1342,12 @@ static int devinet_conf_sysctl(ctl_table *table, + } + + static int devinet_sysctl_forward(ctl_table *ctl, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + int *valp = ctl->data; + int val = *valp; +- int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write && *valp != val) { + struct net *net = ctl->extra2; +@@ -1366,12 +1372,12 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, + } + + int ipv4_doint_and_flush(ctl_table *ctl, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + int *valp = ctl->data; + int val = *valp; +- int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + struct net *net = ctl->extra2; + + if (write && *valp != val) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 18bb383..12f7287 100644 --- a/net/ipv4/esp4.c @@ -1762058,7 +1847370,7 @@ index 2979f14..ebb1e58 100644 } done: diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index 278f46f..df93473 100644 +index 278f46f..bb41992 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1514,13 +1514,17 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) @@ -1762111,7 +1847423,39 @@ index 278f46f..df93473 100644 } static int ip_error(struct sk_buff *skb) -@@ -3412,7 +3414,7 @@ int __init ip_rt_init(void) +@@ -3034,7 +3036,7 @@ void ip_rt_multicast_event(struct in_device *in_dev) + + #ifdef CONFIG_SYSCTL + static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write, +- struct file *filp, void __user *buffer, ++ void __user *buffer, + size_t *lenp, loff_t *ppos) + { + if (write) { +@@ -3044,7 +3046,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write, + + memcpy(&ctl, __ctl, sizeof(ctl)); + ctl.data = &flush_delay; +- proc_dointvec(&ctl, write, filp, buffer, lenp, ppos); ++ proc_dointvec(&ctl, write, buffer, lenp, ppos); + + net = (struct net *)__ctl->extra1; + rt_cache_flush(net, flush_delay); +@@ -3104,12 +3106,11 @@ static void rt_secret_reschedule(int old) + } + + static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write, +- struct file *filp, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { + int old = ip_rt_secret_interval; +- int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos); ++ int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); + + rt_secret_reschedule(old); + +@@ -3412,7 +3413,7 @@ int __init ip_rt_init(void) alloc_large_system_hash("IP route cache", sizeof(struct rt_hash_bucket), rhash_entries, @@ -1762120,7 +1847464,7 @@ index 278f46f..df93473 100644 15 : 17, 0, &rt_hash_log, -@@ -3442,7 +3444,7 @@ int __init ip_rt_init(void) +@@ -3442,7 +3443,7 @@ int __init ip_rt_init(void) printk(KERN_ERR "Unable to create route proc files\n"); #ifdef CONFIG_XFRM xfrm_init(); @@ -1762149,6 +1847493,80 @@ index cd2b97f..a6e0e07 100644 memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c])); tmp[0] = (__force u32)saddr; +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index 4710d21..2dcf04d 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -36,7 +36,7 @@ static void set_local_port_range(int range[2]) + } + + /* Validate changes from /proc interface. */ +-static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp, ++static int ipv4_local_port_range(ctl_table *table, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { +@@ -51,7 +51,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp, + }; + + inet_get_local_port_range(range, range + 1); +- ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); + + if (write && ret == 0) { + if (range[1] < range[0]) +@@ -91,7 +91,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, + } + + +-static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * filp, ++static int proc_tcp_congestion_control(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char val[TCP_CA_NAME_MAX]; +@@ -103,7 +103,7 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file * + + tcp_get_default_congestion_control(val); + +- ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos); ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + if (write && ret == 0) + ret = tcp_set_default_congestion_control(val); + return ret; +@@ -129,7 +129,7 @@ static int sysctl_tcp_congestion_control(ctl_table *table, + } + + static int proc_tcp_available_congestion_control(ctl_table *ctl, +- int write, struct file * filp, ++ int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +@@ -140,13 +140,13 @@ static int proc_tcp_available_congestion_control(ctl_table *ctl, + if (!tbl.data) + return -ENOMEM; + tcp_get_available_congestion_control(tbl.data, TCP_CA_BUF_MAX); +- ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos); ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + kfree(tbl.data); + return ret; + } + + static int proc_allowed_congestion_control(ctl_table *ctl, +- int write, struct file * filp, ++ int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +@@ -158,7 +158,7 @@ static int proc_allowed_congestion_control(ctl_table *ctl, + return -ENOMEM; + + tcp_get_allowed_congestion_control(tbl.data, tbl.maxlen); +- ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos); ++ ret = proc_dostring(&tbl, write, buffer, lenp, ppos); + if (write && ret == 0) + ret = tcp_set_allowed_congestion_control(tbl.data); + kfree(tbl.data); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9114524..21387eb 100644 --- a/net/ipv4/tcp.c @@ -1763338,7 +1848756,7 @@ index 0071ee6..74fb2eb 100644 } diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 43b3c9f..55f486d 100644 +index 43b3c9f..1fd0a3d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -137,6 +137,8 @@ static DEFINE_SPINLOCK(addrconf_verify_lock); @@ -1763444,6 +1848862,40 @@ index 43b3c9f..55f486d 100644 spin_unlock_bh(&ifp->lock); read_unlock_bh(&idev->lock); +@@ -3965,14 +3986,14 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) + #ifdef CONFIG_SYSCTL + + static +-int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp, ++int addrconf_sysctl_forward(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = ctl->data; + int val = *valp; + int ret; + +- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) + ret = addrconf_fixup_forwarding(ctl, valp, val); +@@ -4069,14 +4090,14 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old) + } + + static +-int addrconf_sysctl_disable(ctl_table *ctl, int write, struct file * filp, ++int addrconf_sysctl_disable(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = ctl->data; + int val = *valp; + int ret; + +- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) + ret = addrconf_disable_ipv6(ctl, valp, val); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 45f9a2a..e127a32 100644 --- a/net/ipv6/af_inet6.c @@ -1764053,7 +1849505,7 @@ index 4b264ed..f9fcf69 100644 void ipv6_mc_down(struct inet6_dev *idev) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c -index 9eb68e9..7015478 100644 +index 9eb68e9..498b9b0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -98,7 +98,7 @@ static int pndisc_constructor(struct pneigh_entry *n); @@ -1764137,6 +1849589,35 @@ index 9eb68e9..7015478 100644 #ifdef CONFIG_IPV6_ROUTE_INFO if (in6_dev->cnf.accept_ra_rtr_pref && ndopts.nd_opts_ri) { struct nd_opt_hdr *p; +@@ -1733,7 +1735,7 @@ static void ndisc_warn_deprecated_sysctl(struct ctl_table *ctl, + } + } + +-int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) ++int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct net_device *dev = ctl->extra1; + struct inet6_dev *idev; +@@ -1744,16 +1746,16 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f + ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default"); + + if (strcmp(ctl->procname, "retrans_time") == 0) +- ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + else if (strcmp(ctl->procname, "base_reachable_time") == 0) + ret = proc_dointvec_jiffies(ctl, write, +- filp, buffer, lenp, ppos); ++ buffer, lenp, ppos); + + else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) || + (strcmp(ctl->procname, "base_reachable_time_ms") == 0)) + ret = proc_dointvec_ms_jiffies(ctl, write, +- filp, buffer, lenp, ppos); ++ buffer, lenp, ppos); + else + ret = -1; + diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index ced1f2c..cc9f8ef 100644 --- a/net/ipv6/netfilter/ip6_tables.c @@ -1764669,7 +1850150,7 @@ index 2642a41..da5bd0e 100644 .handler = ipv6_frag_rcv, .flags = INET6_PROTO_NOPOLICY, diff --git a/net/ipv6/route.c b/net/ipv6/route.c -index 1473ee0..77aecbe 100644 +index 1473ee0..d6fe764 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -481,7 +481,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, @@ -1764744,6 +1850225,22 @@ index 1473ee0..77aecbe 100644 net->ipv6.rt6_stats->fib_discarded_routes); return 0; +@@ -2524,13 +2524,13 @@ static const struct file_operations rt6_stats_seq_fops = { + #ifdef CONFIG_SYSCTL + + static +-int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, ++int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct net *net = current->nsproxy->net_ns; + int delay = net->ipv6.sysctl.flush_delay; + if (write) { +- proc_dointvec(ctl, write, filp, buffer, lenp, ppos); ++ proc_dointvec(ctl, write, buffer, lenp, ppos); + fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net); + return 0; + } else @@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) if (table) { @@ -1765572,6 +1851069,40 @@ index 8ff1861..318766e 100644 {"discovery", &discovery_seq_fops}, {"irttp", &irttp_seq_fops}, {"irlmp", &irlmp_seq_fops}, +diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c +index 57f8817..5c86567 100644 +--- a/net/irda/irsysctl.c ++++ b/net/irda/irsysctl.c +@@ -73,12 +73,12 @@ static int min_lap_keepalive_time = 100; /* 100us */ + /* For other sysctl, I've no idea of the range. Maybe Dag could help + * us on that - Jean II */ + +-static int do_devname(ctl_table *table, int write, struct file *filp, ++static int do_devname(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int ret; + +- ret = proc_dostring(table, write, filp, buffer, lenp, ppos); ++ ret = proc_dostring(table, write, buffer, lenp, ppos); + if (ret == 0 && write) { + struct ias_value *val; + +@@ -90,12 +90,12 @@ static int do_devname(ctl_table *table, int write, struct file *filp, + } + + +-static int do_discovery(ctl_table *table, int write, struct file *filp, ++static int do_discovery(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int ret; + +- ret = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret) + return ret; + diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 49c15b4..d985d16 100644 --- a/net/iucv/af_iucv.c @@ -1776505,7 +1862036,7 @@ index 8dddb17..b95699f 100644 module_init(ip_vs_init); diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c -index 7c1333c..fba2892 100644 +index 7c1333c..446e9bd 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -18,6 +18,9 @@ @@ -1776639,6 +1862170,41 @@ index 7c1333c..fba2892 100644 return -ENOENT; } old_sched = sched; +@@ -1495,14 +1496,14 @@ static int ip_vs_zero_all(void) + + + static int +-proc_do_defense_mode(ctl_table *table, int write, struct file * filp, ++proc_do_defense_mode(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; + int val = *valp; + int rc; + +- rc = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ rc = proc_dointvec(table, write, buffer, lenp, ppos); + if (write && (*valp != val)) { + if ((*valp < 0) || (*valp > 3)) { + /* Restore the correct value */ +@@ -1516,7 +1517,7 @@ proc_do_defense_mode(ctl_table *table, int write, struct file * filp, + + + static int +-proc_do_sync_threshold(ctl_table *table, int write, struct file *filp, ++proc_do_sync_threshold(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +@@ -1526,7 +1527,7 @@ proc_do_sync_threshold(ctl_table *table, int write, struct file *filp, + /* backup the value first */ + memcpy(val, valp, sizeof(val)); + +- rc = proc_dointvec(table, write, filp, buffer, lenp, ppos); ++ rc = proc_dointvec(table, write, buffer, lenp, ppos); + if (write && (valp[0] < 0 || valp[1] < 0 || valp[0] >= valp[1])) { + /* Restore the correct value */ + memcpy(valp, val, sizeof(val)); @@ -2077,8 +2078,8 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) return -EPERM; @@ -1777986,6 +1863552,28 @@ index 49479d1..59d8064 100644 { struct nf_conntrack_tuple tuple; struct nf_conntrack_expect *exp; +diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c +index 4e62030..c93494f 100644 +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -226,7 +226,7 @@ static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3]; + static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1]; + static struct ctl_table_header *nf_log_dir_header; + +-static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp, ++static int nf_log_proc_dostring(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + const struct nf_logger *logger; +@@ -260,7 +260,7 @@ static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp, + table->data = "NONE"; + else + table->data = logger->name; +- r = proc_dostring(table, write, filp, buffer, lenp, ppos); ++ r = proc_dostring(table, write, buffer, lenp, ppos); + mutex_unlock(&nf_log_mutex); + } + diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 92761a9..eedc0c1 100644 --- a/net/netfilter/nfnetlink.c @@ -1780801,6 +1866389,28 @@ index ada2a35..7a4ee39 100644 + .release = seq_release_net, +}; +#endif +diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c +index 7b5749e..2220f33 100644 +--- a/net/phonet/sysctl.c ++++ b/net/phonet/sysctl.c +@@ -56,7 +56,7 @@ void phonet_get_local_port_range(int *min, int *max) + } while (read_seqretry(&local_port_range_lock, seq)); + } + +-static int proc_local_port_range(ctl_table *table, int write, struct file *filp, ++static int proc_local_port_range(ctl_table *table, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos) + { +@@ -70,7 +70,7 @@ static int proc_local_port_range(ctl_table *table, int write, struct file *filp, + .extra2 = &local_port_range_max, + }; + +- ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos); ++ ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); + + if (write && ret == 0) { + if (range[1] < range[0]) diff --git a/net/rds/Kconfig b/net/rds/Kconfig index 796773b..ec753b3 100644 --- a/net/rds/Kconfig @@ -1788553,6 +1874163,18 @@ index 2278a50..f6c51e5 100644 } out: +diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c +index c70dd7f..1db618f 100644 +--- a/net/sunrpc/auth_null.c ++++ b/net/sunrpc/auth_null.c +@@ -8,7 +8,6 @@ + + #include + #include +-#include + #include + + #ifdef RPC_DEBUG diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index ff0c230..d6eee29 100644 --- a/net/sunrpc/cache.c @@ -1791842,6 +1877464,28 @@ index 23128ee..ccc5e83 100644 } /* +diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c +index 5231f7a..42f9748 100644 +--- a/net/sunrpc/sysctl.c ++++ b/net/sunrpc/sysctl.c +@@ -56,7 +56,7 @@ rpc_unregister_sysctl(void) + } + } + +-static int proc_do_xprt(ctl_table *table, int write, struct file *file, ++static int proc_do_xprt(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char tmpbuf[256]; +@@ -71,7 +71,7 @@ static int proc_do_xprt(ctl_table *table, int write, struct file *file, + } + + static int +-proc_dodebug(ctl_table *table, int write, struct file *file, ++proc_dodebug(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char tmpbuf[20], c, *s; diff --git a/net/sunrpc/timer.c b/net/sunrpc/timer.c index 31becbf..dd82434 100644 --- a/net/sunrpc/timer.c @@ -1792024,6 +1877668,19 @@ index f412a85..fd46d42 100644 return xprt; } +diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c +index 8710117..35fb68b 100644 +--- a/net/sunrpc/xprtrdma/svc_rdma.c ++++ b/net/sunrpc/xprtrdma/svc_rdma.c +@@ -80,7 +80,7 @@ struct kmem_cache *svc_rdma_ctxt_cachep; + * current value. + */ + static int read_reset_stat(ctl_table *table, int write, +- struct file *filp, void __user *buffer, size_t *lenp, ++ void __user *buffer, size_t *lenp, + loff_t *ppos) + { + atomic_t *stat = (atomic_t *)table->data; diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index 5151f9f..0cf5e8c 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -1805802,6 +1891459,20 @@ index e3097c0..fe30751 100644 { int ret = 0; +diff --git a/security/device_cgroup.c b/security/device_cgroup.c +index b8186ba..6cf8fd2 100644 +--- a/security/device_cgroup.c ++++ b/security/device_cgroup.c +@@ -61,7 +61,8 @@ static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) + struct cgroup_subsys devices_subsys; + + static int devcgroup_can_attach(struct cgroup_subsys *ss, +- struct cgroup *new_cgroup, struct task_struct *task) ++ struct cgroup *new_cgroup, struct task_struct *task, ++ bool threadgroup) + { + if (current != task && !capable(CAP_SYS_ADMIN)) + return -EPERM; diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 6bfc7ea..8e9777b 100644 --- a/security/integrity/ima/ima_fs.c @@ -1806996,9 +1892667,18 @@ index b611d49..5e05dc0 100644 { .ctl_name = 0 } }; diff --git a/security/lsm_audit.c b/security/lsm_audit.c -index 94b8684..500aad0 100644 +index 94b8684..3bb90b6 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c +@@ -187,7 +187,7 @@ static inline void print_ipv6_addr(struct audit_buffer *ab, + char *name1, char *name2) + { + if (!ipv6_addr_any(addr)) +- audit_log_format(ab, " %s=%pI6", name1, addr); ++ audit_log_format(ab, " %s=%pI6c", name1, addr); + if (port) + audit_log_format(ab, " %s=%d", name2, ntohs(port)); + } @@ -220,6 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, } @@ -1807008,6 +1892688,25 @@ index 94b8684..500aad0 100644 case LSM_AUDIT_DATA_IPC: audit_log_format(ab, " key=%d ", a->u.ipc_id); break; +diff --git a/security/min_addr.c b/security/min_addr.c +index 14cc7b3..c844eed 100644 +--- a/security/min_addr.c ++++ b/security/min_addr.c +@@ -28,12 +28,12 @@ static void update_mmap_min_addr(void) + * sysctl handler which just sets dac_mmap_min_addr = the new value and then + * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly + */ +-int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp, ++int mmap_min_addr_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + int ret; + +- ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos); ++ ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); + + update_mmap_min_addr(); + diff --git a/security/security.c b/security/security.c index dc7674f..c4c6732 100644 --- a/security/security.c @@ -1807450,7 +1893149,7 @@ index c73aeaa..c0a454a 100644 +} +EXPORT_SYMBOL_GPL(selinux_is_enabled); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c -index 8d8b69c..417f7c9 100644 +index 8d8b69c..bb230d5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -13,8 +13,8 @@ @@ -1807658,6 +1893357,15 @@ index 8d8b69c..417f7c9 100644 spin_lock(&files->file_lock); for (;;) { +@@ -2405,7 +2411,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) + /* Wake up the parent if it is waiting so that it can recheck + * wait permission to the new task SID. */ + read_lock(&tasklist_lock); +- wake_up_interruptible(¤t->real_parent->signal->wait_chldexit); ++ __wake_up_parent(current, current->real_parent); + read_unlock(&tasklist_lock); + } + @@ -2515,7 +2521,7 @@ out: static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) { @@ -1815109,7 +1900817,7 @@ index 6812fbe..cc24e67 100644 +EXPORT_SYMBOL_HDA(snd_hda_load_patch); +#endif /* CONFIG_SND_HDA_PATCH_LOADER */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index 175f07a..20a66f8 100644 +index 175f07a..c9ad182 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -61,6 +61,9 @@ static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; @@ -1815169,7 +1900877,7 @@ index 175f07a..20a66f8 100644 return 0; } -@@ -2284,6 +2299,30 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) +@@ -2284,6 +2299,31 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) } } @@ -1815177,6 +1900885,7 @@ index 175f07a..20a66f8 100644 + * white-list for enable_msi + */ +static struct snd_pci_quirk msi_white_list[] __devinitdata = { ++ SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1), + SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), + {} +}; @@ -1815200,7 +1900909,7 @@ index 175f07a..20a66f8 100644 /* * constructor -@@ -2318,7 +2357,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, +@@ -2318,7 +2358,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->pci = pci; chip->irq = -1; chip->driver_type = driver_type; @@ -1815209,7 +1900918,7 @@ index 175f07a..20a66f8 100644 chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); -@@ -2526,15 +2565,32 @@ static int __devinit azx_probe(struct pci_dev *pci, +@@ -2526,15 +2566,32 @@ static int __devinit azx_probe(struct pci_dev *pci, return err; } @@ -1815243,7 +1900952,7 @@ index 175f07a..20a66f8 100644 /* create PCM streams */ err = snd_hda_build_pcms(chip->bus); -@@ -2546,8 +2602,6 @@ static int __devinit azx_probe(struct pci_dev *pci, +@@ -2546,8 +2603,6 @@ static int __devinit azx_probe(struct pci_dev *pci, if (err < 0) goto out_free; @@ -1815252,7 +1900961,7 @@ index 175f07a..20a66f8 100644 err = snd_card_register(card); if (err < 0) goto out_free; -@@ -2649,11 +2703,15 @@ static struct pci_device_id azx_ids[] = { +@@ -2649,11 +2704,15 @@ static struct pci_device_id azx_ids[] = { /* this entry seems still valid -- i.e. without emu20kx chip */ { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, #endif @@ -1816763,7 +1902472,7 @@ index c921264..780e1a7 100644 } diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c -index ac868c5..9d899ed 100644 +index ac868c5..3fbbc8c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -108,6 +108,8 @@ struct conexant_spec { @@ -1816775,7 +1902484,42 @@ index ac868c5..9d899ed 100644 }; static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, -@@ -1908,6 +1910,480 @@ static int patch_cxt5051(struct hda_codec *codec) +@@ -680,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = { + }; + + static struct hda_input_mux cxt5045_capture_source_benq = { +- .num_items = 3, ++ .num_items = 5, + .items = { + { "IntMic", 0x1 }, + { "ExtMic", 0x2 }, + { "LineIn", 0x3 }, ++ { "CD", 0x4 }, ++ { "Mixer", 0x0 }, + } + }; + +@@ -809,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { + }; + + static struct snd_kcontrol_new cxt5045_benq_mixers[] = { ++ HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), ++ HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), ++ HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), ++ HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT), ++ + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), + HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), + ++ HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT), ++ HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT), ++ + {} + }; + +@@ -1908,6 +1920,480 @@ static int patch_cxt5051(struct hda_codec *codec) return 0; } @@ -1817256,7 +1903000,7 @@ index ac868c5..9d899ed 100644 /* */ -@@ -1919,12 +2395,15 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { +@@ -1919,12 +2405,15 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_cxt5047 }, { .id = 0x14f15051, .name = "CX20561 (Hermosa)", .patch = patch_cxt5051 }, @@ -1827856,9 +1913600,26 @@ index edfbdc0..9825b71 100644 module_init(bf5xx_ad73311_init); diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c -index af06904..1e9d161 100644 +index af06904..084b688 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c +@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = { + * TFS. When Port G is selected and EMAC then there is a conflict between + * the PHY interrupt line and TFS. Current settings prevent the conflict + * by ignoring the TFS pin when Port G is selected. This allows both +- * ssm2602 using Port G and EMAC concurrently. ++ * codecs and EMAC using Port G concurrently. + */ +-#ifdef CONFIG_BF527_SPORT0_PORTF +-#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) +-#else ++#ifdef CONFIG_BF527_SPORT0_PORTG + #define LOCAL_SPORT0_TFS (0) ++#else ++#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) + #endif + + static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, @@ -227,7 +227,8 @@ static int bf5xx_i2s_probe(struct platform_device *pdev, return 0; } @@ -1828356,7 +1914117,7 @@ index 0000000..ddc5047 +#endif diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c new file mode 100644 -index 0000000..3096bad +index 0000000..ff546e9 --- /dev/null +++ b/sound/soc/blackfin/bf5xx-tdm.c @@ -0,0 +1,343 @@ @@ -1828440,12 +1914201,12 @@ index 0000000..3096bad + * TFS. When Port G is selected and EMAC then there is a conflict between + * the PHY interrupt line and TFS. Current settings prevent the conflict + * by ignoring the TFS pin when Port G is selected. This allows both -+ * ssm2602 using Port G and EMAC concurrently. ++ * codecs and EMAC using Port G concurrently. + */ -+#ifdef CONFIG_BF527_SPORT0_PORTF -+#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) -+#else ++#ifdef CONFIG_BF527_SPORT0_PORTG +#define LOCAL_SPORT0_TFS (0) ++#else ++#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) +#endif + +static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, @@ -1848545,7 +1934306,7 @@ index 58fd1cb..67414f6 100644 if (ret) platform_device_put(evm_snd_device); diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c -index b1ea52f..12a6c54 100644 +index b1ea52f..4ae7070 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -22,6 +22,8 @@ @@ -1848580,18 +1934341,36 @@ index b1ea52f..12a6c54 100644 enum { DAVINCI_MCBSP_WORD_8 = 0, DAVINCI_MCBSP_WORD_12, -@@ -112,6 +107,10 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = { +@@ -102,18 +97,19 @@ enum { + DAVINCI_MCBSP_WORD_32, + }; +-static struct davinci_pcm_dma_params davinci_i2s_pcm_out = { +- .name = "I2S PCM Stereo out", +-}; +- +-static struct davinci_pcm_dma_params davinci_i2s_pcm_in = { +- .name = "I2S PCM Stereo in", +-}; +- struct davinci_mcbsp_dev { ++ /* ++ * dma_params must be first because rtd->dai->cpu_dai->private_data ++ * is cast to a pointer of an array of struct davinci_pcm_dma_params in ++ * davinci_pcm_open. ++ */ ++ struct davinci_pcm_dma_params dma_params[2]; void __iomem *base; +#define MOD_DSP_A 0 +#define MOD_DSP_B 1 + int mode; + u32 pcr; struct clk *clk; - struct davinci_pcm_dma_params *dma_params[2]; +- struct davinci_pcm_dma_params *dma_params[2]; }; -@@ -127,96 +126,100 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg) + + static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, +@@ -127,97 +123,93 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg) return __raw_readl(dev->base + reg); } @@ -1848722,6 +1934501,18 @@ index b1ea52f..12a6c54 100644 - else - MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 0); - davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); +-} +- +-static int davinci_i2s_startup(struct snd_pcm_substream *substream, +- struct snd_soc_dai *dai) +-{ +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; +- struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; +- +- cpu_dai->dma_data = dev->dma_params[substream->stream]; +- +- return 0; + spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); + spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST); + spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST; @@ -1848729,21 +1934520,8 @@ index b1ea52f..12a6c54 100644 + toggle_clock(dev, playback); } - static int davinci_i2s_startup(struct snd_pcm_substream *substream, -- struct snd_soc_dai *dai) -+ struct snd_soc_dai *cpu_dai) - { -- struct snd_soc_pcm_runtime *rtd = substream->private_data; -- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; -- struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; -- -+ struct davinci_mcbsp_dev *dev = cpu_dai->private_data; - cpu_dai->dma_data = dev->dma_params[substream->stream]; -- - return 0; - } - -@@ -228,12 +231,11 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, + #define DEFAULT_BITPERSAMPLE 16 +@@ -228,12 +220,11 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, struct davinci_mcbsp_dev *dev = cpu_dai->private_data; unsigned int pcr; unsigned int srgr; @@ -1848757,7 +1934535,7 @@ index b1ea52f..12a6c54 100644 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* cpu is master */ -@@ -258,11 +260,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, +@@ -258,11 +249,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, return -EINVAL; } @@ -1848770,7 +1934548,7 @@ index b1ea52f..12a6c54 100644 case SND_SOC_DAIFMT_I2S: /* Davinci doesn't support TRUE I2S, but some codecs will have * the left and right channels contiguous. This allows -@@ -282,8 +281,10 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, +@@ -282,8 +270,10 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, */ fmt ^= SND_SOC_DAIFMT_NB_IF; case SND_SOC_DAIFMT_DSP_A: @@ -1848783,7 +1934561,7 @@ index b1ea52f..12a6c54 100644 break; default: printk(KERN_ERR "%s:bad format\n", __func__); -@@ -343,9 +344,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, +@@ -343,9 +333,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, return -EINVAL; } davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); @@ -1848794,15 +1934572,16 @@ index b1ea52f..12a6c54 100644 return 0; } -@@ -353,31 +353,40 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, +@@ -353,31 +342,41 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; - struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; -+ struct davinci_pcm_dma_params *dma_params = dai->dma_data; + struct davinci_mcbsp_dev *dev = dai->private_data; ++ struct davinci_pcm_dma_params *dma_params = ++ &dev->dma_params[substream->stream]; struct snd_interval *i = NULL; int mcbsp_word_length; - u32 w; @@ -1848848,7 +1934627,7 @@ index b1ea52f..12a6c54 100644 /* Determine xfer data type */ switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: -@@ -397,18 +406,31 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, +@@ -397,18 +396,31 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } @@ -1848870,14 +1934649,14 @@ index b1ea52f..12a6c54 100644 + DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); + xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | + DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length); - ++ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr); + else + davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr); + return 0; +} -+ + +static int davinci_i2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ @@ -1848890,7 +1934669,7 @@ index b1ea52f..12a6c54 100644 } return 0; } -@@ -416,35 +438,72 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, +@@ -416,35 +428,71 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -1848924,7 +1934703,10 @@ index b1ea52f..12a6c54 100644 - struct snd_soc_dai *dai) +static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) -+{ + { +- struct snd_soc_device *socdev = platform_get_drvdata(pdev); +- struct snd_soc_card *card = socdev->card; +- struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai; + struct davinci_mcbsp_dev *dev = dai->private_data; + int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + davinci_mcbsp_stop(dev, playback); @@ -1848933,7 +1934715,6 @@ index b1ea52f..12a6c54 100644 +#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 + +static struct snd_soc_dai_ops davinci_i2s_dai_ops = { -+ .startup = davinci_i2s_startup, + .shutdown = davinci_i2s_shutdown, + .prepare = davinci_i2s_prepare, + .trigger = davinci_i2s_trigger, @@ -1848961,10 +1934742,7 @@ index b1ea52f..12a6c54 100644 +EXPORT_SYMBOL_GPL(davinci_i2s_dai); + +static int davinci_i2s_probe(struct platform_device *pdev) - { -- struct snd_soc_device *socdev = platform_get_drvdata(pdev); -- struct snd_soc_card *card = socdev->card; -- struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai; ++{ + struct snd_platform_data *pdata = pdev->dev.platform_data; struct davinci_mcbsp_dev *dev; - struct resource *mem, *ioarea; @@ -1848973,7 +1934751,7 @@ index b1ea52f..12a6c54 100644 int ret; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -@@ -466,8 +525,6 @@ static int davinci_i2s_probe(struct platform_device *pdev, +@@ -466,8 +514,6 @@ static int davinci_i2s_probe(struct platform_device *pdev, goto err_release_region; } @@ -1848982,20 +1934760,22 @@ index b1ea52f..12a6c54 100644 dev->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { ret = -ENODEV; -@@ -476,18 +533,37 @@ static int davinci_i2s_probe(struct platform_device *pdev, +@@ -476,18 +522,35 @@ static int davinci_i2s_probe(struct platform_device *pdev, clk_enable(dev->clk); dev->base = (void __iomem *)IO_ADDRESS(mem->start); - pdata = pdev->dev.platform_data; - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; +- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = pdata->tx_dma_ch; - dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr = +- dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr = ++ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr = (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; +- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = pdata->rx_dma_ch; - dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr = +- dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr = ++ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr = (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); + /* first TX, then RX */ @@ -1849005,7 +1934785,7 @@ index b1ea52f..12a6c54 100644 + ret = -ENXIO; + goto err_free_mem; + } -+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start; ++ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { @@ -1849013,7 +1934793,7 @@ index b1ea52f..12a6c54 100644 + ret = -ENXIO; + goto err_free_mem; + } -+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start; ++ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; + + davinci_i2s_dai.private_data = dev; + ret = snd_soc_register_dai(&davinci_i2s_dai); @@ -1849023,7 +1934803,7 @@ index b1ea52f..12a6c54 100644 return 0; err_free_mem: -@@ -498,62 +574,40 @@ err_release_region: +@@ -498,62 +561,40 @@ err_release_region: return ret; } @@ -1849048,9 +1934828,9 @@ index b1ea52f..12a6c54 100644 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(mem->start, (mem->end - mem->start) + 1); -} - --#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 - +-#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 + -static struct snd_soc_dai_ops davinci_i2s_dai_ops = { - .startup = davinci_i2s_startup, - .trigger = davinci_i2s_trigger, @@ -1849102,10 +1934882,10 @@ index b1ea52f..12a6c54 100644 diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c new file mode 100644 -index 0000000..7a06c0a +index 0000000..5d1f98a --- /dev/null +++ b/sound/soc/davinci/davinci-mcasp.c -@@ -0,0 +1,993 @@ +@@ -0,0 +1,969 @@ +/* + * ALSA SoC McASP Audio Layer for TI DAVINCI processor + * @@ -1849440,14 +1935220,6 @@ index 0000000..7a06c0a + printk(KERN_ERR "GBLCTL write error\n"); +} + -+static int davinci_mcasp_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *cpu_dai) -+{ -+ struct davinci_audio_dev *dev = cpu_dai->private_data; -+ cpu_dai->dma_data = dev->dma_params[substream->stream]; -+ return 0; -+} -+ +static void mcasp_start_rx(struct davinci_audio_dev *dev) +{ + mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); @@ -1849494,17 +1935266,17 @@ index 0000000..7a06c0a + +static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) +{ -+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) ++ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ if (dev->txnumevt) /* enable FIFO */ ++ mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, ++ FIFO_ENABLE); + mcasp_start_tx(dev); -+ else ++ } else { ++ if (dev->rxnumevt) /* enable FIFO */ ++ mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, ++ FIFO_ENABLE); + mcasp_start_rx(dev); -+ -+ /* enable FIFO */ -+ if (dev->txnumevt) -+ mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); -+ -+ if (dev->rxnumevt) -+ mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); ++ } +} + +static void mcasp_stop_rx(struct davinci_audio_dev *dev) @@ -1849521,17 +1935293,17 @@ index 0000000..7a06c0a + +static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) +{ -+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) ++ if (stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ if (dev->txnumevt) /* disable FIFO */ ++ mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, ++ FIFO_ENABLE); + mcasp_stop_tx(dev); -+ else ++ } else { ++ if (dev->rxnumevt) /* disable FIFO */ ++ mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, ++ FIFO_ENABLE); + mcasp_stop_rx(dev); -+ -+ /* disable FIFO */ -+ if (dev->txnumevt) -+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); -+ -+ if (dev->rxnumevt) -+ mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); ++ } +} + +static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, @@ -1849828,7 +1935600,7 @@ index 0000000..7a06c0a +{ + struct davinci_audio_dev *dev = cpu_dai->private_data; + struct davinci_pcm_dma_params *dma_params = -+ dev->dma_params[substream->stream]; ++ &dev->dma_params[substream->stream]; + int word_length; + u8 numevt; + @@ -1849906,7 +1935678,6 @@ index 0000000..7a06c0a +} + +static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { -+ .startup = davinci_mcasp_startup, + .trigger = davinci_mcasp_trigger, + .hw_params = davinci_mcasp_hw_params, + .set_fmt = davinci_mcasp_set_dai_fmt, @@ -1849957,20 +1935728,12 @@ index 0000000..7a06c0a + struct resource *mem, *ioarea, *res; + struct snd_platform_data *pdata; + struct davinci_audio_dev *dev; -+ int count = 0; + int ret = 0; + + dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; + -+ dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2, -+ GFP_KERNEL); -+ if (!dma_data) { -+ ret = -ENOMEM; -+ goto err_release_dev; -+ } -+ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + dev_err(&pdev->dev, "no mem resource?\n"); @@ -1850005,11 +1935768,10 @@ index 0000000..7a06c0a + dev->txnumevt = pdata->txnumevt; + dev->rxnumevt = pdata->rxnumevt; + -+ dma_data[count].name = "I2S PCM Stereo out"; -+ dma_data[count].eventq_no = pdata->eventq_no; -+ dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset + ++ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; ++ dma_data->eventq_no = pdata->eventq_no; ++ dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + + io_v2p(dev->base)); -+ dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count]; + + /* first TX, then RX */ + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); @@ -1850018,13 +1935780,12 @@ index 0000000..7a06c0a + goto err_release_region; + } + -+ dma_data[count].channel = res->start; -+ count++; -+ dma_data[count].name = "I2S PCM Stereo in"; -+ dma_data[count].eventq_no = pdata->eventq_no; -+ dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset + ++ dma_data->channel = res->start; ++ ++ dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; ++ dma_data->eventq_no = pdata->eventq_no; ++ dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + + io_v2p(dev->base)); -+ dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count]; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { @@ -1850032,7 +1935793,7 @@ index 0000000..7a06c0a + goto err_release_region; + } + -+ dma_data[count].channel = res->start; ++ dma_data->channel = res->start; + davinci_mcasp_dai[pdata->op_mode].private_data = dev; + davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; + ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); @@ -1850044,8 +1935805,6 @@ index 0000000..7a06c0a +err_release_region: + release_mem_region(mem->start, (mem->end - mem->start) + 1); +err_release_data: -+ kfree(dma_data); -+err_release_dev: + kfree(dev); + + return ret; @@ -1850054,7 +1935813,6 @@ index 0000000..7a06c0a +static int davinci_mcasp_remove(struct platform_device *pdev) +{ + struct snd_platform_data *pdata = pdev->dev.platform_data; -+ struct davinci_pcm_dma_params *dma_data; + struct davinci_audio_dev *dev; + struct resource *mem; + @@ -1850067,8 +1935825,6 @@ index 0000000..7a06c0a + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem->start, (mem->end - mem->start) + 1); + -+ dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; -+ kfree(dma_data); + kfree(dev); + + return 0; @@ -1850101,10 +1935857,10 @@ index 0000000..7a06c0a + diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h new file mode 100644 -index 0000000..554354c +index 0000000..9d179cc --- /dev/null +++ b/sound/soc/davinci/davinci-mcasp.h -@@ -0,0 +1,60 @@ +@@ -0,0 +1,65 @@ +/* + * ALSA SoC McASP Audio Layer for TI DAVINCI processor + * @@ -1850146,10 +1935902,15 @@ index 0000000..554354c +}; + +struct davinci_audio_dev { ++ /* ++ * dma_params must be first because rtd->dai->cpu_dai->private_data ++ * is cast to a pointer of an array of struct davinci_pcm_dma_params in ++ * davinci_pcm_open. ++ */ ++ struct davinci_pcm_dma_params dma_params[2]; + void __iomem *base; + int sample_rate; + struct clk *clk; -+ struct davinci_pcm_dma_params *dma_params[2]; + unsigned int codec_fmt; + + /* McASP specific data */ @@ -1850166,7 +1935927,7 @@ index 0000000..554354c + +#endif /* DAVINCI_MCASP_H */ diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c -index a059965..2f7da49 100644 +index a059965..c73a915 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -67,6 +67,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) @@ -1850191,7 +1935952,24 @@ index a059965..2f7da49 100644 prtd->period++; if (unlikely(prtd->period >= runtime->periods)) -@@ -143,7 +145,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) +@@ -124,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data) + static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) + { + struct davinci_runtime_data *prtd = substream->runtime->private_data; +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data; + struct edmacc_param p_ram; + int ret; + +- if (!dma_data) +- return -ENODEV; +- +- prtd->params = dma_data; +- + /* Request master DMA channel */ + ret = edma_alloc_channel(prtd->params->channel, + davinci_pcm_dma_irq, substream, +@@ -143,7 +138,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) prtd->master_lch = ret; /* Request parameter RAM reload slot */ @@ -1850200,7 +1935978,7 @@ index a059965..2f7da49 100644 if (ret < 0) { edma_free_channel(prtd->master_lch); return ret; -@@ -160,8 +162,8 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) +@@ -160,8 +155,8 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) * so davinci_pcm_enqueue_dma() takes less time in IRQ. */ edma_read_slot(prtd->slave_lch, &p_ram); @@ -1850211,7 +1935989,7 @@ index a059965..2f7da49 100644 edma_write_slot(prtd->slave_lch, &p_ram); return 0; -@@ -206,6 +208,7 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream) +@@ -206,6 +201,7 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream) /* Copy self-linked parameter RAM entry into master channel */ edma_read_slot(prtd->slave_lch, &temp); edma_write_slot(prtd->master_lch, &temp); @@ -1850219,8 +1935997,15 @@ index a059965..2f7da49 100644 return 0; } -@@ -243,6 +246,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) +@@ -241,14 +237,25 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) + struct snd_pcm_runtime *runtime = substream->runtime; + struct davinci_runtime_data *prtd; int ret = 0; ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; ++ struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data; ++ struct davinci_pcm_dma_params *params = &pa[substream->stream]; ++ if (!params) ++ return -ENODEV; snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); + /* ensure that buffer size is a multiple of period size */ @@ -1850231,11 +1936016,18 @@ index a059965..2f7da49 100644 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL); if (prtd == NULL) + return -ENOMEM; + + spin_lock_init(&prtd->lock); ++ prtd->params = params; + + runtime->private_data = prtd; + diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h -index 62cb4eb..63d9625 100644 +index 62cb4eb..8746606 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h -@@ -12,17 +12,20 @@ +@@ -12,17 +12,19 @@ #ifndef _DAVINCI_PCM_H #define _DAVINCI_PCM_H @@ -1850248,7 +1936040,6 @@ index 62cb4eb..63d9625 100644 - int channel; /* sync dma channel ID */ - dma_addr_t dma_addr; /* device physical address for DMA */ - unsigned int data_type; /* xfer data type */ -+ char *name; /* stream identifier */ + int channel; /* sync dma channel ID */ + unsigned short acnt; + dma_addr_t dma_addr; /* device physical address for DMA */